diff --git a/crates/examples/infra/mod.rs b/crates/examples/infra/mod.rs index 88a2ff900b..0d51195320 100755 --- a/crates/examples/infra/mod.rs +++ b/crates/examples/infra/mod.rs @@ -532,6 +532,7 @@ pub trait RunDa< .hotshot .memberships .committee_leaders(TYPES::View::genesis(), TYPES::Epoch::genesis()) + .await .len(); let total_num_views = usize::try_from(consensus.locked_view().u64()).unwrap(); // `failed_num_views` could include uncommitted views diff --git a/crates/hotshot/src/lib.rs b/crates/hotshot/src/lib.rs index 16fa47f31d..c52dee77a8 100644 --- a/crates/hotshot/src/lib.rs +++ b/crates/hotshot/src/lib.rs @@ -518,7 +518,7 @@ impl, V: Versions> SystemContext Membership for RandomizedCommittee { } /// Get the stake table for the current view - fn stake_table( + async fn stake_table( &self, _epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -110,7 +110,7 @@ impl Membership for RandomizedCommittee { } /// Get the stake table for the current view - fn da_stake_table( + async fn da_stake_table( &self, _epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -118,7 +118,7 @@ impl Membership for RandomizedCommittee { } /// Get all members of the committee for the current view - fn committee_members( + async fn committee_members( &self, _view_number: ::View, _epoch: ::Epoch, @@ -130,7 +130,7 @@ impl Membership for RandomizedCommittee { } /// Get all members of the committee for the current view - fn da_committee_members( + async fn da_committee_members( &self, _view_number: ::View, _epoch: ::Epoch, @@ -142,7 +142,7 @@ impl Membership for RandomizedCommittee { } /// Get all eligible leaders of the committee for the current view - fn committee_leaders( + async fn committee_leaders( &self, _view_number: ::View, _epoch: ::Epoch, @@ -154,7 +154,7 @@ impl Membership for RandomizedCommittee { } /// Get the stake table entry for a public key - fn stake( + async fn stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -164,7 +164,7 @@ impl Membership for RandomizedCommittee { } /// Get the stake table entry for a public key - fn da_stake( + async fn da_stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -174,7 +174,7 @@ impl Membership for RandomizedCommittee { } /// Check if a node has stake in the committee - fn has_stake( + async fn has_stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -185,7 +185,7 @@ impl Membership for RandomizedCommittee { } /// Check if a node has stake in the committee - fn has_da_stake( + async fn has_da_stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -201,7 +201,7 @@ impl Membership for RandomizedCommittee { // } /// Index the vector of public keys with the current view number - fn lookup_leader( + async fn lookup_leader( &self, view_number: TYPES::View, _epoch: ::Epoch, @@ -218,30 +218,30 @@ impl Membership for RandomizedCommittee { } /// Get the total number of nodes in the committee - fn total_nodes(&self, _epoch: ::Epoch) -> usize { + async fn total_nodes(&self, _epoch: ::Epoch) -> usize { self.stake_table.len() } /// Get the total number of nodes in the committee - fn da_total_nodes(&self, _epoch: ::Epoch) -> usize { + async fn da_total_nodes(&self, _epoch: ::Epoch) -> usize { self.da_stake_table.len() } /// Get the voting success threshold for the committee - fn success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64 * 2) / 3) + 1).unwrap() } /// Get the voting success threshold for the committee - fn da_success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn da_success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.da_stake_table.len() as u64 * 2) / 3) + 1).unwrap() } /// Get the voting failure threshold for the committee - fn failure_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn failure_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64) / 3) + 1).unwrap() } /// Get the voting upgrade threshold for the committee - fn upgrade_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn upgrade_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(max( (self.stake_table.len() as u64 * 9) / 10, ((self.stake_table.len() as u64 * 2) / 3) + 1, diff --git a/crates/hotshot/src/traits/election/randomized_committee_members.rs b/crates/hotshot/src/traits/election/randomized_committee_members.rs index 5c85ad9c07..19fa22ed05 100644 --- a/crates/hotshot/src/traits/election/randomized_committee_members.rs +++ b/crates/hotshot/src/traits/election/randomized_committee_members.rs @@ -125,7 +125,7 @@ impl Membership } /// Get the stake table for the current view - fn stake_table( + async fn stake_table( &self, epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -140,7 +140,7 @@ impl Membership } /// Get the da stake table for the current view - fn da_stake_table( + async fn da_stake_table( &self, epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -155,11 +155,11 @@ impl Membership } /// Get all members of the committee for the current view - fn committee_members( + async fn committee_members( &self, _view_number: ::View, epoch: ::Epoch, - ) -> BTreeSet<::SignatureKey> { + ) -> BTreeSet { let filter = self.make_quorum_filter(epoch); self.stake_table .iter() @@ -170,7 +170,7 @@ impl Membership } /// Get all members of the committee for the current view - fn da_committee_members( + async fn da_committee_members( &self, _view_number: ::View, epoch: ::Epoch, @@ -189,12 +189,12 @@ impl Membership &self, view_number: ::View, epoch: ::Epoch, - ) -> BTreeSet<::SignatureKey> { + ) -> impl futures::Future> + Send { self.committee_members(view_number, epoch) } /// Get the stake table entry for a public key - fn stake( + async fn stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -218,7 +218,7 @@ impl Membership } /// Get the da stake table entry for a public key - fn da_stake( + async fn da_stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -242,7 +242,7 @@ impl Membership } /// Check if a node has stake in the committee - fn has_stake( + async fn has_stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -267,7 +267,7 @@ impl Membership } /// Check if a node has stake in the committee - fn has_da_stake( + async fn has_da_stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -292,7 +292,7 @@ impl Membership } /// Index the vector of public keys with the current view number - fn lookup_leader( + async fn lookup_leader( &self, view_number: TYPES::View, epoch: ::Epoch, @@ -318,36 +318,36 @@ impl Membership } /// Get the total number of nodes in the committee - fn total_nodes(&self, epoch: ::Epoch) -> usize { + async fn total_nodes(&self, epoch: ::Epoch) -> usize { self.make_quorum_filter(epoch).len() } /// Get the total number of nodes in the committee - fn da_total_nodes(&self, epoch: ::Epoch) -> usize { + async fn da_total_nodes(&self, epoch: ::Epoch) -> usize { self.make_da_quorum_filter(epoch).len() } /// Get the voting success threshold for the committee - fn success_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { - let len = self.total_nodes(epoch); + async fn success_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { + let len = self.total_nodes(epoch).await; NonZeroU64::new(((len as u64 * 2) / 3) + 1).unwrap() } /// Get the voting success threshold for the committee - fn da_success_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { - let len = self.da_total_nodes(epoch); + async fn da_success_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { + let len = self.da_total_nodes(epoch).await; NonZeroU64::new(((len as u64 * 2) / 3) + 1).unwrap() } /// Get the voting failure threshold for the committee - fn failure_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { - let len = self.total_nodes(epoch); + async fn failure_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { + let len = self.total_nodes(epoch).await; NonZeroU64::new(((len as u64) / 3) + 1).unwrap() } /// Get the voting upgrade threshold for the committee - fn upgrade_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { - let len = self.total_nodes(epoch); + async fn upgrade_threshold(&self, epoch: ::Epoch) -> NonZeroU64 { + let len = self.total_nodes(epoch).await; NonZeroU64::new(max((len as u64 * 9) / 10, ((len as u64 * 2) / 3) + 1)).unwrap() } } diff --git a/crates/hotshot/src/traits/election/static_committee.rs b/crates/hotshot/src/traits/election/static_committee.rs index d2b62f80b7..ebfd7ffee4 100644 --- a/crates/hotshot/src/traits/election/static_committee.rs +++ b/crates/hotshot/src/traits/election/static_committee.rs @@ -99,7 +99,7 @@ impl Membership for StaticCommittee { } /// Get the stake table for the current view - fn stake_table( + async fn stake_table( &self, _epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -107,7 +107,7 @@ impl Membership for StaticCommittee { } /// Get the stake table for the current view - fn da_stake_table( + async fn da_stake_table( &self, _epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -115,7 +115,7 @@ impl Membership for StaticCommittee { } /// Get all members of the committee for the current view - fn committee_members( + async fn committee_members( &self, _view_number: ::View, _epoch: ::Epoch, @@ -127,7 +127,7 @@ impl Membership for StaticCommittee { } /// Get all members of the committee for the current view - fn da_committee_members( + async fn da_committee_members( &self, _view_number: ::View, _epoch: ::Epoch, @@ -139,7 +139,7 @@ impl Membership for StaticCommittee { } /// Get all eligible leaders of the committee for the current view - fn committee_leaders( + async fn committee_leaders( &self, _view_number: ::View, _epoch: ::Epoch, @@ -151,7 +151,7 @@ impl Membership for StaticCommittee { } /// Get the stake table entry for a public key - fn stake( + async fn stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -161,7 +161,7 @@ impl Membership for StaticCommittee { } /// Get the DA stake table entry for a public key - fn da_stake( + async fn da_stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -171,7 +171,7 @@ impl Membership for StaticCommittee { } /// Check if a node has stake in the committee - fn has_stake( + async fn has_stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -182,7 +182,7 @@ impl Membership for StaticCommittee { } /// Check if a node has stake in the committee - fn has_da_stake( + async fn has_da_stake( &self, pub_key: &::SignatureKey, _epoch: ::Epoch, @@ -193,7 +193,7 @@ impl Membership for StaticCommittee { } /// Index the vector of public keys with the current view number - fn lookup_leader( + async fn lookup_leader( &self, view_number: TYPES::View, _epoch: ::Epoch, @@ -205,32 +205,32 @@ impl Membership for StaticCommittee { } /// Get the total number of nodes in the committee - fn total_nodes(&self, _epoch: ::Epoch) -> usize { + async fn total_nodes(&self, _epoch: ::Epoch) -> usize { self.stake_table.len() } /// Get the total number of DA nodes in the committee - fn da_total_nodes(&self, _epoch: ::Epoch) -> usize { + async fn da_total_nodes(&self, _epoch: ::Epoch) -> usize { self.da_stake_table.len() } /// Get the voting success threshold for the committee - fn success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64 * 2) / 3) + 1).unwrap() } /// Get the voting success threshold for the committee - fn da_success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn da_success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.da_stake_table.len() as u64 * 2) / 3) + 1).unwrap() } /// Get the voting failure threshold for the committee - fn failure_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn failure_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64) / 3) + 1).unwrap() } /// Get the voting upgrade threshold for the committee - fn upgrade_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn upgrade_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { let len = self.stake_table.len(); NonZeroU64::new(max((len as u64 * 9) / 10, ((len as u64 * 2) / 3) + 1)).unwrap() } diff --git a/crates/hotshot/src/traits/election/static_committee_leader_two_views.rs b/crates/hotshot/src/traits/election/static_committee_leader_two_views.rs index 8833d06872..071dc76ab7 100644 --- a/crates/hotshot/src/traits/election/static_committee_leader_two_views.rs +++ b/crates/hotshot/src/traits/election/static_committee_leader_two_views.rs @@ -100,7 +100,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -108,7 +108,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -116,7 +116,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::View, _epoch: ::Epoch, @@ -128,7 +128,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::View, _epoch: ::Epoch, @@ -140,7 +140,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::View, _epoch: ::Epoch, @@ -152,7 +152,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::SignatureKey, _epoch: ::Epoch, @@ -162,7 +162,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::SignatureKey, _epoch: ::Epoch, @@ -172,7 +172,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::SignatureKey, _epoch: ::Epoch, @@ -183,7 +183,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::SignatureKey, _epoch: ::Epoch, @@ -194,7 +194,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::Epoch, @@ -207,32 +207,32 @@ impl Membership for StaticCommitteeLeaderForTwoViews::Epoch) -> usize { + async fn total_nodes(&self, _epoch: ::Epoch) -> usize { self.stake_table.len() } /// Get the total number of DA nodes in the committee - fn da_total_nodes(&self, _epoch: ::Epoch) -> usize { + async fn da_total_nodes(&self, _epoch: ::Epoch) -> usize { self.da_stake_table.len() } /// Get the voting success threshold for the committee - fn success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64 * 2) / 3) + 1).unwrap() } /// Get the voting success threshold for the committee - fn da_success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn da_success_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.da_stake_table.len() as u64 * 2) / 3) + 1).unwrap() } /// Get the voting failure threshold for the committee - fn failure_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn failure_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64) / 3) + 1).unwrap() } /// Get the voting upgrade threshold for the committee - fn upgrade_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { + async fn upgrade_threshold(&self, _epoch: ::Epoch) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64 * 9) / 10) + 1).unwrap() } } diff --git a/crates/hotshot/src/traits/election/two_static_committees.rs b/crates/hotshot/src/traits/election/two_static_committees.rs index 25af69905c..520af9ce0f 100644 --- a/crates/hotshot/src/traits/election/two_static_committees.rs +++ b/crates/hotshot/src/traits/election/two_static_committees.rs @@ -176,7 +176,7 @@ impl Membership for TwoStaticCommittees { } /// Get the stake table for the current view - fn stake_table( + async fn stake_table( &self, epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -188,7 +188,7 @@ impl Membership for TwoStaticCommittees { } /// Get the stake table for the current view - fn da_stake_table( + async fn da_stake_table( &self, epoch: ::Epoch, ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { @@ -200,7 +200,7 @@ impl Membership for TwoStaticCommittees { } /// Get all members of the committee for the current view - fn committee_members( + async fn committee_members( &self, _view_number: ::View, epoch: ::Epoch, @@ -221,7 +221,7 @@ impl Membership for TwoStaticCommittees { } /// Get all members of the committee for the current view - fn da_committee_members( + async fn da_committee_members( &self, _view_number: ::View, epoch: ::Epoch, @@ -242,7 +242,7 @@ impl Membership for TwoStaticCommittees { } /// Get all eligible leaders of the committee for the current view - fn committee_leaders( + async fn committee_leaders( &self, _view_number: ::View, epoch: ::Epoch, @@ -263,7 +263,7 @@ impl Membership for TwoStaticCommittees { } /// Get the stake table entry for a public key - fn stake( + async fn stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -277,7 +277,7 @@ impl Membership for TwoStaticCommittees { } /// Get the DA stake table entry for a public key - fn da_stake( + async fn da_stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -291,7 +291,7 @@ impl Membership for TwoStaticCommittees { } /// Check if a node has stake in the committee - fn has_stake( + async fn has_stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -310,7 +310,7 @@ impl Membership for TwoStaticCommittees { } /// Check if a node has stake in the committee - fn has_da_stake( + async fn has_da_stake( &self, pub_key: &::SignatureKey, epoch: ::Epoch, @@ -329,7 +329,7 @@ impl Membership for TwoStaticCommittees { } /// Index the vector of public keys with the current view number - fn lookup_leader( + async fn lookup_leader( &self, view_number: TYPES::View, epoch: ::Epoch, @@ -348,7 +348,7 @@ impl Membership for TwoStaticCommittees { } /// Get the total number of nodes in the committee - fn total_nodes(&self, epoch: ::Epoch) -> usize { + async fn total_nodes(&self, epoch: ::Epoch) -> usize { if *epoch != 0 && *epoch % 2 == 0 { self.stake_table.0.len() } else { @@ -357,7 +357,7 @@ impl Membership for TwoStaticCommittees { } /// Get the total number of DA nodes in the committee - fn da_total_nodes(&self, epoch: ::Epoch) -> usize { + async fn da_total_nodes(&self, epoch: ::Epoch) -> usize { if *epoch != 0 && *epoch % 2 == 0 { self.da_stake_table.0.len() } else { @@ -366,7 +366,7 @@ impl Membership for TwoStaticCommittees { } /// Get the voting success threshold for the committee - fn success_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { + async fn success_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { if *epoch != 0 && *epoch % 2 == 0 { NonZeroU64::new(((self.stake_table.0.len() as u64 * 2) / 3) + 1).unwrap() } else { @@ -375,7 +375,7 @@ impl Membership for TwoStaticCommittees { } /// Get the voting success threshold for the committee - fn da_success_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { + async fn da_success_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { if *epoch != 0 && *epoch % 2 == 0 { NonZeroU64::new(((self.da_stake_table.0.len() as u64 * 2) / 3) + 1).unwrap() } else { @@ -384,7 +384,7 @@ impl Membership for TwoStaticCommittees { } /// Get the voting failure threshold for the committee - fn failure_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { + async fn failure_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { if *epoch != 0 && *epoch % 2 == 0 { NonZeroU64::new(((self.stake_table.0.len() as u64) / 3) + 1).unwrap() } else { @@ -393,7 +393,7 @@ impl Membership for TwoStaticCommittees { } /// Get the voting upgrade threshold for the committee - fn upgrade_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { + async fn upgrade_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64 { if *epoch != 0 && *epoch % 2 == 0 { NonZeroU64::new(max( (self.stake_table.0.len() as u64 * 9) / 10, diff --git a/crates/hotshot/src/traits/networking/libp2p_network.rs b/crates/hotshot/src/traits/networking/libp2p_network.rs index 0f1fbfc858..4a995d996d 100644 --- a/crates/hotshot/src/traits/networking/libp2p_network.rs +++ b/crates/hotshot/src/traits/networking/libp2p_network.rs @@ -984,7 +984,7 @@ impl ConnectedNetwork for Libp2pNetwork { { let future_view = ::View::new(view) + LOOK_AHEAD; let epoch = ::Epoch::new(epoch); - let future_leader = match membership.leader(future_view, epoch) { + let future_leader = match membership.leader(future_view, epoch).await { Ok(l) => l, Err(e) => { return tracing::info!( diff --git a/crates/hotshot/src/types/handle.rs b/crates/hotshot/src/types/handle.rs index e3024e876b..7f05091d84 100644 --- a/crates/hotshot/src/types/handle.rs +++ b/crates/hotshot/src/types/handle.rs @@ -187,7 +187,7 @@ impl + 'static, V: Versions> if let HotShotEvent::QuorumProposalResponseRecv(quorum_proposal) = hs_event.as_ref() { // Make sure that the quorum_proposal is valid - if let Err(err) = quorum_proposal.validate_signature(&mem, epoch_height) { + if let Err(err) = quorum_proposal.validate_signature(&mem, epoch_height).await { tracing::warn!("Invalid Proposal Received after Request. Err {:?}", err); continue; } @@ -327,6 +327,7 @@ impl + 'static, V: Versions> self.hotshot .memberships .leader(view_number, epoch_number) + .await .context("Failed to lookup leader") } diff --git a/crates/libp2p-networking/src/network/transport.rs b/crates/libp2p-networking/src/network/transport.rs index aac8a66b60..c182afa505 100644 --- a/crates/libp2p-networking/src/network/transport.rs +++ b/crates/libp2p-networking/src/network/transport.rs @@ -136,7 +136,10 @@ impl StakeTableAuthentica } // Check if the public key is in the stake table - if !stake_table.has_stake(&public_key, Types::Epoch::new(0)) { + if !stake_table + .has_stake(&public_key, Types::Epoch::new(0)) + .await + { return Err(anyhow::anyhow!("Peer not in stake table")); } } diff --git a/crates/task-impls/src/consensus/handlers.rs b/crates/task-impls/src/consensus/handlers.rs index fbd1960ce4..286b561c84 100644 --- a/crates/task-impls/src/consensus/handlers.rs +++ b/crates/task-impls/src/consensus/handlers.rs @@ -46,7 +46,8 @@ pub(crate) async fn handle_quorum_vote_recv< .is_high_qc_for_last_block(); let we_are_leader = task_state .membership - .leader(vote.view_number() + 1, task_state.cur_epoch)? + .leader(vote.view_number() + 1, task_state.cur_epoch) + .await? == task_state.public_key; ensure!( in_transition || we_are_leader, @@ -88,7 +89,8 @@ pub(crate) async fn handle_timeout_vote_recv< ensure!( task_state .membership - .leader(vote.view_number() + 1, task_state.cur_epoch)? + .leader(vote.view_number() + 1, task_state.cur_epoch) + .await? == task_state.public_key, info!( "We are not the leader for view {:?}", @@ -132,7 +134,8 @@ pub async fn send_high_qc ensure!( task_state .membership - .has_stake(&task_state.public_key, epoch), + .has_stake(&task_state.public_key, epoch) + .await, debug!( "We were not chosen for the consensus committee for view {:?}", view_number @@ -348,7 +353,8 @@ pub(crate) async fn handle_timeout .add(1); if task_state .membership - .leader(view_number, task_state.cur_epoch)? + .leader(view_number, task_state.cur_epoch) + .await? == task_state.public_key { task_state diff --git a/crates/task-impls/src/da.rs b/crates/task-impls/src/da.rs index fb2775d378..bbddc04188 100644 --- a/crates/task-impls/src/da.rs +++ b/crates/task-impls/src/da.rs @@ -120,7 +120,7 @@ impl, V: Versions> DaTaskState, V: Versions> DaTaskState, V: Versions> DaTaskState, V: Versions> DaTaskState, V: Versions> DaTaskState( hs_event.as_ref() { // Make sure that the quorum_proposal is valid - if quorum_proposal.validate_signature(&mem, epoch_height).is_ok() { + if quorum_proposal.validate_signature(&mem, epoch_height).await.is_ok() { proposal = Some(quorum_proposal.clone()); } @@ -128,8 +128,8 @@ pub(crate) async fn fetch_proposal( let justify_qc_epoch = justify_qc.data.epoch(); if !justify_qc .is_valid_cert( - quorum_membership.stake_table(justify_qc_epoch), - quorum_membership.success_threshold(justify_qc_epoch), + quorum_membership.stake_table(justify_qc_epoch).await, + quorum_membership.success_threshold(justify_qc_epoch).await, upgrade_lock, ) .await @@ -654,10 +654,12 @@ pub(crate) async fn validate_proposal_view_and_certs< ); // Validate the proposal's signature. This should also catch if the leaf_commitment does not equal our calculated parent commitment - proposal.validate_signature( - &validation_info.quorum_membership, - validation_info.epoch_height, - )?; + proposal + .validate_signature( + &validation_info.quorum_membership, + validation_info.epoch_height, + ) + .await?; // Verify a timeout certificate OR a view sync certificate exists and is valid. if proposal.data.justify_qc.view_number() != view_number - 1 { @@ -680,10 +682,12 @@ pub(crate) async fn validate_proposal_view_and_certs< .is_valid_cert( validation_info .quorum_membership - .stake_table(timeout_cert_epoch), + .stake_table(timeout_cert_epoch) + .await, validation_info .quorum_membership - .success_threshold(timeout_cert_epoch), + .success_threshold(timeout_cert_epoch) + .await, &validation_info.upgrade_lock ) .await, @@ -706,10 +710,12 @@ pub(crate) async fn validate_proposal_view_and_certs< .is_valid_cert( validation_info .quorum_membership - .stake_table(view_sync_cert_epoch), + .stake_table(view_sync_cert_epoch) + .await, validation_info .quorum_membership - .success_threshold(view_sync_cert_epoch), + .success_threshold(view_sync_cert_epoch) + .await, &validation_info.upgrade_lock ) .await, diff --git a/crates/task-impls/src/network.rs b/crates/task-impls/src/network.rs index 2d459013b6..816407b3b9 100644 --- a/crates/task-impls/src/network.rs +++ b/crates/task-impls/src/network.rs @@ -310,7 +310,8 @@ impl< if let Some((sender, message_kind, transmit)) = self.parse_event(event, &mut maybe_action).await { - self.spawn_transmit_task(message_kind, maybe_action, transmit, sender); + self.spawn_transmit_task(message_kind, maybe_action, transmit, sender) + .await; }; } @@ -449,7 +450,7 @@ impl< HotShotEvent::QuorumVoteSend(vote) => { *maybe_action = Some(HotShotAction::Vote); let view_number = vote.view_number() + 1; - let leader = match self.membership.leader(view_number, self.epoch) { + let leader = match self.membership.leader(view_number, self.epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -554,7 +555,7 @@ impl< *maybe_action = Some(HotShotAction::DaVote); let view_number = vote.view_number(); let epoch = vote.data.epoch; - let leader = match self.membership.leader(view_number, epoch) { + let leader = match self.membership.leader(view_number, epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -601,7 +602,7 @@ impl< } HotShotEvent::ViewSyncPreCommitVoteSend(vote) => { let view_number = vote.view_number() + vote.date().relay; - let leader = match self.membership.leader(view_number, self.epoch) { + let leader = match self.membership.leader(view_number, self.epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -632,7 +633,7 @@ impl< HotShotEvent::ViewSyncCommitVoteSend(vote) => { *maybe_action = Some(HotShotAction::ViewSyncVote); let view_number = vote.view_number() + vote.date().relay; - let leader = match self.membership.leader(view_number, self.epoch) { + let leader = match self.membership.leader(view_number, self.epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -663,7 +664,7 @@ impl< HotShotEvent::ViewSyncFinalizeVoteSend(vote) => { *maybe_action = Some(HotShotAction::ViewSyncVote); let view_number = vote.view_number() + vote.date().relay; - let leader = match self.membership.leader(view_number, self.epoch) { + let leader = match self.membership.leader(view_number, self.epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -742,7 +743,7 @@ impl< HotShotEvent::TimeoutVoteSend(vote) => { *maybe_action = Some(HotShotAction::Vote); let view_number = vote.view_number() + 1; - let leader = match self.membership.leader(view_number, self.epoch) { + let leader = match self.membership.leader(view_number, self.epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -780,7 +781,7 @@ impl< HotShotEvent::UpgradeVoteSend(vote) => { tracing::error!("Sending upgrade vote!"); let view_number = vote.view_number(); - let leader = match self.membership.leader(view_number, self.epoch) { + let leader = match self.membership.leader(view_number, self.epoch).await { Ok(l) => l, Err(e) => { tracing::warn!( @@ -850,7 +851,7 @@ impl< } /// Creates a network message and spawns a task that transmits it on the wire. - fn spawn_transmit_task( + async fn spawn_transmit_task( &mut self, message_kind: MessageKind, maybe_action: Option, @@ -872,7 +873,8 @@ impl< let committee_topic = Topic::Global; let da_committee = self .membership - .da_committee_members(view_number, self.epoch); + .da_committee_members(view_number, self.epoch) + .await; let network = Arc::clone(&self.network); let storage = Arc::clone(&self.storage); let consensus = OuterConsensus::new(Arc::clone(&self.consensus.inner_consensus)); @@ -999,7 +1001,8 @@ pub mod test { &mut transmit, &self.membership, ); - self.spawn_transmit_task(message_kind, maybe_action, transmit, sender); + self.spawn_transmit_task(message_kind, maybe_action, transmit, sender) + .await; } } } diff --git a/crates/task-impls/src/quorum_proposal/handlers.rs b/crates/task-impls/src/quorum_proposal/handlers.rs index 7c29ffe426..e1c9bdecbe 100644 --- a/crates/task-impls/src/quorum_proposal/handlers.rs +++ b/crates/task-impls/src/quorum_proposal/handlers.rs @@ -132,8 +132,10 @@ impl ProposalDependencyHandle { .is_valid_cert( // TODO take epoch from `qc` // https://github.com/EspressoSystems/HotShot/issues/3917 - self.quorum_membership.stake_table(qc.data.epoch), - self.quorum_membership.success_threshold(qc.data.epoch), + self.quorum_membership.stake_table(qc.data.epoch).await, + self.quorum_membership + .success_threshold(qc.data.epoch) + .await, &self.upgrade_lock, ) .await @@ -306,7 +308,12 @@ impl ProposalDependencyHandle { )); // Make sure we are the leader for the view and epoch. // We might have ended up here because we were in the epoch transition. - if self.quorum_membership.leader(self.view_number, epoch)? != self.public_key { + if self + .quorum_membership + .leader(self.view_number, epoch) + .await? + != self.public_key + { tracing::debug!( "We are not the leader in the epoch for which we are about to propose. Do not send the quorum proposal." ); diff --git a/crates/task-impls/src/quorum_proposal/mod.rs b/crates/task-impls/src/quorum_proposal/mod.rs index ac1a9d7837..f116783fff 100644 --- a/crates/task-impls/src/quorum_proposal/mod.rs +++ b/crates/task-impls/src/quorum_proposal/mod.rs @@ -271,7 +271,7 @@ impl, V: Versions> /// without losing the data that it received, as the dependency task would otherwise have no /// ability to receive the event and, thus, would never propose. #[instrument(skip_all, fields(id = self.id, latest_proposed_view = *self.latest_proposed_view), name = "Create dependency task", level = "error")] - fn create_dependency_task_if_new( + async fn create_dependency_task_if_new( &mut self, view_number: TYPES::View, epoch_number: TYPES::Epoch, @@ -280,8 +280,11 @@ impl, V: Versions> event: Arc>, epoch_transition_indicator: EpochTransitionIndicator, ) -> Result<()> { - let leader_in_current_epoch = - self.quorum_membership.leader(view_number, epoch_number)? == self.public_key; + let leader_in_current_epoch = self + .quorum_membership + .leader(view_number, epoch_number) + .await? + == self.public_key; // If we are in the epoch transition and we are the leader in the next epoch, // we might want to start collecting dependencies for our next epoch proposal. let leader_in_next_epoch = matches!( @@ -289,7 +292,8 @@ impl, V: Versions> EpochTransitionIndicator::InTransition ) && self .quorum_membership - .leader(view_number, epoch_number + 1)? + .leader(view_number, epoch_number + 1) + .await? == self.public_key; // Don't even bother making the task if we are not entitled to propose anyway. ensure!( @@ -405,7 +409,8 @@ impl, V: Versions> event_sender, Arc::clone(&event), epoch_transition_indicator, - )?; + ) + .await?; } either::Left(qc) => { // Only update if the qc is from a newer view @@ -439,7 +444,8 @@ impl, V: Versions> event_sender, Arc::clone(&event), epoch_transition_indicator, - )?; + ) + .await?; } }, HotShotEvent::SendPayloadCommitmentAndMetadata( @@ -459,7 +465,8 @@ impl, V: Versions> event_sender, Arc::clone(&event), EpochTransitionIndicator::NotInTransition, - )?; + ) + .await?; } HotShotEvent::ViewSyncFinalizeCertificateRecv(certificate) => { // MERGE TODO @@ -472,8 +479,8 @@ impl, V: Versions> ensure!( certificate .is_valid_cert( - self.quorum_membership.stake_table(epoch_number), - self.quorum_membership.success_threshold(epoch_number), + self.quorum_membership.stake_table(epoch_number).await, + self.quorum_membership.success_threshold(epoch_number).await, &self.upgrade_lock ) .await, @@ -492,7 +499,8 @@ impl, V: Versions> event_sender, event, EpochTransitionIndicator::NotInTransition, - )?; + ) + .await?; } HotShotEvent::QuorumProposalPreliminarilyValidated(proposal) => { let view_number = proposal.data.view_number(); @@ -508,7 +516,8 @@ impl, V: Versions> event_sender, Arc::clone(&event), epoch_transition_indicator, - )?; + ) + .await?; } HotShotEvent::QuorumProposalSend(proposal, _) => { let view = proposal.data.view_number(); @@ -527,7 +536,8 @@ impl, V: Versions> event_sender, Arc::clone(&event), EpochTransitionIndicator::NotInTransition, - )?; + ) + .await?; } HotShotEvent::ViewChange(view, epoch) => { if epoch > &self.cur_epoch { @@ -543,8 +553,10 @@ impl, V: Versions> let cert_epoch_number = qc.data.epoch; ensure!( qc.is_valid_cert( - self.quorum_membership.stake_table(cert_epoch_number), - self.quorum_membership.success_threshold(cert_epoch_number), + self.quorum_membership.stake_table(cert_epoch_number).await, + self.quorum_membership + .success_threshold(cert_epoch_number) + .await, &self.upgrade_lock ) .await, diff --git a/crates/task-impls/src/quorum_proposal_recv/handlers.rs b/crates/task-impls/src/quorum_proposal_recv/handlers.rs index 2f5df35a65..f20e83101a 100644 --- a/crates/task-impls/src/quorum_proposal_recv/handlers.rs +++ b/crates/task-impls/src/quorum_proposal_recv/handlers.rs @@ -163,10 +163,12 @@ pub(crate) async fn handle_quorum_proposal_recv< .is_valid_cert( validation_info .quorum_membership - .stake_table(justify_qc.data.epoch), + .stake_table(justify_qc.data.epoch) + .await, validation_info .quorum_membership - .success_threshold(justify_qc.data.epoch), + .success_threshold(justify_qc.data.epoch) + .await, &validation_info.upgrade_lock, ) .await diff --git a/crates/task-impls/src/quorum_vote/handlers.rs b/crates/task-impls/src/quorum_vote/handlers.rs index 98f8c5561d..0ab5390e2b 100644 --- a/crates/task-impls/src/quorum_vote/handlers.rs +++ b/crates/task-impls/src/quorum_vote/handlers.rs @@ -60,6 +60,7 @@ async fn handle_quorum_proposal_validated_drb_calculation_start< if task_state .membership .has_stake(&task_state.public_key, current_epoch_number) + .await { task_state .drb_computations @@ -80,7 +81,7 @@ async fn handle_quorum_proposal_validated_drb_calculation_start< /// /// We don't need to handle the special cases explicitly here, because the first proposal /// with which we'll start the DRB computation is for epoch 3. -fn handle_quorum_proposal_validated_drb_calculation_seed< +async fn handle_quorum_proposal_validated_drb_calculation_seed< TYPES: NodeType, I: NodeImplementation, V: Versions, @@ -113,6 +114,7 @@ fn handle_quorum_proposal_validated_drb_calculation_seed< if task_state .membership .has_stake(&task_state.public_key, current_epoch_number + 1) + .await { let new_epoch_number = current_epoch_number + 2; let Ok(drb_seed_input_vec) = bincode::serialize(&proposal.justify_qc.signatures) else { @@ -252,7 +254,8 @@ pub(crate) async fn handle_quorum_proposal_validated< proposal, task_state, &leaf_views, - )?; + ) + .await?; } } @@ -413,7 +416,7 @@ pub(crate) async fn submit_vote, V )); ensure!( - quorum_membership.has_stake(&public_key, epoch_number), + quorum_membership.has_stake(&public_key, epoch_number).await, info!( "We were not chosen for quorum committee on {:?}", view_number diff --git a/crates/task-impls/src/quorum_vote/mod.rs b/crates/task-impls/src/quorum_vote/mod.rs index 04b8a677dc..78b9abd3e0 100644 --- a/crates/task-impls/src/quorum_vote/mod.rs +++ b/crates/task-impls/src/quorum_vote/mod.rs @@ -507,8 +507,8 @@ impl, V: Versions> QuorumVoteTaskS // Validate the DAC. ensure!( cert.is_valid_cert( - self.membership.da_stake_table(cert_epoch), - self.membership.da_success_threshold(cert_epoch), + self.membership.da_stake_table(cert_epoch).await, + self.membership.da_success_threshold(cert_epoch).await, &self.upgrade_lock ) .await, @@ -551,14 +551,15 @@ impl, V: Versions> QuorumVoteTaskS ensure!( self.membership .da_committee_members(view, disperse_epoch) + .await .contains(sender) - || *sender == self.membership.leader(view, disperse_epoch)?, + || *sender == self.membership.leader(view, disperse_epoch).await?, "VID share was not sent by a DA member or the view leader." ); // NOTE: `verify_share` returns a nested `Result`, so we must check both the inner // and outer results - match vid_scheme(self.membership.total_nodes(disperse_epoch)).verify_share( + match vid_scheme(self.membership.total_nodes(disperse_epoch).await).verify_share( &disperse.data.share, &disperse.data.common, payload_commitment, diff --git a/crates/task-impls/src/request.rs b/crates/task-impls/src/request.rs index 56e16c1a37..2ace2b8b08 100644 --- a/crates/task-impls/src/request.rs +++ b/crates/task-impls/src/request.rs @@ -113,7 +113,8 @@ impl> TaskState for NetworkRequest .vid_shares() .contains_key(&prop_view) { - self.spawn_requests(prop_view, prop_epoch, sender, receiver); + self.spawn_requests(prop_view, prop_epoch, sender, receiver) + .await; } Ok(()) } @@ -145,7 +146,7 @@ impl> TaskState for NetworkRequest impl> NetworkRequestState { /// Creates and signs the payload, then will create a request task - fn spawn_requests( + async fn spawn_requests( &mut self, view: TYPES::View, epoch: TYPES::Epoch, @@ -163,13 +164,14 @@ impl> NetworkRequestState, signature: Signature, @@ -185,8 +187,8 @@ impl> NetworkRequestState> NetworkRequestState = self .membership .da_committee_members(view, epoch) + .await .into_iter() .collect(); // Randomize the recipients so all replicas don't overload the same 1 recipients diff --git a/crates/task-impls/src/response.rs b/crates/task-impls/src/response.rs index 27983cdffa..9bb271dc55 100644 --- a/crates/task-impls/src/response.rs +++ b/crates/task-impls/src/response.rs @@ -72,7 +72,9 @@ impl NetworkResponseState { match event.as_ref() { HotShotEvent::VidRequestRecv(request, sender) => { // Verify request is valid - if !self.valid_sender(sender, self.consensus.read().await.cur_epoch()) + if !self + .valid_sender(sender, self.consensus.read().await.cur_epoch()) + .await || !valid_signature::(request, sender) { continue; @@ -178,8 +180,8 @@ impl NetworkResponseState { } /// Makes sure the sender is allowed to send a request in the given epoch. - fn valid_sender(&self, sender: &TYPES::SignatureKey, epoch: TYPES::Epoch) -> bool { - self.quorum.has_stake(sender, epoch) + async fn valid_sender(&self, sender: &TYPES::SignatureKey, epoch: TYPES::Epoch) -> bool { + self.quorum.has_stake(sender, epoch).await } } diff --git a/crates/task-impls/src/transactions.rs b/crates/task-impls/src/transactions.rs index ce01590734..8429fffa53 100644 --- a/crates/task-impls/src/transactions.rs +++ b/crates/task-impls/src/transactions.rs @@ -213,9 +213,9 @@ impl, V: Versions> TransactionTask .number_of_empty_blocks_proposed .add(1); - let membership_total_nodes = self.membership.total_nodes(self.cur_epoch); + let membership_total_nodes = self.membership.total_nodes(self.cur_epoch).await; let Some(null_fee) = null_block::builder_fee::( - self.membership.total_nodes(self.cur_epoch), + self.membership.total_nodes(self.cur_epoch).await, version, *block_view, ) else { @@ -356,15 +356,15 @@ impl, V: Versions> TransactionTask } /// Produce a null block - pub fn null_block( + pub async fn null_block( &self, block_view: TYPES::View, block_epoch: TYPES::Epoch, version: Version, ) -> Option> { - let membership_total_nodes = self.membership.total_nodes(self.cur_epoch); + let membership_total_nodes = self.membership.total_nodes(self.cur_epoch).await; let Some(null_fee) = null_block::builder_fee::( - self.membership.total_nodes(self.cur_epoch), + self.membership.total_nodes(self.cur_epoch).await, version, *block_view, ) else { @@ -418,7 +418,7 @@ impl, V: Versions> TransactionTask e ); - let null_block = self.null_block(block_view, block_epoch, version)?; + let null_block = self.null_block(block_view, block_epoch, version).await?; // Increment the metric for number of empty blocks proposed self.consensus @@ -492,7 +492,7 @@ impl, V: Versions> TransactionTask self.cur_view = view; self.cur_epoch = *epoch; - if self.membership.leader(view, *epoch)? == self.public_key { + if self.membership.leader(view, *epoch).await? == self.public_key { self.handle_view_change(&event_stream, view, *epoch).await; return Ok(()); } @@ -757,7 +757,7 @@ impl, V: Versions> TransactionTask // builder for VID computation. let (block, header_input) = if version >= V::Epochs::VERSION { futures::join! { - client.claim_block_with_num_nodes(block_info.block_hash.clone(), view_number.u64(), self.public_key.clone(), &request_signature, self.membership.total_nodes(self.cur_epoch)) , + client.claim_block_with_num_nodes(block_info.block_hash.clone(), view_number.u64(), self.public_key.clone(), &request_signature, self.membership.total_nodes(self.cur_epoch).await), client.claim_block_header_input(block_info.block_hash.clone(), view_number.u64(), self.public_key.clone(), &request_signature) } } else { diff --git a/crates/task-impls/src/upgrade.rs b/crates/task-impls/src/upgrade.rs index a8dec2e3f3..2b8f2afa8d 100644 --- a/crates/task-impls/src/upgrade.rs +++ b/crates/task-impls/src/upgrade.rs @@ -179,7 +179,7 @@ impl UpgradeTaskState { ); // We then validate that the proposal was issued by the leader for the view. - let view_leader_key = self.quorum_membership.leader(view, self.cur_epoch)?; + let view_leader_key = self.quorum_membership.leader(view, self.cur_epoch).await?; ensure!( view_leader_key == *sender, info!( @@ -223,11 +223,14 @@ impl UpgradeTaskState { { let view = vote.view_number(); ensure!( - self.quorum_membership.leader(view, self.cur_epoch)? == self.public_key, + self.quorum_membership.leader(view, self.cur_epoch).await? + == self.public_key, debug!( "We are not the leader for view {} are we leader for next view? {}", *view, - self.quorum_membership.leader(view + 1, self.cur_epoch)? + self.quorum_membership + .leader(view + 1, self.cur_epoch) + .await? == self.public_key ) ); @@ -270,10 +273,14 @@ impl UpgradeTaskState { && time >= self.start_proposing_time && time < self.stop_proposing_time && !self.upgraded().await - && self.quorum_membership.leader( - TYPES::View::new(view + UPGRADE_PROPOSE_OFFSET), - self.cur_epoch, - )? == self.public_key + && self + .quorum_membership + .leader( + TYPES::View::new(view + UPGRADE_PROPOSE_OFFSET), + self.cur_epoch, + ) + .await? + == self.public_key { let upgrade_proposal_data = UpgradeProposalData { old_version: V::Base::VERSION, diff --git a/crates/task-impls/src/vid.rs b/crates/task-impls/src/vid.rs index 07dd5d1b72..5746e57ceb 100644 --- a/crates/task-impls/src/vid.rs +++ b/crates/task-impls/src/vid.rs @@ -78,7 +78,7 @@ impl> VidTaskState { ::BlockPayload::from_bytes(encoded_transactions, metadata); let builder_commitment = payload.builder_commitment(metadata); let epoch = self.cur_epoch; - if self.membership.leader(*view_number, epoch).ok()? != self.public_key { + if self.membership.leader(*view_number, epoch).await.ok()? != self.public_key { tracing::debug!( "We are not the leader in the current epoch. Do not send the VID dispersal." ); diff --git a/crates/task-impls/src/view_sync.rs b/crates/task-impls/src/view_sync.rs index 98b9fd1876..b364b90153 100644 --- a/crates/task-impls/src/view_sync.rs +++ b/crates/task-impls/src/view_sync.rs @@ -310,7 +310,10 @@ impl ViewSyncTaskState { // We do not have a relay task already running, so start one ensure!( - self.membership.leader(vote_view + relay, self.cur_epoch)? == self.public_key, + self.membership + .leader(vote_view + relay, self.cur_epoch) + .await? + == self.public_key, "View sync vote sent to wrong leader" ); @@ -355,7 +358,10 @@ impl ViewSyncTaskState { // We do not have a relay task already running, so start one ensure!( - self.membership.leader(vote_view + relay, self.cur_epoch)? == self.public_key, + self.membership + .leader(vote_view + relay, self.cur_epoch) + .await? + == self.public_key, debug!("View sync vote sent to wrong leader") ); @@ -400,7 +406,10 @@ impl ViewSyncTaskState { // We do not have a relay task already running, so start one ensure!( - self.membership.leader(vote_view + relay, self.cur_epoch)? == self.public_key, + self.membership + .leader(vote_view + relay, self.cur_epoch) + .await? + == self.public_key, debug!("View sync vote sent to wrong leader") ); @@ -473,7 +482,7 @@ impl ViewSyncTaskState { ); self.num_timeouts_tracked += 1; - let leader = self.membership.leader(view_number, self.cur_epoch)?; + let leader = self.membership.leader(view_number, self.cur_epoch).await?; tracing::warn!( %leader, leader_mnemonic = hotshot_types::utils::mnemonic(&leader), @@ -534,8 +543,8 @@ impl ViewSyncReplicaTaskState { // If certificate is not valid, return current state if !certificate .is_valid_cert( - self.membership.stake_table(self.cur_epoch), - self.membership.failure_threshold(self.cur_epoch), + self.membership.stake_table(self.cur_epoch).await, + self.membership.failure_threshold(self.cur_epoch).await, &self.upgrade_lock, ) .await @@ -618,8 +627,8 @@ impl ViewSyncReplicaTaskState { // If certificate is not valid, return current state if !certificate .is_valid_cert( - self.membership.stake_table(self.cur_epoch), - self.membership.success_threshold(self.cur_epoch), + self.membership.stake_table(self.cur_epoch).await, + self.membership.success_threshold(self.cur_epoch).await, &self.upgrade_lock, ) .await @@ -713,8 +722,8 @@ impl ViewSyncReplicaTaskState { // If certificate is not valid, return current state if !certificate .is_valid_cert( - self.membership.stake_table(self.cur_epoch), - self.membership.success_threshold(self.cur_epoch), + self.membership.stake_table(self.cur_epoch).await, + self.membership.success_threshold(self.cur_epoch).await, &self.upgrade_lock, ) .await diff --git a/crates/task-impls/src/vote_collection.rs b/crates/task-impls/src/vote_collection.rs index 182a40a8c3..a24f17f3ed 100644 --- a/crates/task-impls/src/vote_collection.rs +++ b/crates/task-impls/src/vote_collection.rs @@ -83,7 +83,7 @@ pub trait AggregatableVote< &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, - ) -> Result; + ) -> impl std::future::Future> + Send; /// return the Hotshot event for the completion of this CERT fn make_cert_event(certificate: CERT, key: &TYPES::SignatureKey) -> HotShotEvent; @@ -109,7 +109,7 @@ impl< ) -> Result> { if self.check_if_leader { ensure!( - vote.leader(&self.membership, self.epoch)? == self.public_key, + vote.leader(&self.membership, self.epoch).await? == self.public_key, info!("Received vote for a view in which we were not the leader.") ); } @@ -340,12 +340,12 @@ type ViewSyncFinalizeVoteState = VoteCollectionTaskState< impl AggregatableVote, QuorumCertificate> for QuorumVote { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.view_number() + 1, epoch) + membership.leader(self.view_number() + 1, epoch).await } fn make_cert_event( certificate: QuorumCertificate, @@ -358,12 +358,12 @@ impl AggregatableVote, QuorumCertifica impl AggregatableVote, QuorumCertificate2> for QuorumVote2 { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.view_number() + 1, epoch) + membership.leader(self.view_number() + 1, epoch).await } fn make_cert_event( certificate: QuorumCertificate2, @@ -376,12 +376,12 @@ impl AggregatableVote, QuorumCertific impl AggregatableVote, UpgradeCertificate> for UpgradeVote { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.view_number(), epoch) + membership.leader(self.view_number(), epoch).await } fn make_cert_event( certificate: UpgradeCertificate, @@ -394,12 +394,12 @@ impl AggregatableVote, UpgradeCertifi impl AggregatableVote, DaCertificate2> for DaVote2 { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.view_number(), epoch) + membership.leader(self.view_number(), epoch).await } fn make_cert_event( certificate: DaCertificate2, @@ -412,12 +412,12 @@ impl AggregatableVote, DaCertificate2 AggregatableVote, TimeoutCertificate2> for TimeoutVote2 { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.view_number() + 1, epoch) + membership.leader(self.view_number() + 1, epoch).await } fn make_cert_event( certificate: TimeoutCertificate2, @@ -431,12 +431,14 @@ impl AggregatableVote, ViewSyncCommitCertificate2> for ViewSyncCommitVote2 { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.date().round + self.date().relay, epoch) + membership + .leader(self.date().round + self.date().relay, epoch) + .await } fn make_cert_event( certificate: ViewSyncCommitCertificate2, @@ -450,12 +452,14 @@ impl AggregatableVote, ViewSyncPreCommitCertificate2> for ViewSyncPreCommitVote2 { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.date().round + self.date().relay, epoch) + membership + .leader(self.date().round + self.date().relay, epoch) + .await } fn make_cert_event( certificate: ViewSyncPreCommitCertificate2, @@ -469,12 +473,14 @@ impl AggregatableVote, ViewSyncFinalizeCertificate2> for ViewSyncFinalizeVote2 { - fn leader( + async fn leader( &self, membership: &TYPES::Membership, epoch: TYPES::Epoch, ) -> Result { - membership.leader(self.date().round + self.date().relay, epoch) + membership + .leader(self.date().round + self.date().relay, epoch) + .await } fn make_cert_event( certificate: ViewSyncFinalizeCertificate2, diff --git a/crates/testing/src/helpers.rs b/crates/testing/src/helpers.rs index 2fa1fd6eec..bbb2d12609 100644 --- a/crates/testing/src/helpers.rs +++ b/crates/testing/src/helpers.rs @@ -212,11 +212,11 @@ pub async fn build_assembled_sig< epoch: TYPES::Epoch, upgrade_lock: &UpgradeLock, ) -> ::QcType { - let stake_table = CERT::stake_table(membership, epoch); + let stake_table = CERT::stake_table(membership, epoch).await; let real_qc_pp: ::QcParams = ::public_parameter( stake_table.clone(), - U256::from(CERT::threshold(membership, epoch)), + U256::from(CERT::threshold(membership, epoch).await), ); let total_nodes = stake_table.len(); let signers = bitvec![1; total_nodes]; @@ -265,32 +265,33 @@ pub fn key_pair_for_id( /// # Panics /// if unable to create a [`VidSchemeType`] #[must_use] -pub fn vid_scheme_from_view_number( +pub async fn vid_scheme_from_view_number( membership: &TYPES::Membership, view_number: TYPES::View, epoch_number: TYPES::Epoch, ) -> VidSchemeType { let num_storage_nodes = membership .committee_members(view_number, epoch_number) + .await .len(); vid_scheme(num_storage_nodes) } -pub fn vid_payload_commitment( +pub async fn vid_payload_commitment( quorum_membership: &::Membership, view_number: TYPES::View, epoch_number: TYPES::Epoch, transactions: Vec, ) -> VidCommitment { let mut vid = - vid_scheme_from_view_number::(quorum_membership, view_number, epoch_number); + vid_scheme_from_view_number::(quorum_membership, view_number, epoch_number).await; let encoded_transactions = TestTransaction::encode(&transactions); let vid_disperse = vid.disperse(&encoded_transactions).unwrap(); vid_disperse.commit } -pub fn da_payload_commitment( +pub async fn da_payload_commitment( quorum_membership: &::Membership, transactions: Vec, epoch_number: TYPES::Epoch, @@ -299,24 +300,24 @@ pub fn da_payload_commitment( vid_commitment( &encoded_transactions, - quorum_membership.total_nodes(epoch_number), + quorum_membership.total_nodes(epoch_number).await, ) } -pub fn build_payload_commitment( +pub async fn build_payload_commitment( membership: &::Membership, view: TYPES::View, epoch: TYPES::Epoch, ) -> ::Commit { // Make some empty encoded transactions, we just care about having a commitment handy for the // later calls. We need the VID commitment to be able to propose later. - let mut vid = vid_scheme_from_view_number::(membership, view, epoch); + let mut vid = vid_scheme_from_view_number::(membership, view, epoch).await; let encoded_transactions = Vec::new(); vid.commit_only(&encoded_transactions).unwrap() } /// TODO: -pub fn build_vid_proposal( +pub async fn build_vid_proposal( quorum_membership: &::Membership, view_number: TYPES::View, epoch_number: TYPES::Epoch, @@ -324,7 +325,7 @@ pub fn build_vid_proposal( private_key: &::PrivateKey, ) -> VidProposal { let mut vid = - vid_scheme_from_view_number::(quorum_membership, view_number, epoch_number); + vid_scheme_from_view_number::(quorum_membership, view_number, epoch_number).await; let encoded_transactions = TestTransaction::encode(&transactions); let vid_disperse = VidDisperse::from_membership( @@ -332,7 +333,8 @@ pub fn build_vid_proposal( vid.disperse(&encoded_transactions).unwrap(), quorum_membership, epoch_number, - ); + ) + .await; let signature = TYPES::SignatureKey::sign(private_key, vid_disperse.payload_commitment.as_ref()) @@ -368,8 +370,10 @@ pub async fn build_da_certificate( ) -> DaCertificate2 { let encoded_transactions = TestTransaction::encode(&transactions); - let da_payload_commitment = - vid_commitment(&encoded_transactions, membership.total_nodes(epoch_number)); + let da_payload_commitment = vid_commitment( + &encoded_transactions, + membership.total_nodes(epoch_number).await, + ); let da_data = DaData2 { payload_commit: da_payload_commitment, diff --git a/crates/testing/src/view_generator.rs b/crates/testing/src/view_generator.rs index d5c1cb7ca5..f640e6c547 100644 --- a/crates/testing/src/view_generator.rs +++ b/crates/testing/src/view_generator.rs @@ -98,7 +98,8 @@ impl TestView { let leader_public_key = public_key; let payload_commitment = - da_payload_commitment::(membership, transactions.clone(), genesis_epoch); + da_payload_commitment::(membership, transactions.clone(), genesis_epoch) + .await; let (vid_disperse, vid_proposal) = build_vid_proposal( membership, @@ -106,7 +107,8 @@ impl TestView { genesis_epoch, transactions.clone(), &private_key, - ); + ) + .await; let da_certificate = build_da_certificate( membership, @@ -240,7 +242,8 @@ impl TestView { ); let payload_commitment = - da_payload_commitment::(membership, transactions.clone(), self.epoch_number); + da_payload_commitment::(membership, transactions.clone(), self.epoch_number) + .await; let (vid_disperse, vid_proposal) = build_vid_proposal( membership, @@ -248,7 +251,8 @@ impl TestView { self.epoch_number, transactions.clone(), &private_key, - ); + ) + .await; let da_certificate = build_da_certificate::( membership, diff --git a/crates/testing/tests/tests_1/da_task.rs b/crates/testing/tests/tests_1/da_task.rs index c7af796395..a068616736 100644 --- a/crates/testing/tests/tests_1/da_task.rs +++ b/crates/testing/tests/tests_1/da_task.rs @@ -48,7 +48,11 @@ async fn test_da_task() { let encoded_transactions = Arc::from(TestTransaction::encode(&transactions)); let (payload_commit, precompute) = precompute_vid_commitment( &encoded_transactions, - handle.hotshot.memberships.total_nodes(EpochNumber::new(0)), + handle + .hotshot + .memberships + .total_nodes(EpochNumber::new(0)) + .await, ); let mut generator = TestViewGenerator::generate(membership.clone()); @@ -107,7 +111,7 @@ async fn test_da_task() { ViewNumber::new(2), EpochNumber::new(0), vec1::vec1![null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(0)), + membership.total_nodes(EpochNumber::new(0)).await, ::Base::VERSION, *ViewNumber::new(2), ) @@ -156,7 +160,11 @@ async fn test_da_task_storage_failure() { let encoded_transactions = Arc::from(TestTransaction::encode(&transactions)); let (payload_commit, precompute) = precompute_vid_commitment( &encoded_transactions, - handle.hotshot.memberships.total_nodes(EpochNumber::new(0)), + handle + .hotshot + .memberships + .total_nodes(EpochNumber::new(0)) + .await, ); let mut generator = TestViewGenerator::generate(membership.clone()); @@ -215,7 +223,7 @@ async fn test_da_task_storage_failure() { ViewNumber::new(2), EpochNumber::new(0), vec1::vec1![null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(0)), + membership.total_nodes(EpochNumber::new(0)).await, ::Base::VERSION, *ViewNumber::new(2), ) diff --git a/crates/testing/tests/tests_1/message.rs b/crates/testing/tests/tests_1/message.rs index e19cce630b..0199e8629c 100644 --- a/crates/testing/tests/tests_1/message.rs +++ b/crates/testing/tests/tests_1/message.rs @@ -105,8 +105,8 @@ async fn test_certificate2_validity() { assert!( qc.is_valid_cert( - membership.stake_table(EpochNumber::new(0)), - membership.success_threshold(EpochNumber::new(0)), + membership.stake_table(EpochNumber::new(0)).await, + membership.success_threshold(EpochNumber::new(0)).await, &handle.hotshot.upgrade_lock ) .await @@ -114,8 +114,8 @@ async fn test_certificate2_validity() { assert!( qc2.is_valid_cert( - membership.stake_table(EpochNumber::new(0)), - membership.success_threshold(EpochNumber::new(0)), + membership.stake_table(EpochNumber::new(0)).await, + membership.success_threshold(EpochNumber::new(0)).await, &handle.hotshot.upgrade_lock ) .await diff --git a/crates/testing/tests/tests_1/quorum_proposal_task.rs b/crates/testing/tests/tests_1/quorum_proposal_task.rs index 0935aef8f8..4652fb3b97 100644 --- a/crates/testing/tests/tests_1/quorum_proposal_task.rs +++ b/crates/testing/tests/tests_1/quorum_proposal_task.rs @@ -57,7 +57,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_1() { &membership, ViewNumber::new(node_id), EpochNumber::new(1), - ); + ) + .await; let mut generator = TestViewGenerator::generate(membership.clone()); @@ -90,7 +91,7 @@ async fn test_quorum_proposal_task_quorum_proposal_view_1() { let genesis_cert = proposals[0].data.justify_qc.clone(); let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize()); let builder_fee = null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(1)), + membership.total_nodes(EpochNumber::new(1)).await, ::Base::VERSION, *ViewNumber::new(1), ) @@ -182,7 +183,7 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() { let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize()); let builder_fee = null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(1)), + membership.total_nodes(EpochNumber::new(1)).await, ::Base::VERSION, *ViewNumber::new(1), ) @@ -196,7 +197,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() { &membership, ViewNumber::new(1), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), TestMetadata { num_transactions: 0 @@ -215,7 +217,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() { &membership, ViewNumber::new(2), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[0].data.block_header.metadata, ViewNumber::new(2), @@ -232,7 +235,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() { &membership, ViewNumber::new(3), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[1].data.block_header.metadata, ViewNumber::new(3), @@ -249,7 +253,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() { &membership, ViewNumber::new(4), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[2].data.block_header.metadata, ViewNumber::new(4), @@ -266,7 +271,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() { &membership, ViewNumber::new(5), EpochNumber::new(1) - ), + ) + .await, builder_commitment, proposals[3].data.block_header.metadata, ViewNumber::new(5), @@ -314,7 +320,8 @@ async fn test_quorum_proposal_task_qc_timeout() { &membership, ViewNumber::new(node_id), EpochNumber::new(1), - ); + ) + .await; let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize()); let mut generator = TestViewGenerator::generate(membership.clone()); @@ -360,7 +367,7 @@ async fn test_quorum_proposal_task_qc_timeout() { }, ViewNumber::new(3), vec1![null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(1)), + membership.total_nodes(EpochNumber::new(1)).await, ::Base::VERSION, *ViewNumber::new(3), ) @@ -403,7 +410,8 @@ async fn test_quorum_proposal_task_view_sync() { &membership, ViewNumber::new(node_id), EpochNumber::new(1), - ); + ) + .await; let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize()); let mut generator = TestViewGenerator::generate(membership.clone()); @@ -451,7 +459,7 @@ async fn test_quorum_proposal_task_view_sync() { }, ViewNumber::new(2), vec1![null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(1)), + membership.total_nodes(EpochNumber::new(1)).await, ::Base::VERSION, *ViewNumber::new(2), ) @@ -518,7 +526,7 @@ async fn test_quorum_proposal_task_liveness_check() { let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize()); let builder_fee = null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(1)), + membership.total_nodes(EpochNumber::new(1)).await, ::Base::VERSION, *ViewNumber::new(1), ) @@ -536,7 +544,8 @@ async fn test_quorum_proposal_task_liveness_check() { &membership, ViewNumber::new(1), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), TestMetadata { num_transactions: 0 @@ -555,7 +564,8 @@ async fn test_quorum_proposal_task_liveness_check() { &membership, ViewNumber::new(2), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[0].data.block_header.metadata, ViewNumber::new(2), @@ -572,7 +582,8 @@ async fn test_quorum_proposal_task_liveness_check() { &membership, ViewNumber::new(3), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[1].data.block_header.metadata, ViewNumber::new(3), @@ -589,7 +600,8 @@ async fn test_quorum_proposal_task_liveness_check() { &membership, ViewNumber::new(4), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[2].data.block_header.metadata, ViewNumber::new(4), @@ -606,7 +618,8 @@ async fn test_quorum_proposal_task_liveness_check() { &membership, ViewNumber::new(5), EpochNumber::new(1) - ), + ) + .await, builder_commitment, proposals[3].data.block_header.metadata, ViewNumber::new(5), diff --git a/crates/testing/tests/tests_1/transaction_task.rs b/crates/testing/tests/tests_1/transaction_task.rs index e4ed70be64..747e40e29d 100644 --- a/crates/testing/tests/tests_1/transaction_task.rs +++ b/crates/testing/tests/tests_1/transaction_task.rs @@ -42,7 +42,11 @@ async fn test_transaction_task_leader_two_views_in_a_row() { let (_, precompute_data) = precompute_vid_commitment( &[], - handle.hotshot.memberships.total_nodes(EpochNumber::new(0)), + handle + .hotshot + .memberships + .total_nodes(EpochNumber::new(0)) + .await, ); // current view @@ -55,7 +59,11 @@ async fn test_transaction_task_leader_two_views_in_a_row() { EpochNumber::new(1), vec1::vec1![ null_block::builder_fee::( - handle.hotshot.memberships.total_nodes(EpochNumber::new(0)), + handle + .hotshot + .memberships + .total_nodes(EpochNumber::new(0)) + .await, ::Base::VERSION, *ViewNumber::new(4), ) diff --git a/crates/testing/tests/tests_1/upgrade_task_with_proposal.rs b/crates/testing/tests/tests_1/upgrade_task_with_proposal.rs index 44833d7727..4de636ba0b 100644 --- a/crates/testing/tests/tests_1/upgrade_task_with_proposal.rs +++ b/crates/testing/tests/tests_1/upgrade_task_with_proposal.rs @@ -126,7 +126,7 @@ async fn test_upgrade_task_with_proposal() { let genesis_cert = proposals[0].data.justify_qc.clone(); let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize()); let builder_fee = null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(1)), + membership.total_nodes(EpochNumber::new(1)).await, ::Base::VERSION, *ViewNumber::new(1), ) @@ -156,7 +156,8 @@ async fn test_upgrade_task_with_proposal() { &membership, ViewNumber::new(1), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), TestMetadata { num_transactions: 0 @@ -175,7 +176,8 @@ async fn test_upgrade_task_with_proposal() { &membership, ViewNumber::new(2), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[0].data.block_header.metadata, ViewNumber::new(2), @@ -193,7 +195,8 @@ async fn test_upgrade_task_with_proposal() { &membership, ViewNumber::new(3), EpochNumber::new(1) - ), + ) + .await, builder_commitment.clone(), proposals[1].data.block_header.metadata, ViewNumber::new(3), diff --git a/crates/testing/tests/tests_1/vid_task.rs b/crates/testing/tests/tests_1/vid_task.rs index 3cd850183c..25e9e4c559 100644 --- a/crates/testing/tests/tests_1/vid_task.rs +++ b/crates/testing/tests/tests_1/vid_task.rs @@ -51,7 +51,8 @@ async fn test_vid_task() { &membership, ViewNumber::new(0), EpochNumber::new(0), - ); + ) + .await; let transactions = vec![TestTransaction::new(vec![0])]; let (payload, metadata) = >::from_transactions( @@ -91,7 +92,8 @@ async fn test_vid_task() { vid_disperse, &membership, EpochNumber::new(0), - ); + ) + .await; let vid_proposal = Proposal { data: vid_disperse.clone(), @@ -110,7 +112,7 @@ async fn test_vid_task() { ViewNumber::new(2), EpochNumber::new(0), vec1::vec1![null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(0)), + membership.total_nodes(EpochNumber::new(0)).await, ::Base::VERSION, *ViewNumber::new(2), ) @@ -132,7 +134,7 @@ async fn test_vid_task() { }, ViewNumber::new(2), vec1![null_block::builder_fee::( - membership.total_nodes(EpochNumber::new(0)), + membership.total_nodes(EpochNumber::new(0)).await, ::Base::VERSION, *ViewNumber::new(2), ) diff --git a/crates/testing/tests/tests_3/byzantine_tests.rs b/crates/testing/tests/tests_3/byzantine_tests.rs index 0ab5f68d19..ea376ace6b 100644 --- a/crates/testing/tests/tests_3/byzantine_tests.rs +++ b/crates/testing/tests/tests_3/byzantine_tests.rs @@ -171,12 +171,12 @@ cross_tests!( Ignore: false, Metadata: { let nodes_count: usize = 10; - let behaviour = Rc::new(move |node_id| { + let behaviour = Rc::new( move |node_id| { let dishonest_voting = DishonestVoting { view_increment: nodes_count as u64, - modifier: Arc::new(move |_pk, message_kind, transmit_type: &mut TransmitType, membership: &::Membership| { + modifier: Arc::new( move |_pk, message_kind, transmit_type: &mut TransmitType, membership: &::Membership| { if let MessageKind::Consensus(SequencingMessage::General(GeneralConsensusMessage::Vote(vote))) = message_kind { - *transmit_type = TransmitType::Direct(membership.leader(vote.view_number() + 1 - nodes_count as u64, EpochNumber::new(0)).unwrap()); + *transmit_type = TransmitType::Direct(tokio::runtime::Runtime::new().unwrap().block_on(membership.leader(vote.view_number() + 1 - nodes_count as u64, EpochNumber::new(0))).unwrap()); } else { {} } diff --git a/crates/types/src/data.rs b/crates/types/src/data.rs index 73acf9d6f0..d5039b2a48 100644 --- a/crates/types/src/data.rs +++ b/crates/types/src/data.rs @@ -219,7 +219,7 @@ impl VidDisperse { /// Create VID dispersal from a specified membership for a given epoch. /// Uses the specified function to calculate share dispersal /// Allows for more complex stake table functionality - pub fn from_membership( + pub async fn from_membership( view_number: TYPES::View, mut vid_disperse: JfVidDisperse, membership: &TYPES::Membership, @@ -227,6 +227,7 @@ impl VidDisperse { ) -> Self { let shares = membership .committee_members(view_number, epoch) + .await .iter() .map(|node| (node.clone(), vid_disperse.shares.remove(0))) .collect(); @@ -253,7 +254,7 @@ impl VidDisperse { epoch: TYPES::Epoch, precompute_data: Option, ) -> Self { - let num_nodes = membership.total_nodes(epoch); + let num_nodes = membership.total_nodes(epoch).await; let vid_disperse = spawn_blocking(move || { precompute_data @@ -266,7 +267,7 @@ impl VidDisperse { // Unwrap here will just propagate any panic from the spawned task, it's not a new place we can panic. let vid_disperse = vid_disperse.unwrap(); - Self::from_membership(view, vid_disperse, membership.as_ref(), epoch) + Self::from_membership(view, vid_disperse, membership.as_ref(), epoch).await } } diff --git a/crates/types/src/message.rs b/crates/types/src/message.rs index 0f36bae2de..0b5540b8b6 100644 --- a/crates/types/src/message.rs +++ b/crates/types/src/message.rs @@ -441,7 +441,9 @@ where self.data.block_header.block_number(), epoch_height, )); - let view_leader_key = quorum_membership.leader(view_number, proposal_epoch)?; + let view_leader_key = quorum_membership + .leader(view_number, proposal_epoch) + .await?; let proposed_leaf = Leaf::from_quorum_proposal(&self.data); ensure!( @@ -463,7 +465,7 @@ where /// Checks that the signature of the quorum proposal is valid. /// # Errors /// Returns an error when the proposal signature is invalid. - pub fn validate_signature( + pub async fn validate_signature( &self, quorum_membership: &TYPES::Membership, epoch_height: u64, @@ -473,7 +475,9 @@ where self.data.block_header.block_number(), epoch_height, )); - let view_leader_key = quorum_membership.leader(view_number, proposal_epoch)?; + let view_leader_key = quorum_membership + .leader(view_number, proposal_epoch) + .await?; let proposed_leaf = Leaf2::from_quorum_proposal(&self.data); ensure!( diff --git a/crates/types/src/simple_certificate.rs b/crates/types/src/simple_certificate.rs index 91d5f00d7a..e2bc046a54 100644 --- a/crates/types/src/simple_certificate.rs +++ b/crates/types/src/simple_certificate.rs @@ -43,7 +43,7 @@ pub trait Threshold { fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, - ) -> u64; + ) -> impl futures::Future + Send; } /// Defines a threshold which is 2f + 1 (Amount needed for Quorum) @@ -51,11 +51,11 @@ pub trait Threshold { pub struct SuccessThreshold {} impl Threshold for SuccessThreshold { - fn threshold>( + async fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, ) -> u64 { - membership.success_threshold(epoch).into() + membership.success_threshold(epoch).await.into() } } @@ -64,11 +64,11 @@ impl Threshold for SuccessThreshold { pub struct OneHonestThreshold {} impl Threshold for OneHonestThreshold { - fn threshold>( + async fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, ) -> u64 { - membership.failure_threshold(epoch).into() + membership.failure_threshold(epoch).await.into() } } @@ -77,11 +77,11 @@ impl Threshold for OneHonestThreshold { pub struct UpgradeThreshold {} impl Threshold for UpgradeThreshold { - fn threshold>( + async fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, ) -> u64 { - membership.upgrade_threshold(epoch).into() + membership.upgrade_threshold(epoch).await.into() } } @@ -191,7 +191,8 @@ impl> Certificate membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch, - ) -> Option<::StakeTableEntry> { + ) -> impl futures::Future::StakeTableEntry>> + + Send { membership.da_stake(pub_key, epoch) } @@ -199,21 +200,22 @@ impl> Certificate fn stake_table>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> Vec<::StakeTableEntry> { + ) -> impl futures::Future::StakeTableEntry>> + Send + { membership.da_stake_table(epoch) } /// Proxy's to `Membership.da_total_nodes` fn total_nodes>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> usize { + ) -> impl futures::Future + Send { membership.da_total_nodes(epoch) } - fn threshold>( + async fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, ) -> u64 { - membership.da_success_threshold(epoch).into() + membership.da_success_threshold(epoch).await.into() } fn data(&self) -> &Self::Voteable { &self.data @@ -275,33 +277,34 @@ impl> Certificate>( + async fn stake_table_entry>( membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch, ) -> Option<::StakeTableEntry> { - membership.da_stake(pub_key, epoch) + membership.da_stake(pub_key, epoch).await } /// Proxy's to `Membership.da_stake_table` fn stake_table>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> Vec<::StakeTableEntry> { + ) -> impl futures::Future::StakeTableEntry>> + Send + { membership.da_stake_table(epoch) } /// Proxy's to `Membership.da_total_nodes` - fn total_nodes>( + async fn total_nodes>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, ) -> usize { - membership.da_total_nodes(epoch) + membership.da_total_nodes(epoch).await } - fn threshold>( + async fn threshold>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, ) -> u64 { - membership.da_success_threshold(epoch).into() + membership.da_success_threshold(epoch).await.into() } fn data(&self) -> &Self::Voteable { &self.data @@ -365,25 +368,27 @@ impl< self.signatures.as_ref().unwrap(), ) } - fn threshold>( + async fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, ) -> u64 { - THRESHOLD::threshold(membership, epoch) + THRESHOLD::threshold(membership, epoch).await } fn stake_table_entry>( membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch, - ) -> Option<::StakeTableEntry> { + ) -> impl futures::Future::StakeTableEntry>> + + Send { membership.stake(pub_key, epoch) } fn stake_table>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> Vec<::StakeTableEntry> { + ) -> impl futures::Future::StakeTableEntry>> + Send + { membership.stake_table(epoch) } @@ -391,7 +396,7 @@ impl< fn total_nodes>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> usize { + ) -> impl futures::Future + Send { membership.total_nodes(epoch) } @@ -458,8 +463,8 @@ impl UpgradeCertificate { if let Some(ref cert) = upgrade_certificate { ensure!( cert.is_valid_cert( - quorum_membership.stake_table(epoch), - quorum_membership.upgrade_threshold(epoch), + quorum_membership.stake_table(epoch).await, + quorum_membership.upgrade_threshold(epoch).await, upgrade_lock ) .await, diff --git a/crates/types/src/traits/election.rs b/crates/types/src/traits/election.rs index 5b72ea4f84..7f381d1af2 100644 --- a/crates/types/src/traits/election.rs +++ b/crates/types/src/traits/election.rs @@ -29,34 +29,34 @@ pub trait Membership: Clone + Debug + Send + Sync { fn stake_table( &self, epoch: TYPES::Epoch, - ) -> Vec<::StakeTableEntry>; + ) -> impl futures::Future::StakeTableEntry>> + Send; /// Get all participants in the committee (including their stake) for a specific epoch fn da_stake_table( &self, epoch: TYPES::Epoch, - ) -> Vec<::StakeTableEntry>; + ) -> impl futures::Future::StakeTableEntry>> + Send; /// Get all participants in the committee for a specific view for a specific epoch fn committee_members( &self, view_number: TYPES::View, epoch: TYPES::Epoch, - ) -> BTreeSet; + ) -> impl futures::Future> + Send; /// Get all participants in the committee for a specific view for a specific epoch fn da_committee_members( &self, view_number: TYPES::View, epoch: TYPES::Epoch, - ) -> BTreeSet; + ) -> impl futures::Future> + Send; /// Get all leaders in the committee for a specific view for a specific epoch fn committee_leaders( &self, view_number: TYPES::View, epoch: TYPES::Epoch, - ) -> BTreeSet; + ) -> impl futures::Future> + Send; /// Get the stake table entry for a public key, returns `None` if the /// key is not in the table for a specific epoch @@ -64,7 +64,8 @@ pub trait Membership: Clone + Debug + Send + Sync { &self, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch, - ) -> Option<::StakeTableEntry>; + ) -> impl futures::Future::StakeTableEntry>> + + Send; /// Get the DA stake table entry for a public key, returns `None` if the /// key is not in the table for a specific epoch @@ -72,13 +73,22 @@ pub trait Membership: Clone + Debug + Send + Sync { &self, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch, - ) -> Option<::StakeTableEntry>; + ) -> impl futures::Future::StakeTableEntry>> + + Send; /// See if a node has stake in the committee in a specific epoch - fn has_stake(&self, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch) -> bool; + fn has_stake( + &self, + pub_key: &TYPES::SignatureKey, + epoch: TYPES::Epoch, + ) -> impl futures::Future + Send; /// See if a node has stake in the committee in a specific epoch - fn has_da_stake(&self, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch) -> bool; + fn has_da_stake( + &self, + pub_key: &TYPES::SignatureKey, + epoch: TYPES::Epoch, + ) -> impl futures::Future + Send; /// The leader of the committee for view `view_number` in `epoch`. /// @@ -87,12 +97,18 @@ pub trait Membership: Clone + Debug + Send + Sync { /// /// # Errors /// Returns an error if the leader cannot be calculated. - fn leader(&self, view: TYPES::View, epoch: TYPES::Epoch) -> Result { + fn leader( + &self, + view: TYPES::View, + epoch: TYPES::Epoch, + ) -> impl futures::Future> + Send { use utils::anytrace::*; - self.lookup_leader(view, epoch).wrap().context(info!( - "Failed to get leader for view {view} in epoch {epoch}" - )) + async move { + self.lookup_leader(view, epoch).await.wrap().context(info!( + "Failed to get leader for view {view} in epoch {epoch}" + )) + } } /// The leader of the committee for view `view_number` in `epoch`. @@ -106,23 +122,35 @@ pub trait Membership: Clone + Debug + Send + Sync { &self, view: TYPES::View, epoch: TYPES::Epoch, - ) -> std::result::Result; + ) -> impl futures::Future> + Send; /// Returns the number of total nodes in the committee in an epoch `epoch` - fn total_nodes(&self, epoch: TYPES::Epoch) -> usize; + fn total_nodes(&self, epoch: TYPES::Epoch) -> impl futures::Future + Send; /// Returns the number of total DA nodes in the committee in an epoch `epoch` - fn da_total_nodes(&self, epoch: TYPES::Epoch) -> usize; + fn da_total_nodes(&self, epoch: TYPES::Epoch) -> impl futures::Future + Send; /// Returns the threshold for a specific `Membership` implementation - fn success_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64; + fn success_threshold( + &self, + epoch: TYPES::Epoch, + ) -> impl futures::Future + Send; /// Returns the DA threshold for a specific `Membership` implementation - fn da_success_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64; + fn da_success_threshold( + &self, + epoch: TYPES::Epoch, + ) -> impl futures::Future + Send; /// Returns the threshold for a specific `Membership` implementation - fn failure_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64; + fn failure_threshold( + &self, + epoch: TYPES::Epoch, + ) -> impl futures::Future + Send; /// Returns the threshold required to upgrade the network protocol - fn upgrade_threshold(&self, epoch: TYPES::Epoch) -> NonZeroU64; + fn upgrade_threshold( + &self, + epoch: TYPES::Epoch, + ) -> impl futures::Future + Send; } diff --git a/crates/types/src/vote.rs b/crates/types/src/vote.rs index e70dbe41a3..6c4d24eb54 100644 --- a/crates/types/src/vote.rs +++ b/crates/types/src/vote.rs @@ -84,26 +84,27 @@ pub trait Certificate: HasViewNumber { fn threshold>( membership: &MEMBERSHIP, epoch: ::Epoch, - ) -> u64; + ) -> impl futures::Future + Send; /// Get Stake Table from Membership implementation. fn stake_table>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> Vec<::StakeTableEntry>; + ) -> impl futures::Future::StakeTableEntry>> + Send; /// Get Total Nodes from Membership implementation. fn total_nodes>( membership: &MEMBERSHIP, epoch: TYPES::Epoch, - ) -> usize; + ) -> impl futures::Future + Send; /// Get `StakeTableEntry` from Membership implementation. fn stake_table_entry>( membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: TYPES::Epoch, - ) -> Option<::StakeTableEntry>; + ) -> impl futures::Future::StakeTableEntry>> + + Send; /// Get the commitment which was voted on fn data(&self) -> &Self::Voteable; @@ -186,10 +187,10 @@ impl< return Either::Left(()); } - let Some(stake_table_entry) = CERT::stake_table_entry(membership, &key, epoch) else { + let Some(stake_table_entry) = CERT::stake_table_entry(membership, &key, epoch).await else { return Either::Left(()); }; - let stake_table = CERT::stake_table(membership, epoch); + let stake_table = CERT::stake_table(membership, epoch).await; let Some(vote_node_id) = stake_table .iter() .position(|x| *x == stake_table_entry.clone()) @@ -209,10 +210,10 @@ impl< if total_vote_map.contains_key(&key) { return Either::Left(()); } - let (signers, sig_list) = self - .signers - .entry(vote_commitment) - .or_insert((bitvec![0; CERT::total_nodes(membership, epoch)], Vec::new())); + let (signers, sig_list) = self.signers.entry(vote_commitment).or_insert(( + bitvec![0; CERT::total_nodes(membership, epoch).await], + Vec::new(), + )); if signers.get(vote_node_id).as_deref() == Some(&true) { error!("Node id is already in signers list"); return Either::Left(()); @@ -223,12 +224,12 @@ impl< *total_stake_casted += stake_table_entry.stake(); total_vote_map.insert(key, (vote.signature(), vote_commitment)); - if *total_stake_casted >= CERT::threshold(membership, epoch).into() { + if *total_stake_casted >= CERT::threshold(membership, epoch).await.into() { // Assemble QC let real_qc_pp: <::SignatureKey as SignatureKey>::QcParams = ::public_parameter( stake_table, - U256::from(CERT::threshold(membership, epoch)), + U256::from(CERT::threshold(membership, epoch).await), ); let real_qc_sig = ::assemble(