Conversation
`SessionInterface::set_keys` bypasses `inc_consumers` (the account may not be live on the relay chain). However `do_purge_keys` unconditionally called `dec_consumers`, causing a mismatch when keys set externally were purged locally. Add `ExternallySetKeys` storage map to record accounts whose keys were set via the external path. `do_purge_keys` now only decrements consumers for accounts registered through the local session pallet.
When `SessionInterface::set_keys` updates existing keys or `SessionInterface::purge_keys` removes them, any held key deposit from a prior local registration is now released via `release_all(BestEffort)`. This prevents deposits from getting stuck when validators transition from local to external key management.
|
/cmd prdoc --audience runtime_dev --bump minor |
Ank4n
left a comment
There was a problem hiding this comment.
Wouldn't it also work if we just incremented and decremented consumer when set(new)/purge via SessionInterface as well? Simpler I think, and consumer would still be correctly accounted?
Yes it would be simpler but for a new validator who only sets keys via AH , there is no real need to have an account on RC and so no need to increment the counter (or to hold a deposit on RC). But if the consensus is to go with your proposal , I can def make the changes |
kianenigma
left a comment
There was a problem hiding this comment.
I am not convinced this is the right way to fix this. Now the session pallet needs to know about the idea of external keys, which I think can be avoided:
- If key is set locally, consumer and deposit behavior is atm correct.
- If key is set remotely, an inner code path that ignores consumer and deposit should be called. The remote chain handles the deposit. Consumer can be fully ignored, because your account that is actually alive is in another chain. Perhaps the remote chain should tweak your consumer on the remote chain, but not here.
And how would you handle the case of a key set on AH and purged on RC? If RC-purge doesn't have to know about external keys, then it will just decrease the counter... ps note that atm (So w/o this PR) |
I would fully disable RC session mgmt, and my comment was stemming from the idea that this is the path to go. Isn't that easier? |
So ignoring the deposit (since on Polkadot and Kusama we are not setting KeyDeposit on RC and we won't so let's keep that out from the discussion) - the only drawback of disabling RC Session mgmt would be that we just don't decrement consumer on purge on AH [UPDATE] to be noted also that setting keys on AH requires 10k DOT, settings keys on RC ED (1DOT) |
kianenigma
left a comment
There was a problem hiding this comment.
Okay, reading the
/// Accounts whose keys were set via `SessionInterface` (external path) without
/// incrementing the consumer reference or placing a key deposit. `do_purge_keys`
/// only decrements consumers for accounts that were registered through the local
/// session pallet.
#[pallet::storage]
pub type ExternallySetKeys<T: Config> =
StorageMap<_, Twox64Concat, T::AccountId, (), OptionQuery>;
Gives me a better idea of what is intended here.
Suggestion to simplify this + make sure it is a reasonable feature that won't bite us in the future:
- There is two distinct paths to set keys: Via other pallets (
SessionInterface) and#[pallet::call] - Former ignores consumer + deposit, latter manages them ()
- They should generally not share any code path.
- They cannot be inter-mixed -- If you set it via
SessionInterface, you have to purge it with the same method. And visa versa.
My reading of the PR is that this will it easier to understand + still meet our needs. KISS: Keeping It Stupid Simple.
I thought about exactly this and I wanted to implement this in the 1st place because keeps a proper separation of concerns. The main reason I didn't go for that is that in the moment we remove the |
|
There is also a brute-force approach that won't bite us in the future:
[UPDATE]: which is the equivalent of disabling the call in the runtime then (Except that we can keep consumer ref correct) - so what you already proposed and to fast-track the release we could do that first |
kianenigma
left a comment
There was a problem hiding this comment.
Upon further reading, I think this PR is fine. To convince myself more that it is right, I tried to break down all code paths and test coverage, and this is what I think we should test for:
// test coverage overview:
// set local, purge local
// set local, purge remote
// set remote, purge local
// set remote, purge remote
// non-purge scenarios:
// - set local, switch remote
// - set remote, switch local
// each test ensures at each step:
// - consumer count
// - deposit
// - externally set key
#[test]
fn set_local_purge_local() {}
#[test]
fn set_local_purge_remote() {}
#[test]
fn set_remote_purge_remote() {}
#[test]
fn set_remote_purge_local() {}
#[test]
fn set_local_to_remote() {}
#[test]
fn set_remote_to_local() {}
I think most are covered now, but perhaps this is a better breakdown of it. I think all other E2E scenarios are built from these 6 components.
Feel free to incorporate in whatever way it fits the PR best. Happy to do a final review afterwards.
Done - PTAL 🙇 |
Having an extra storage in session pallet is almost equivalent to keeping an account on RC by incrementing consumer on it, no? And less code changes? Additionally, pretty soon we are going to get rid of setting keys locally so there will eventually be only one path. This solution is perfectly fine btw and since you are already done with it, lets go with it 🚀. |
…ly set keys (#11197) Tracks whether session keys were set externally (via `SessionInterface`, e.g. from AH) or locally. Transitions between the two paths correctly manage the key deposit and consumer ref in both directions. --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> (cherry picked from commit b965285)
|
Successfully created backport PR for |
…ly set keys (#11197) Tracks whether session keys were set externally (via `SessionInterface`, e.g. from AH) or locally. Transitions between the two paths correctly manage the key deposit and consumer ref in both directions. --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> (cherry picked from commit b965285)
|
Successfully created backport PR for |
Backport #11197 into `stable2512` from sigurpol. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> --------- Co-authored-by: Paolo La Camera <paolo@parity.io> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Backport #11197 into `stable2603` from sigurpol. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> Co-authored-by: Paolo La Camera <paolo@parity.io> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…ly set keys (paritytech#11197) Tracks whether session keys were set externally (via `SessionInterface`, e.g. from AH) or locally. Transitions between the two paths correctly manage the key deposit and consumer ref in both directions. --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Backport paritytech#11197 into `stable2512` from sigurpol. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> --------- Co-authored-by: Paolo La Camera <paolo@parity.io> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Tracks whether session keys were set externally (via
SessionInterface, e.g. from AH) or locally.Transitions between the two paths correctly manage the key deposit and consumer ref in both directions.