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

refactor: split out composite electoral system trait #5334

Merged
merged 18 commits into from
Nov 11, 2024
Merged
4 changes: 2 additions & 2 deletions .github/workflows/ci-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
uses: ./.github/workflows/_40_post_check.yml
secrets: inherit
with:
full-bouncer: false
full-bouncer: true
ngrok: true
test-benchmarks:
needs: [build-benchmarks]
Expand All @@ -79,7 +79,7 @@ jobs:
uses: ./.github/workflows/upgrade-test.yml
secrets: inherit
with:
run-job: false
run-job: true
kylezs marked this conversation as resolved.
Show resolved Hide resolved
publish:
needs: [package]
uses: ./.github/workflows/_30_publish.yml
Expand Down
20 changes: 10 additions & 10 deletions engine/src/elections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ use cf_primitives::MILLISECONDS_PER_BLOCK;
use cf_utilities::{future_map::FutureMap, task_scope::Scope, UnendingStream};
use futures::{stream, StreamExt, TryStreamExt};
use pallet_cf_elections::{
electoral_system::{ElectionIdentifierOf, ElectoralSystem},
vote_storage::{AuthorityVote, VoteStorage},
SharedDataHash, MAXIMUM_VOTES_PER_EXTRINSIC,
CompositeElectionIdentifierOf, ElectoralSystemRunner, SharedDataHash,
MAXIMUM_VOTES_PER_EXTRINSIC,
};
use rand::Rng;
use std::{
collections::{BTreeMap, HashMap},
sync::Arc,
};
use tracing::{error, info, warn};
use voter_api::VoterApi;
use voter_api::CompositeVoterApi;

