Skip to content
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

Add Signer groups and rotation #938

Merged
merged 14 commits into from
Jul 17, 2024
Merged

Add Signer groups and rotation #938

merged 14 commits into from
Jul 17, 2024

Conversation

JesseAbram
Copy link
Member

@JesseAbram JesseAbram commented Jul 16, 2024

  • Set parameters for size of signer group and T of N
  • Add Signer groups to chain
  • Get randomness to select new signer from validators on session refresh
  • Rotate Signers

@JesseAbram JesseAbram mentioned this pull request Jul 16, 2024
19 tasks
@JesseAbram JesseAbram marked this pull request as ready for review July 16, 2024 20:48
@@ -714,6 +714,7 @@ parameter_types! {
impl pallet_staking_extension::Config for Runtime {
type Currency = Balances;
type MaxEndpointLength = MaxEndpointLength;
type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JesseAbram JesseAbram added Bump `spec_version` A change which affects the current runtime behaviour Bump `impl_version` A change which only affect the implementation details of the runtime Bump `transaction_version` A change which affects how existing extrinsics are created (e.g parameter changes) labels Jul 16, 2024
Copy link
Collaborator

@HCastano HCastano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think this needs an impl_version bump since we're already bumping the spec_version. I also don't think the transaction_version needs to be bumped since only new stuff is being added, as opposed to existing extrinsics being changed

Comment on lines 163 to 169
#[pallet::storage]
#[pallet::getter(fn signers)]
pub type Signers<T: Config> = StorageValue<_, Vec<T::ValidatorId>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn next_signers)]
pub type NextSigners<T: Config> = StorageValue<_, Vec<T::ValidatorId>, ValueQuery>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add docs to these?

'sp-runtime/std',

"rand_chacha/std",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use chaha20 here instead of something else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw it used in the society pallet, when I have a choice like this to make I default to auditted production code, open to other ideas

Comment on lines +406 to +408
// TODO: Is randomness freshness an issue here
// https://github.com/paritytech/substrate/issues/8312
let (seed, _) = T::Randomness::random(phrase);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So does this mean that we should also be checking how fresh the randomness is here before committing to use it ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ummmmmmm no I don't believe so this is like more of a commit reveal thing where this can be useful, as in like idk a lottery, bets are placed, there is a clear end time then you grab randomness, but the way we use randomness is in an ever flowing system where validators are swapped in and out, potentially we can grab the randomness from a previous session, some more investitgation on how validators are ordered may help here, but good randomness is probably enough

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case this should be hashed out in #944

let mut current_signers = Self::signers();
// Since not enough validators do not allow rotation
// TODO: https://github.com/entropyxyz/entropy-core/issues/943
if validators.len() <= current_signers.len() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case that validators.len() == current_signers.len() why not allow rotation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do have #943 open for discussion about this, but if we do not let signers leave validators while in the signer group (which is also a discussion lol) then we can assume all validators are signers here and we can not let them leave in fear of losing the parent key

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If validators.len() == current_signers.len() then we still want to run the last bit of this function, which is currently just a comment - as in we still do a reshare with the same signer set.

validators.len() < current_signers.len() i guess should be a state which is impossible to get into. Not sure how to handle that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya probably not a reshare but a refresh instead, can you add this comment to #943

let mut next_signer_up = &current_signers[0].clone();
let mut index;
// loops to find signer in validator that is not already signer
while current_signers.contains(next_signer_up) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty expensive lookup to do on a Vec, esp with random indexes, can we get away with making Signers a map?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmmmm ok so we do know signers is relatively small and this would cause other operations (coming in future PRs) to increase complexity (happy to explain them but honestly may be better to see in a few days) that being said Im open to making this an issue and going back over to optimise this, but for now I feel strongly about leaving this as is to push through the flow

