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

Integrate session pallet into validator-sets pallet #440

Merged
merged 11 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions coordinator/src/substrate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async fn in_set(
return Ok(None);
};
let key = (Ristretto::generator() * key.deref()).to_bytes();
Ok(Some(participants.iter().any(|participant| participant.0 == key)))
Ok(Some(participants.iter().any(|(participant, _)| participant.0 == key)))
}

async fn handle_new_set<D: Db>(
Expand All @@ -64,26 +64,11 @@ async fn handle_new_set<D: Db>(

let set_data = {
let serai = serai.as_of(block.hash()).validator_sets();
let set_participants =
let mut set_participants =
serai.participants(set.network).await?.expect("NewSet for set which doesn't exist");

let allocation_per_key_share = serai
.allocation_per_key_share(set.network)
.await?
.expect("NewSet for set which didn't have an allocation per key share")
.0;

let mut set_data = vec![];
for participant in set_participants {
let allocation = serai
.allocation(set.network, participant)
.await?
.expect("validator selected for set yet didn't have an allocation")
.0;
set_data.push((participant, u16::try_from(allocation / allocation_per_key_share).unwrap()));
}
amortize_excess_key_shares(&mut set_data);
set_data
amortize_excess_key_shares(&mut set_participants);
set_participants
};

let time = if let Ok(time) = block.time() {
Expand Down
5 changes: 4 additions & 1 deletion substrate/client/src/serai/validator_sets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ impl<'a> SeraiValidatorSets<'a> {
self.0.storage(PALLET, "CurrentSession", Some(vec![scale_value(network)])).await
}

pub async fn participants(&self, network: NetworkId) -> Result<Option<Vec<Public>>, SeraiError> {
pub async fn participants(
&self,
network: NetworkId,
) -> Result<Option<Vec<(Public, u16)>>, SeraiError> {
self.0.storage(PALLET, "Participants", Some(vec![scale_value(network)])).await
}

Expand Down
7 changes: 6 additions & 1 deletion substrate/client/tests/validator_sets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ serai_test!(

{
let vs_serai = serai.with_current_latest_block().await.unwrap().validator_sets();
let participants = vs_serai.participants(set.network).await.unwrap().unwrap();
let participants = vs_serai.participants(set.network).await
.unwrap()
.unwrap()
.into_iter()
.map(|(k, _)| k)
.collect::<Vec<_>>();
let participants_ref: &[_] = participants.as_ref();
assert_eq!(participants_ref, [public].as_ref());
assert_eq!(vs_serai.musig_key(set).await.unwrap().unwrap(), musig_key(set, &[public]).0);
Expand Down
9 changes: 7 additions & 2 deletions substrate/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use support::{
},
parameter_types, construct_runtime,
};
use codec::{Encode, Decode};

use babe::AuthorityId as BabeId;
use grandpa::AuthorityId as GrandpaId;
Expand Down Expand Up @@ -540,9 +541,13 @@ sp_api::impl_runtime_apis! {

impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
fn authorities() -> Vec<AuthorityDiscoveryId> {
ValidatorSets::serai_validators()
Babe::authorities()
.into_iter()
.map(|(id, _)| AuthorityDiscoveryId::from(id))
.map(|(id, _)| {
// TODO: any better way to do this?
akildemir marked this conversation as resolved.
Show resolved Hide resolved
let key = id.encode();
AuthorityDiscoveryId::decode(&mut key.as_slice()).unwrap()
})
.collect()
}
}
Expand Down
22 changes: 3 additions & 19 deletions substrate/validator-sets/pallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod pallet {
use sp_std::{vec, vec::Vec};
use sp_application_crypto::RuntimePublic;
use sp_session::ShouldEndSession;
use sp_runtime::traits::IsMember;

use frame_system::pallet_prelude::*;
use frame_support::{
Expand Down Expand Up @@ -64,18 +65,11 @@ pub mod pallet {

/// The current session for a network.
///
akildemir marked this conversation as resolved.
Show resolved Hide resolved
/// This does not store the current session for Serai.
// Uses Identity for the lookup to avoid a hash of a severely limited fixed key-space.
#[pallet::storage]
#[pallet::getter(fn session)]
pub type CurrentSession<T: Config> = StorageMap<_, Identity, NetworkId, Session, OptionQuery>;

/// The current set of serai validators.
#[pallet::storage]
#[pallet::getter(fn serai_validators)]
pub type SeraiValidators<T: Config> =
StorageValue<_, BoundedVec<(Public, u64), ConstU32<{ MAX_KEY_SHARES_PER_SET }>>, ValueQuery>;

/// The allocation required per key share.
// Uses Identity for the lookup to avoid a hash of a severely limited fixed key-space.
#[pallet::storage]
Expand Down Expand Up @@ -110,13 +104,8 @@ pub mod pallet {
// current set's validators
#[inline]
fn in_active_serai_set(account: Public) -> bool {
// TODO: This is bounded O(n). Can we get O(1) via a storage lookup, like we do with InSet?
for (validator, _) in Self::serai_validators() {
if validator == account {
return true;
}
}
false
// TODO: TODO: is_member is internally O(n). Update Babe to use an O(1) storage lookup?
akildemir marked this conversation as resolved.
Show resolved Hide resolved
Babe::<T>::is_member(&BabeAuthorityId::from(account))
}

/// Returns true if the account is included in an active set.
Expand Down Expand Up @@ -405,10 +394,6 @@ pub mod pallet {
}
Pallet::<T>::new_set(id);
}

// set the initial serai validators
let initial_validators = Pallet::<T>::participants(NetworkId::Serai);
SeraiValidators::<T>::put(initial_validators.clone());
}
}

Expand Down Expand Up @@ -691,7 +676,6 @@ pub mod pallet {
let session = prior_serai_session.0 + 1;
let validators = prior_serai_participants;
let next_validators = Self::participants(NetworkId::Serai);
SeraiValidators::<T>::put(&validators);
Babe::<T>::enact_epoch_change(
WeakBoundedVec::force_from(
validators.iter().copied().map(|(id, w)| (BabeAuthorityId::from(id), w)).collect(),
Expand Down
Loading