const MAXIMUM_CONCURRENT_FILTER_REQUESTS: usize = 16;
const LIFETIME_OF_SHARED_DATA_IN_CACHE: std::time::Duration = std::time::Duration::from_secs(90);
Expand All @@ -34,7 +34,7 @@ const INITIAL_VOTER_REQUEST_TIMEOUT: std::time::Duration = std::time::Duration::
pub struct Voter<
Instance: 'static,
StateChainClient: ElectoralApi<Instance> + SignedExtrinsicApi + ChainApi,
VoterClient: VoterApi<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem> + Send + Sync + 'static,
VoterClient: CompositeVoterApi<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner> + Send + Sync + 'static,
> where
state_chain_runtime::Runtime:
pallet_cf_elections::Config<Instance>,
Expand All @@ -47,7 +47,7 @@ pub struct Voter<
impl<
Instance: Send + Sync + 'static,
StateChainClient: ElectoralApi<Instance> + SignedExtrinsicApi + ChainApi,
VoterClient: VoterApi<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem> + Clone + Send + Sync + 'static,
VoterClient: CompositeVoterApi<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner> + Clone + Send + Sync + 'static,
> Voter<Instance, StateChainClient, VoterClient>
where
state_chain_runtime::Runtime:
Expand Down Expand Up @@ -111,17 +111,17 @@ where
std::time::Duration::from_millis(MILLISECONDS_PER_BLOCK);
let mut submit_interval = tokio::time::interval(BLOCK_TIME);
let mut pending_submissions = BTreeMap::<
ElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem>,
CompositeElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner>,
(
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::PartialVote,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::Vote,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner as ElectoralSystemRunner>::Vote as VoteStorage>::PartialVote,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner as ElectoralSystemRunner>::Vote as VoteStorage>::Vote,
)
>::default();
let mut vote_tasks = FutureMap::default();
let mut shared_data_cache = HashMap::<
SharedDataHash,
(
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::SharedData,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner as ElectoralSystemRunner>::Vote as VoteStorage>::SharedData,
std::time::Instant,
)
>::default();
Expand Down Expand Up @@ -163,7 +163,7 @@ where
Ok(vote) => {
info!("Voting task for election: '{:?}' succeeded.", election_identifier);
// Create the partial_vote early so that SharedData can be provided as soon as the vote has been generated, rather than only after it is submitted.
let partial_vote = <<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::vote_into_partial_vote(&vote, |shared_data| {
let partial_vote = <<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner as ElectoralSystemRunner>::Vote as VoteStorage>::vote_into_partial_vote(&vote, |shared_data| {
let shared_data_hash = SharedDataHash::of(&shared_data);
if shared_data_cache.len() > MAXIMUM_SHARED_DATA_CACHE_ITEMS {
for shared_data_hash in shared_data_cache.keys().cloned().take(shared_data_cache.len() - MAXIMUM_SHARED_DATA_CACHE_ITEMS).collect::<Vec<_>>() {
Expand Down
30 changes: 21 additions & 9 deletions engine/src/elections/voter_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ use frame_support::{
};
use pallet_cf_elections::{
electoral_system::ElectoralSystem,
electoral_systems::composite::{self, Composite},
electoral_system_runner::RunnerStorageAccessTrait,
electoral_systems::composite::{self, CompositeRunner},
vote_storage::{self, VoteStorage},
ElectoralSystemRunner,
};

#[async_trait::async_trait]
Expand All @@ -17,33 +19,43 @@ pub trait VoterApi<E: ElectoralSystem> {
) -> Result<<<E as ElectoralSystem>::Vote as VoteStorage>::Vote, anyhow::Error>;
}

pub struct CompositeVoter<ElectoralSystem, Voters> {
pub struct CompositeVoter<ElectoralSystemRunner, Voters> {
voters: Voters,
_phantom: core::marker::PhantomData<ElectoralSystem>,
_phantom: core::marker::PhantomData<ElectoralSystemRunner>,
}
impl<ElectoralSystem, Voters: Clone> Clone for CompositeVoter<ElectoralSystem, Voters> {
impl<ElectoralSystemRunner, Voters: Clone> Clone for CompositeVoter<ElectoralSystemRunner, Voters> {
fn clone(&self) -> Self {
Self { voters: self.voters.clone(), _phantom: Default::default() }
}
}

impl<ElectoralSystem, Voters> CompositeVoter<ElectoralSystem, Voters> {
impl<ElectoralSystemRunner, Voters> CompositeVoter<ElectoralSystemRunner, Voters> {
pub fn new(voters: Voters) -> Self {
Self { voters, _phantom: Default::default() }
}
}

#[async_trait::async_trait]
pub trait CompositeVoterApi<E: ElectoralSystemRunner> {
async fn vote(
&self,
settings: <E as ElectoralSystemRunner>::ElectoralSettings,
properties: <E as ElectoralSystemRunner>::ElectionProperties,
) -> Result<<<E as ElectoralSystemRunner>::Vote as VoteStorage>::Vote, anyhow::Error>;
}

// TODO Combine this into the composite macro PRO-1736
macro_rules! generate_voter_api_tuple_impls {
($module:ident: ($(($electoral_system:ident, $voter:ident)),*$(,)?)) => {
#[allow(non_snake_case)]
#[async_trait::async_trait]
impl<$($voter: VoterApi<$electoral_system> + Send + Sync),*, $($electoral_system : ElectoralSystem<ValidatorId = ValidatorId> + Send + Sync + 'static),*, ValidatorId: MaybeSerializeDeserialize + Member + Parameter, Hooks: Send + Sync + 'static + composite::$module::Hooks<$($electoral_system,)*>> VoterApi<Composite<($($electoral_system,)*), ValidatorId, Hooks>> for CompositeVoter<Composite<($($electoral_system,)*), ValidatorId, Hooks>, ($($voter,)*)> {
impl<$($voter: VoterApi<$electoral_system> + Send + Sync),*, $($electoral_system : ElectoralSystem<ValidatorId = ValidatorId> + Send + Sync + 'static),*, ValidatorId: MaybeSerializeDeserialize + Member + Parameter, StorageAccess: RunnerStorageAccessTrait<ElectoralSystemRunner = CompositeRunner<($($electoral_system,)*), ValidatorId, StorageAccess, Hooks>> + Send + Sync + 'static, Hooks: Send + Sync + 'static + composite::$module::Hooks<$($electoral_system,)*>> CompositeVoterApi<CompositeRunner<($($electoral_system,)*), ValidatorId, StorageAccess, Hooks>> for CompositeVoter<CompositeRunner<($($electoral_system,)*), ValidatorId, StorageAccess, Hooks>, ($($voter,)*)> {
async fn vote(
&self,
settings: <Composite<($($electoral_system,)*), ValidatorId, Hooks> as ElectoralSystem>::ElectoralSettings,
properties: <Composite<($($electoral_system,)*), ValidatorId, Hooks> as ElectoralSystem>::ElectionProperties,
settings: <CompositeRunner<($($electoral_system,)*), ValidatorId, StorageAccess, Hooks> as ElectoralSystemRunner>::ElectoralSettings,
properties: <CompositeRunner<($($electoral_system,)*), ValidatorId, StorageAccess, Hooks> as ElectoralSystemRunner>::ElectionProperties,
) -> Result<
<<Composite<($($electoral_system,)*), ValidatorId, Hooks> as ElectoralSystem>::Vote as VoteStorage>::Vote,
<<CompositeRunner<($($electoral_system,)*), ValidatorId, StorageAccess, Hooks> as ElectoralSystemRunner>::Vote as VoteStorage>::Vote,
anyhow::Error,
> {
use vote_storage::composite::$module::CompositeVote;
Expand Down
21 changes: 10 additions & 11 deletions engine/src/state_chain_observer/client/electoral_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use crate::state_chain_observer::client::{
};
use codec::{Decode, Encode};
use pallet_cf_elections::{
electoral_system::{ElectionIdentifierOf, ElectoralSystem},
vote_storage::VoteStorage,
ElectoralDataFor,
electoral_system_runner::CompositeElectionIdentifierOf, vote_storage::VoteStorage,
ElectoralDataFor, ElectoralSystemRunner,
};
use state_chain_runtime::SolanaInstance;
use std::collections::{BTreeMap, BTreeSet};
Expand All @@ -29,10 +28,10 @@ where
fn filter_votes(
&self,
proposed_votes: BTreeMap<
ElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem>,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::Vote,
CompositeElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner>,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner as ElectoralSystemRunner>::Vote as VoteStorage>::Vote,
>,
) -> impl std::future::Future<Output = BTreeSet<ElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystem>>> + Send + 'static;
) -> impl std::future::Future<Output = BTreeSet<CompositeElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<Instance>>::ElectoralSystemRunner>>> + Send + 'static;
}

impl<
Expand Down Expand Up @@ -68,10 +67,10 @@ impl<
fn filter_votes(
&self,
proposed_votes: BTreeMap<
ElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystem>,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::Vote,
CompositeElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystemRunner>,
<<<state_chain_runtime::Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystemRunner as ElectoralSystemRunner>::Vote as VoteStorage>::Vote,
>,
) -> impl std::future::Future<Output = BTreeSet<ElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystem>>> + Send + 'static{
) -> impl std::future::Future<Output = BTreeSet<CompositeElectionIdentifierOf<<state_chain_runtime::Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystemRunner>>> + Send + 'static{
let base_rpc_client = self.base_rpc_client.clone();
let account_id = self.signed_extrinsic_client.account_id();
async move {
Expand All @@ -82,10 +81,10 @@ impl<
.map_err(anyhow::Error::from)
.and_then(|electoral_data| {
<BTreeSet<
ElectionIdentifierOf<
CompositeElectionIdentifierOf<
<state_chain_runtime::Runtime as pallet_cf_elections::Config<
SolanaInstance,
>>::ElectoralSystem,
>>::ElectoralSystemRunner,
>,
> as Decode>::decode(&mut &electoral_data[..])
.map_err(Into::into)
Expand Down
4 changes: 2 additions & 2 deletions engine/src/witness/sol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use futures::FutureExt;
use pallet_cf_elections::{electoral_system::ElectoralSystem, vote_storage::VoteStorage};
use state_chain_runtime::{
chainflip::solana_elections::{
SolanaBlockHeightTracking, SolanaEgressWitnessing, SolanaElectoralSystem,
SolanaBlockHeightTracking, SolanaEgressWitnessing, SolanaElectoralSystemRunner,
SolanaFeeTracking, SolanaIngressTracking, SolanaLiveness, SolanaNonceTracking,
TransactionSuccessDetails,
},
Expand Down Expand Up @@ -195,7 +195,7 @@ where
crate::elections::Voter::new(
scope,
state_chain_client,
CompositeVoter::<SolanaElectoralSystem, _>::new((
CompositeVoter::<SolanaElectoralSystemRunner, _>::new((
SolanaBlockHeightTrackingVoter { client: client.clone() },
SolanaFeeTrackingVoter { client: client.clone() },
SolanaIngressTrackingVoter { client: client.clone() },
Expand Down
20 changes: 10 additions & 10 deletions state-chain/cf-integration-tests/src/solana.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ use frame_support::{
traits::{OnFinalize, UnfilteredDispatchable},
};
use pallet_cf_elections::{
electoral_system::{ElectionIdentifierOf, ElectoralSystem},
vote_storage::{composite::tuple_6_impls::CompositeVote, AuthorityVote, VoteStorage},
MAXIMUM_VOTES_PER_EXTRINSIC,
vote_storage::{composite::tuple_6_impls::CompositeVote, AuthorityVote},
CompositeAuthorityVoteOf, CompositeElectionIdentifierOf, MAXIMUM_VOTES_PER_EXTRINSIC,
};
use pallet_cf_ingress_egress::{DepositWitness, FetchOrTransfer};
use pallet_cf_validator::RotationPhase;
Expand Down Expand Up @@ -58,11 +57,12 @@ const BOB: AccountId = AccountId::new([0x44; 32]);
const DEPOSIT_AMOUNT: u64 = 5_000_000_000u64; // 5 Sol
const FALLBACK_ADDRESS: SolAddress = SolAddress([0xf0; 32]);

type SolanaElectionVote = BoundedBTreeMap::<
ElectionIdentifierOf<<Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystem>,
AuthorityVote<
<<<Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::PartialVote,
<<<Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystem as ElectoralSystem>::Vote as VoteStorage>::Vote,
type SolanaElectionVote = BoundedBTreeMap<
CompositeElectionIdentifierOf<
<Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystemRunner,
>,
CompositeAuthorityVoteOf<
<Runtime as pallet_cf_elections::Config<SolanaInstance>>::ElectoralSystemRunner,
>,
ConstU32<MAXIMUM_VOTES_PER_EXTRINSIC>,
>;
Expand Down Expand Up @@ -729,8 +729,8 @@ fn solana_ccm_execution_error_can_trigger_fallback() {
let ccm_broadcast_id = pallet_cf_broadcast::PendingBroadcasts::<Runtime, SolanaInstance>::get().into_iter().next().unwrap();

// Get the election identifier of the Solana egress.
let election_id = SolanaElections::with_electoral_access_and_identifiers(
|_, election_identifiers| {
let election_id = SolanaElections::with_election_identifiers(
|election_identifiers| {
Ok(election_identifiers.last().cloned().unwrap())
},
).unwrap();
Expand Down
Loading