pallets/parameters/src/lib.rs Show resolved Hide resolved
pallets/parameters/src/lib.rs Outdated Show resolved Hide resolved
pallets/parameters/src/lib.rs Outdated Show resolved Hide resolved
node/cli/src/chain_spec/testnet.rs Outdated Show resolved Hide resolved
pallets/parameters/src/lib.rs Outdated Show resolved Hide resolved
JesseAbram and others added 2 commits July 16, 2024 15:32
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
@JesseAbram JesseAbram requested a review from HCastano July 16, 2024 22:48
Copy link
Contributor

@ameba23 ameba23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 💯 (pending CI)

Just to confirm the scope of this PR is to add a signing committee concept to the staking pallet, but not yet actually use them.

I haven't looked into the issue around 'freshness' relating to randomness, and obviously having a good source of randomness is pretty critical here, but since there is a comment and #944 i think we should move ahead with this.

As discussed elsewhere, as well as randomness there are other factors we could use in this selection process eg: stake, age of validator, and number of blocks since a validator was last in the signing committee.

As for the frequency of rotation (moving one validator in/out per session), i think this is too frequent, and should probably also be configurable as a parameter, or even depend on this size of the validator set (the more validators, the more frequent the rotation). As i mentioned before, my main concern is that the more frequent the rotation, the higher the chance that a malicious actor who controls n nodes will control the complete signing committee. But for simplicity i think we should leave this as it is for now and merge this.

As for having t and n configurable as a parameter. I totally agree with this, and i can't see a reason why changing them with a running network would cause issues. But of course issues with this could well pop up.

}

// removes first signer and pushes new signer to back
current_signers.remove(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think we need to worry too much about optimising for performance here as this only runs once per session and we know that current_signers is small, but i agree that VecDeque is better suited to this.

i am totally down with removing the first current signer and pushing the new one to the end. 👍

let mut current_signers = Self::signers();
// Since not enough validators do not allow rotation
// TODO: https://github.com/entropyxyz/entropy-core/issues/943
if validators.len() <= current_signers.len() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If validators.len() == current_signers.len() then we still want to run the last bit of this function, which is currently just a comment - as in we still do a reshare with the same signer set.

validators.len() < current_signers.len() i guess should be a state which is impossible to get into. Not sure how to handle that.

) -> DispatchResult {
T::UpdateOrigin::ensure_origin(origin)?;
let signer_info = SignersSize { total_signers, threshold };
// TODO: add checks to make sure threshold is not bigger then signature size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and that threshold is greater than 1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these checks being left as a TODO? For some quick ones, e.g Peg's suggestion or threshold <= total_signers we should be able to do now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya imma add them now

pallets/parameters/src/benchmarking.rs Show resolved Hide resolved
pallets/parameters/src/lib.rs Outdated Show resolved Hide resolved
) -> DispatchResult {
T::UpdateOrigin::ensure_origin(origin)?;
let signer_info = SignersSize { total_signers, threshold };
// TODO: add checks to make sure threshold is not bigger then signature size
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these checks being left as a TODO? For some quick ones, e.g Peg's suggestion or threshold <= total_signers we should be able to do now

// no next signers at start
assert_eq!(Staking::next_signers().len(), 0);

Staking::new_session_handler(&vec![1u64, 2u64, 3u64]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need to explicitly specify the u64 type in this whole test

pallets/staking/src/tests.rs Outdated Show resolved Hide resolved
Comment on lines +417 to +420
inital_signers: initial_authorities.iter().map(|auth| {
auth.0.clone()
})
.collect::<Vec<_>>(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the testnet config we may want it to be empty actually, and instead have it be populated through a different jumpstart related mechanism.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe, let's open an issue here, too much discussion to be had and let's not slow down the rest of the flow

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually covered in #941

CHANGELOG.md Outdated Show resolved Hide resolved
@HCastano HCastano removed Bump `impl_version` A change which only affect the implementation details of the runtime Bump `transaction_version` A change which affects how existing extrinsics are created (e.g parameter changes) labels Jul 17, 2024
@JesseAbram JesseAbram merged commit 9549194 into master Jul 17, 2024
13 checks passed
@JesseAbram JesseAbram deleted the signer-rotation-groups branch July 17, 2024 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bump `spec_version` A change which affects the current runtime behaviour
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants