-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integrate signer changes dynamically #978
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥇 Looks good.
@@ -64,6 +64,10 @@ pub const NETWORK_PARENT_KEY: &str = "NETWORK_PARENT_KEY_FOR_ENTROPY_"; | |||
/// Total signers on the network with the parent key | |||
pub const TOTAL_SIGNERS: u8 = 3; | |||
|
|||
/// Max signers, for bounding of total signers for benches, | |||
/// Can be changed but requires a re-run of benches | |||
pub const MAX_SIGNERS: u8 = 15; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
pallets/parameters/src/lib.rs
Outdated
); | ||
let current_session = pallet_session::Pallet::<T>::current_index(); | ||
ensure!( | ||
current_session >= old_signer_info.last_session_change, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be >
rather than >=
?
} | ||
|
||
#[derive(Clone, Encode, Decode, Eq, PartialEqNoBound, RuntimeDebug, TypeInfo, Default)] | ||
pub struct SignersSize { | ||
pub threshold: u8, | ||
pub total_signers: u8, | ||
pub last_session_change: u32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A doccomment would be nice. If i understood right this is the session index number of the last session in which threshold
or total_signers
changed.
signer_info.total_signers, | ||
signer_info.threshold | ||
), | ||
Error::<Runtime>::OneChangePerSession, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If i understood right this tests that you cannot make a change when the current session is older than last_session_change
(which is hopefully an impossible state to get into), but not that you cannot make two changes in the same session.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed as per your previous comment, good catch
pallets/staking/src/lib.rs
Outdated
// removes first signer and pushes new signer to back if total signers not increased | ||
if current_signers.len() >= signers_info.total_signers as usize { | ||
current_signers.remove(0); | ||
} | ||
current_signers.push(next_signer_up.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if we decrease total_signers
? I guess here we have a similar if
as above, and only push the next_signer_up
if total_signers
did not decrease.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
pallets/staking/src/tests.rs
Outdated
}); | ||
assert_ok!(Staking::new_session_handler(&[6, 5, 3, 4])); | ||
// Signer size increased is reflected as 5 is not removed from vec | ||
assert_eq!(Staking::next_signers().unwrap().next_signers, vec![5, 6, 3]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we also want a test for decreasing signer size
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments and questions, but overall looks good 👍
} | ||
|
||
#[derive(Clone, Encode, Decode, Eq, PartialEqNoBound, RuntimeDebug, TypeInfo, Default)] | ||
pub struct SignersSize { | ||
pub threshold: u8, | ||
pub total_signers: u8, | ||
pub last_session_change: u32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can probably use the SessionIndex
type directly here (which is typedef'd to a u32
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya but then I would have to pull in sp-staking pallet, a whole new crate for one type does not seem worth it
@@ -96,12 +100,19 @@ pub mod module { | |||
ThresholdGreaterThenSigners, | |||
/// Threhsold has to be more than 0 | |||
ThrehsoldTooLow, | |||
/// Signers over max signers, can happen however needs a benchmark rerun |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What benchmark are you referring to here?
If it's the change_signers_info()
one this isn't required. The extrinsic is of constant time and doesn't change based off the inputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any bench that we loop over the signers, a few, like confirm_jump_start, confirm_reshare, anything with confirm mainly because it has to check if the current signer is in the signers struct which is O(n)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JesseAbram so these actually don't scale with the number of signers. In the case of confirm_jump_start_confirm()
the c
parameter doesn't influence the final weight. Also reading through the extrinsic we're only doing constant time storage queries, no loops.
Maybe can you point me to where the O(n)
operations are happening?
pallets/parameters/src/tests.rs
Outdated
); | ||
|
||
assert_noop!( | ||
Parameters::change_signers_info(RuntimeOrigin::root(), 8, signer_info.threshold), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of 8
here I would do something like new_threshold = old_signer_info.threshold + 2
and use that instead
@@ -327,7 +327,8 @@ pub mod pallet { | |||
// ensure that registration was indeed successful. | |||
// | |||
// If it fails we'll need to allow another jumpstart. | |||
if jump_start_info.confirmations.len() == (TOTAL_SIGNERS as usize - 1) { | |||
let signers_amount = pallet_parameters::Pallet::<T>::signers_info().total_signers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let signers_amount = pallet_parameters::Pallet::<T>::signers_info().total_signers; | |
let total_signers = pallet_parameters::Pallet::<T>::signers_info().total_signers; |
For consistency
pallets/staking/src/mock.rs
Outdated
@@ -409,7 +409,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { | |||
pallet_parameters::GenesisConfig::<Test> { | |||
request_limit: 5u32, | |||
max_instructions_per_programs: 5u64, | |||
total_signers: 5u8, | |||
total_signers: 2u8, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change this to 3
to match the Registry
config, and then in the test change the total_signers
to 4
. This makes testing across the pallets more predictable
pallets/staking/src/tests.rs
Outdated
|
||
pallet_parameters::SignersInfo::<Test>::put(SignersSize { | ||
total_signers: 3, | ||
threshold: 2, | ||
last_session_change: 0, | ||
}); | ||
assert_ok!(Staking::new_session_handler(&[6, 5, 3, 4])); | ||
// Signer size increased is reflected as 5 is not removed from vec | ||
assert_eq!(Staking::next_signers().unwrap().next_signers, vec![5, 6, 3]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you be able to throw these (and the few lines of code above) into a separate test? While it does test the session handler behaviour, it's more of specific test related to the management of the signers at the session boundary
@@ -64,6 +64,10 @@ pub const NETWORK_PARENT_KEY: &str = "NETWORK_PARENT_KEY_FOR_ENTROPY_"; | |||
/// Total signers on the network with the parent key | |||
pub const TOTAL_SIGNERS: u8 = 3; | |||
|
|||
/// Max signers, for bounding of total signers for benches, | |||
/// Can be changed but requires a re-run of benches |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Can be changed but requires a re-run of benches |
Similar thing here, if I'm thinking of the right extrinsic it's constant time
Co-authored-by: Hernando Castano <[email protected]>
This also adds bounding to changing N in parameters, by only allowing 1 signer to be added per session, and in session if the signer size is increased it will add one new signer and not remove a signer instead of adding 2 new ones