From 54dd9fa2ae588d8a0e1adfc713d36dede5d8276d Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Mon, 3 Mar 2025 16:50:58 +0500 Subject: [PATCH] change stake table entry to peer config for EpochCommittes --- Cargo.lock | 2 +- contracts/rust/adapter/src/stake_table.rs | 13 ++ hotshot-query-service/Cargo.toml | 2 +- hotshot-task-impls/src/helpers.rs | 24 +-- .../src/quorum_proposal/handlers.rs | 6 +- hotshot-task-impls/src/quorum_proposal/mod.rs | 5 +- hotshot-task-impls/src/quorum_vote/mod.rs | 3 +- hotshot-task-impls/src/view_sync.rs | 7 +- hotshot-testing/src/helpers.rs | 14 +- hotshot-types/src/lib.rs | 17 +- hotshot-types/src/simple_certificate.rs | 15 +- hotshot-types/src/traits/election.rs | 24 +-- hotshot-types/src/vote.rs | 9 +- .../traits/election/randomized_committee.rs | 109 +++++----- .../election/randomized_committee_members.rs | 101 +++++----- .../src/traits/election/static_committee.rs | 94 ++++----- .../static_committee_leader_two_views.rs | 107 +++++----- .../traits/election/two_static_committees.rs | 147 +++++++------- sequencer-sqlite/Cargo.lock | 2 +- sequencer/src/api.rs | 14 +- sequencer/src/api/data_source.rs | 5 +- sequencer/src/api/endpoints.rs | 1 + types/src/v0/impls/l1.rs | 2 +- types/src/v0/impls/stake_table.rs | 187 +++++++++--------- types/src/v0/v0_3/stake_table.rs | 6 +- 25 files changed, 463 insertions(+), 453 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23b30af2c9..0e70eb9ff2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1598,7 +1598,7 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atomic_store" version = "0.1.3" -source = "git+https://github.com/EspressoSystems/atomicstore.git?tag=0.1.4#64c092596e889b9f376fd4bae8974404c43cd12c" +source = "git+https://github.com/EspressoSystems/atomicstore.git?tag=0.1.5#6d2bbaf0bb3b5cd49e9907e60738bccbd4b8c374" dependencies = [ "ark-serialize 0.4.2", "bincode", diff --git a/contracts/rust/adapter/src/stake_table.rs b/contracts/rust/adapter/src/stake_table.rs index cdd8ecf912..1ea6e98077 100644 --- a/contracts/rust/adapter/src/stake_table.rs +++ b/contracts/rust/adapter/src/stake_table.rs @@ -26,6 +26,7 @@ use hotshot_types::{ signature_key::BLSPubKey, stake_table::StakeTableEntry, traits::signature_key::SignatureKey as _, + PeerConfig, }; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -216,6 +217,18 @@ impl From for StakeTableEntry { } } +impl From for PeerConfig { + fn from(value: NodeInfoJf) -> Self { + Self { + stake_table_entry: StakeTableEntry { + stake_key: value.stake_table_key, + stake_amount: U256::from(1), // dummy stake amount + }, + state_ver_key: value.state_ver_key, + } + } +} + impl From for NodeInfoJf { fn from(value: NodeInfo) -> Self { let NodeInfo { diff --git a/hotshot-query-service/Cargo.toml b/hotshot-query-service/Cargo.toml index 26384ad291..8a8d2a830b 100644 --- a/hotshot-query-service/Cargo.toml +++ b/hotshot-query-service/Cargo.toml @@ -101,7 +101,7 @@ vbs = "0.1" vec1 = "1.12" # Dependencies enabled by feature "file-system-data-source". -atomic_store = { git = "https://github.com/EspressoSystems/atomicstore.git", tag = "0.1.4", optional = true } +atomic_store = { git = "https://github.com/EspressoSystems/atomicstore.git", tag = "0.1.5", optional = true } # Dependencies enabled by feature "sql-data-source". include_dir = { version = "0.7", optional = true } diff --git a/hotshot-task-impls/src/helpers.rs b/hotshot-task-impls/src/helpers.rs index 4b78a68922..cd6aade29b 100644 --- a/hotshot-task-impls/src/helpers.rs +++ b/hotshot-task-impls/src/helpers.rs @@ -29,6 +29,7 @@ use hotshot_types::{ option_epoch_from_block_number, Terminator, View, ViewInner, }, vote::{Certificate, HasViewNumber}, + StakeTableEntries, }; use hotshot_utils::anytrace::*; use std::{ @@ -139,7 +140,7 @@ pub(crate) async fn fetch_proposal( justify_qc .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, upgrade_lock, ) @@ -191,19 +192,6 @@ async fn decide_epoch_root( .await }; - if let Some(write_callback) = write_callback { - let mut membership_writer = membership.write().await; - write_callback(&mut *membership_writer); - } else { - // If we didn't get a write callback out of add_epoch_root, then don't bother locking and calling sync_l1 - return; - } - - let write_callback = { - let membership_reader = membership.read().await; - membership_reader.sync_l1().await - }; - if let Some(write_callback) = write_callback { let mut membership_writer = membership.write().await; write_callback(&mut *membership_writer); @@ -785,7 +773,7 @@ pub(crate) async fn validate_proposal_view_and_certs< timeout_cert .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &validation_info.upgrade_lock, ) @@ -816,7 +804,7 @@ pub(crate) async fn validate_proposal_view_and_certs< // View sync certs must also be valid. view_sync_cert .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &validation_info.upgrade_lock, ) @@ -944,7 +932,7 @@ pub async fn validate_qc_and_next_epoch_qc( { let consensus_reader = consensus.read().await; qc.is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, upgrade_lock, ) @@ -972,7 +960,7 @@ pub async fn validate_qc_and_next_epoch_qc( // Validate the next epoch qc as well next_epoch_qc .is_valid_cert( - membership_next_stake_table, + StakeTableEntries::::from(membership_next_stake_table).0, membership_next_success_threshold, upgrade_lock, ) diff --git a/hotshot-task-impls/src/quorum_proposal/handlers.rs b/hotshot-task-impls/src/quorum_proposal/handlers.rs index 4ac06ff2f3..c2372962d3 100644 --- a/hotshot-task-impls/src/quorum_proposal/handlers.rs +++ b/hotshot-task-impls/src/quorum_proposal/handlers.rs @@ -28,7 +28,7 @@ use hotshot_types::{ signature_key::SignatureKey, }, utils::{is_last_block_in_epoch, option_epoch_from_block_number}, - vote::{Certificate, HasViewNumber}, + vote::{Certificate, HasViewNumber}, StakeTableEntries, }; use hotshot_utils::anytrace::*; use tracing::instrument; @@ -134,7 +134,7 @@ impl ProposalDependencyHandle { if qc .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &self.upgrade_lock, ) @@ -348,7 +348,7 @@ impl ProposalDependencyHandle { .await .drb_seeds_and_results .results - .get(epoch_val) + .get(&(*epoch_val + 1)) .copied() } else { None diff --git a/hotshot-task-impls/src/quorum_proposal/mod.rs b/hotshot-task-impls/src/quorum_proposal/mod.rs index 3866ee6042..c5bcc1bc00 100644 --- a/hotshot-task-impls/src/quorum_proposal/mod.rs +++ b/hotshot-task-impls/src/quorum_proposal/mod.rs @@ -15,6 +15,7 @@ use hotshot_task::{ dependency_task::DependencyTask, task::TaskState, }; +use hotshot_types::StakeTableEntries; use hotshot_types::{ consensus::OuterConsensus, message::UpgradeLock, @@ -479,7 +480,7 @@ impl, V: Versions> certificate .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &self.upgrade_lock, ) @@ -563,7 +564,7 @@ impl, V: Versions> drop(membership_reader); qc.is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &self.upgrade_lock, ) diff --git a/hotshot-task-impls/src/quorum_vote/mod.rs b/hotshot-task-impls/src/quorum_vote/mod.rs index 5493a166e7..32354d7c6b 100644 --- a/hotshot-task-impls/src/quorum_vote/mod.rs +++ b/hotshot-task-impls/src/quorum_vote/mod.rs @@ -15,6 +15,7 @@ use hotshot_task::{ dependency_task::{DependencyTask, HandleDepOutput}, task::TaskState, }; +use hotshot_types::StakeTableEntries; use hotshot_types::{ consensus::{ConsensusMetricsValue, OuterConsensus}, data::{Leaf2, QuorumProposalWrapper}, @@ -553,7 +554,7 @@ impl, V: Versions> QuorumVoteTaskS // Validate the DAC. cert.is_valid_cert( - membership_da_stake_table, + StakeTableEntries::::from(membership_da_stake_table).0, membership_da_success_threshold, &self.upgrade_lock, ) diff --git a/hotshot-task-impls/src/view_sync.rs b/hotshot-task-impls/src/view_sync.rs index 8d203f1107..f984bc4dff 100644 --- a/hotshot-task-impls/src/view_sync.rs +++ b/hotshot-task-impls/src/view_sync.rs @@ -31,6 +31,7 @@ use hotshot_types::{ }, utils::EpochTransitionIndicator, vote::{Certificate, HasViewNumber, Vote}, + StakeTableEntries, }; use hotshot_utils::anytrace::*; use tokio::{spawn, task::JoinHandle, time::sleep}; @@ -557,7 +558,7 @@ impl ViewSyncReplicaTaskState { // If certificate is not valid, return current state if let Err(e) = certificate .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_failure_threshold, &self.upgrade_lock, ) @@ -651,7 +652,7 @@ impl ViewSyncReplicaTaskState { // If certificate is not valid, return current state if let Err(e) = certificate .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &self.upgrade_lock, ) @@ -756,7 +757,7 @@ impl ViewSyncReplicaTaskState { // If certificate is not valid, return current state if let Err(e) = certificate .is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_success_threshold, &self.upgrade_lock, ) diff --git a/hotshot-testing/src/helpers.rs b/hotshot-testing/src/helpers.rs index 64ffb29083..be2ee38f55 100644 --- a/hotshot-testing/src/helpers.rs +++ b/hotshot-testing/src/helpers.rs @@ -25,19 +25,11 @@ use hotshot_example_types::{ }; use hotshot_task_impls::events::HotShotEvent; use hotshot_types::{ - consensus::ConsensusMetricsValue, - data::{vid_commitment, Leaf2, VidCommitment, VidDisperse, VidDisperseShare}, - message::{Proposal, UpgradeLock}, - simple_certificate::DaCertificate2, - simple_vote::{DaData2, DaVote2, SimpleVote, VersionedVoteData}, - traits::{ + consensus::ConsensusMetricsValue, data::{vid_commitment, Leaf2, VidCommitment, VidDisperse, VidDisperseShare}, message::{Proposal, UpgradeLock}, simple_certificate::DaCertificate2, simple_vote::{DaData2, DaVote2, SimpleVote, VersionedVoteData}, traits::{ election::Membership, node_implementation::{NodeType, Versions}, EncodeBytes, - }, - utils::{option_epoch_from_block_number, View, ViewInner}, - vote::{Certificate, HasViewNumber, Vote}, - ValidatorConfig, + }, utils::{option_epoch_from_block_number, View, ViewInner}, vote::{Certificate, HasViewNumber, Vote}, StakeTableEntries, ValidatorConfig }; use primitive_types::U256; use serde::Serialize; @@ -229,7 +221,7 @@ pub async fn build_assembled_sig< let stake_table = CERT::stake_table(&*membership_reader, epoch); let real_qc_pp: ::QcParams = ::public_parameter( - stake_table.clone(), + StakeTableEntries::::from(stake_table.clone()).0, U256::from(CERT::threshold(&*membership_reader, epoch)), ); drop(membership_reader); diff --git a/hotshot-types/src/lib.rs b/hotshot-types/src/lib.rs index 8d227f42ba..822fc62f6e 100644 --- a/hotshot-types/src/lib.rs +++ b/hotshot-types/src/lib.rs @@ -11,7 +11,7 @@ use bincode::Options; use displaydoc::Display; use light_client::StateVerKey; use tracing::error; -use traits::signature_key::SignatureKey; +use traits::{node_implementation::NodeType, signature_key::SignatureKey}; use url::Url; use vec1::Vec1; @@ -158,6 +158,21 @@ impl Default for PeerConfig { } } +pub struct StakeTableEntries( + pub Vec<<::SignatureKey as SignatureKey>::StakeTableEntry>, +); + +impl From>> for StakeTableEntries { + fn from(peers: Vec>) -> Self { + Self( + peers + .into_iter() + .map(|peer| peer.stake_table_entry) + .collect::>(), + ) + } +} + /// Holds configuration for a `HotShot` #[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)] #[serde(bound(deserialize = ""))] diff --git a/hotshot-types/src/simple_certificate.rs b/hotshot-types/src/simple_certificate.rs index fff599b6d0..82092027b5 100644 --- a/hotshot-types/src/simple_certificate.rs +++ b/hotshot-types/src/simple_certificate.rs @@ -35,6 +35,7 @@ use crate::{ signature_key::SignatureKey, }, vote::{Certificate, HasViewNumber}, + PeerConfig, StakeTableEntries, }; /// Trait which allows use to inject different threshold calculations into a Certificate type @@ -192,7 +193,7 @@ impl> Certificate membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: Option, - ) -> Option<::StakeTableEntry> { + ) -> Option> { membership.da_stake(pub_key, epoch) } @@ -200,7 +201,7 @@ impl> Certificate fn stake_table>( membership: &MEMBERSHIP, epoch: Option, - ) -> Vec<::StakeTableEntry> { + ) -> Vec> { membership.da_stake_table(epoch) } /// Proxy's to `Membership.da_total_nodes` @@ -281,7 +282,7 @@ impl> Certificate, - ) -> Option<::StakeTableEntry> { + ) -> Option> { membership.da_stake(pub_key, epoch) } @@ -289,7 +290,7 @@ impl> Certificate>( membership: &MEMBERSHIP, epoch: Option, - ) -> Vec<::StakeTableEntry> { + ) -> Vec> { membership.da_stake_table(epoch) } /// Proxy's to `Membership.da_total_nodes` @@ -379,14 +380,14 @@ impl< membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: Option, - ) -> Option<::StakeTableEntry> { + ) -> Option> { membership.stake(pub_key, epoch) } fn stake_table>( membership: &MEMBERSHIP, epoch: Option, - ) -> Vec<::StakeTableEntry> { + ) -> Vec> { membership.stake_table(epoch) } @@ -477,7 +478,7 @@ impl UpgradeCertificate { drop(membership_reader); cert.is_valid_cert( - membership_stake_table, + StakeTableEntries::::from(membership_stake_table).0, membership_upgrade_threshold, upgrade_lock, ) diff --git a/hotshot-types/src/traits/election.rs b/hotshot-types/src/traits/election.rs index 2473f6b357..853bcfae5f 100644 --- a/hotshot-types/src/traits/election.rs +++ b/hotshot-types/src/traits/election.rs @@ -11,14 +11,13 @@ use async_trait::async_trait; use hotshot_utils::anytrace::Result; use super::node_implementation::NodeType; -use crate::{drb::DrbResult, traits::signature_key::SignatureKey, PeerConfig}; +use crate::{drb::DrbResult, PeerConfig}; #[async_trait] /// A protocol for determining membership in and participating in a committee. pub trait Membership: Debug + Send + Sync { /// The error type returned by methods like `lookup_leader`. type Error: std::fmt::Display; - /// Create a committee fn new( // Note: eligible_leaders is currently a hack because the DA leader == the quorum leader @@ -28,16 +27,10 @@ pub trait Membership: Debug + Send + Sync { ) -> Self; /// Get all participants in the committee (including their stake) for a specific epoch - fn stake_table( - &self, - epoch: Option, - ) -> Vec<::StakeTableEntry>; + fn stake_table(&self, epoch: Option) -> Vec>; /// Get all participants in the committee (including their stake) for a specific epoch - fn da_stake_table( - &self, - epoch: Option, - ) -> Vec<::StakeTableEntry>; + fn da_stake_table(&self, epoch: Option) -> Vec>; /// Get all participants in the committee for a specific view for a specific epoch fn committee_members( @@ -66,7 +59,7 @@ pub trait Membership: Debug + Send + Sync { &self, pub_key: &TYPES::SignatureKey, epoch: Option, - ) -> Option<::StakeTableEntry>; + ) -> Option>; /// Get the DA stake table entry for a public key, returns `None` if the /// key is not in the table for a specific epoch @@ -74,7 +67,7 @@ pub trait Membership: Debug + Send + Sync { &self, pub_key: &TYPES::SignatureKey, epoch: Option, - ) -> Option<::StakeTableEntry>; + ) -> Option>; /// See if a node has stake in the committee in a specific epoch fn has_stake(&self, pub_key: &TYPES::SignatureKey, epoch: Option) -> bool; @@ -146,13 +139,6 @@ pub trait Membership: Debug + Send + Sync { None } - #[allow(clippy::type_complexity)] - /// Called after add_epoch_root runs and any callback has been invoked. - /// Causes a read lock to be reacquired for this functionality. - async fn sync_l1(&self) -> Option> { - None - } - /// Called to notify the Membership when a new DRB result has been calculated. /// Observes the same semantics as add_epoch_root fn add_drb_result(&mut self, _epoch: TYPES::Epoch, _drb_result: DrbResult); diff --git a/hotshot-types/src/vote.rs b/hotshot-types/src/vote.rs index 21d2f8ad85..789615ab80 100644 --- a/hotshot-types/src/vote.rs +++ b/hotshot-types/src/vote.rs @@ -29,6 +29,7 @@ use crate::{ node_implementation::{NodeType, Versions}, signature_key::{SignatureKey, StakeTableEntryType}, }, + PeerConfig, StakeTableEntries, }; /// A simple vote that has a signer and commitment to the data voted on. @@ -91,7 +92,7 @@ pub trait Certificate: HasViewNumber { fn stake_table>( membership: &MEMBERSHIP, epoch: Option, - ) -> Vec<::StakeTableEntry>; + ) -> Vec>; /// Get Total Nodes from Membership implementation. fn total_nodes>( @@ -104,7 +105,7 @@ pub trait Certificate: HasViewNumber { membership: &MEMBERSHIP, pub_key: &TYPES::SignatureKey, epoch: Option, - ) -> Option<::StakeTableEntry>; + ) -> Option>; /// Get the commitment which was voted on fn data(&self) -> &Self::Voteable; @@ -221,14 +222,14 @@ impl< signers.set(vote_node_id, true); sig_list.push(original_signature); - *total_stake_casted += stake_table_entry.stake(); + *total_stake_casted += stake_table_entry.stake_table_entry.stake(); total_vote_map.insert(key, (vote.signature(), vote_commitment)); if *total_stake_casted >= threshold.into() { // Assemble QC let real_qc_pp: <::SignatureKey as SignatureKey>::QcParams = ::public_parameter( - stake_table, + StakeTableEntries::::from(stake_table).0, U256::from(threshold), ); diff --git a/hotshot/src/traits/election/randomized_committee.rs b/hotshot/src/traits/election/randomized_committee.rs index 932ef724fa..dca2593d33 100644 --- a/hotshot/src/traits/election/randomized_committee.rs +++ b/hotshot/src/traits/election/randomized_committee.rs @@ -4,7 +4,11 @@ // You should have received a copy of the MIT License // along with the HotShot repository. If not, see . -use std::{cmp::max, collections::BTreeMap, num::NonZeroU64}; +use std::{ + cmp::max, + collections::{BTreeMap, BTreeSet}, + num::NonZeroU64, +}; use hotshot_types::{ drb::{ @@ -28,77 +32,86 @@ pub struct Committee { /// The nodes eligible for leadership. /// NOTE: This is currently a hack because the DA leader needs to be the quorum /// leader but without voting rights. - eligible_leaders: Vec<::StakeTableEntry>, + eligible_leaders: Vec>, /// The nodes on the committee and their stake - stake_table: Vec<::StakeTableEntry>, + stake_table: Vec>, /// The nodes on the committee and their stake - da_stake_table: Vec<::StakeTableEntry>, + da_stake_table: Vec>, /// Stake tables randomized with the DRB, used (only) for leader election randomized_committee: RandomizedCommittee<::StakeTableEntry>, /// The nodes on the committee and their stake, indexed by public key - indexed_stake_table: - BTreeMap::StakeTableEntry>, + indexed_stake_table: BTreeMap>, /// The nodes on the committee and their stake, indexed by public key - indexed_da_stake_table: - BTreeMap::StakeTableEntry>, + indexed_da_stake_table: BTreeMap>, } impl Membership for Committee { type Error = hotshot_utils::anytrace::Error; - /// Create a new election fn new( committee_members: Vec::SignatureKey>>, da_members: Vec::SignatureKey>>, ) -> Self { // For each eligible leader, get the stake table entry - let eligible_leaders: Vec<::StakeTableEntry> = + let eligible_leaders: Vec::SignatureKey>> = committee_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // For each member, get the stake table entry - let members: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let members: Vec::SignatureKey>> = committee_members + .iter() + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() + .collect(); // For each member, get the stake table entry - let da_members: Vec<::StakeTableEntry> = da_members + let da_members: Vec::SignatureKey>> = da_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // Index the stake table by public key - let indexed_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = members - .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) - .collect(); + let indexed_stake_table: BTreeMap> = + members + .iter() + .map(|config| { + ( + TYPES::SignatureKey::public_key(&config.stake_table_entry), + config.clone(), + ) + }) + .collect(); // Index the stake table by public key - let indexed_da_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = da_members - .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) - .collect(); + let indexed_da_stake_table: BTreeMap> = + da_members + .iter() + .map(|config| { + ( + TYPES::SignatureKey::public_key(&config.stake_table_entry), + config.clone(), + ) + }) + .collect(); // We use a constant value of `[0u8; 32]` for the drb, since this is just meant to be used in tests - let randomized_committee = generate_stake_cdf(eligible_leaders.clone(), [0u8; 32]); + let randomized_committee = generate_stake_cdf( + eligible_leaders + .clone() + .into_iter() + .map(|leader| leader.stake_table_entry) + .collect::>(), + [0u8; 32], + ); Self { eligible_leaders, @@ -114,7 +127,7 @@ impl Membership for Committee { fn stake_table( &self, _epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec> { self.stake_table.clone() } @@ -122,7 +135,7 @@ impl Membership for Committee { fn da_stake_table( &self, _epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec> { self.da_stake_table.clone() } @@ -131,10 +144,10 @@ impl Membership for Committee { &self, _view_number: ::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|x| TYPES::SignatureKey::public_key(&x.stake_table_entry)) .collect() } @@ -143,10 +156,10 @@ impl Membership for Committee { &self, _view_number: ::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.da_stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|x| TYPES::SignatureKey::public_key(&x.stake_table_entry)) .collect() } @@ -155,10 +168,10 @@ impl Membership for Committee { &self, _view_number: ::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.eligible_leaders .iter() - .map(TYPES::SignatureKey::public_key) + .map(|x| TYPES::SignatureKey::public_key(&x.stake_table_entry)) .collect() } @@ -167,7 +180,7 @@ impl Membership for Committee { &self, pub_key: &::SignatureKey, _epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option> { // Only return the stake if it is above zero self.indexed_stake_table.get(pub_key).cloned() } @@ -177,7 +190,7 @@ impl Membership for Committee { &self, pub_key: &::SignatureKey, _epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option> { // Only return the stake if it is above zero self.indexed_da_stake_table.get(pub_key).cloned() } @@ -190,7 +203,7 @@ impl Membership for Committee { ) -> bool { self.indexed_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Check if a node has stake in the committee @@ -201,7 +214,7 @@ impl Membership for Committee { ) -> bool { self.indexed_da_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } // /// Get the network topic for the committee diff --git a/hotshot/src/traits/election/randomized_committee_members.rs b/hotshot/src/traits/election/randomized_committee_members.rs index 4a3c8d508a..78d5881005 100644 --- a/hotshot/src/traits/election/randomized_committee_members.rs +++ b/hotshot/src/traits/election/randomized_committee_members.rs @@ -32,21 +32,19 @@ pub struct RandomizedCommitteeMembers { /// The nodes eligible for leadership. /// NOTE: This is currently a hack because the DA leader needs to be the quorum /// leader but without voting rights. - eligible_leaders: Vec<::StakeTableEntry>, + eligible_leaders: Vec>, /// The nodes on the committee and their stake - stake_table: Vec<::StakeTableEntry>, + stake_table: Vec>, /// The nodes on the da committee and their stake - da_stake_table: Vec<::StakeTableEntry>, + da_stake_table: Vec>, /// The nodes on the committee and their stake, indexed by public key - indexed_stake_table: - BTreeMap::StakeTableEntry>, + indexed_stake_table: BTreeMap>, /// The nodes on the da committee and their stake, indexed by public key - indexed_da_stake_table: - BTreeMap::StakeTableEntry>, + indexed_da_stake_table: BTreeMap>, /// Phantom _pd: PhantomData, @@ -98,51 +96,52 @@ impl Membership for RandomizedCommitteeMembers { type Error = hotshot_utils::anytrace::Error; - /// Create a new election fn new( committee_members: Vec::SignatureKey>>, da_members: Vec::SignatureKey>>, ) -> Self { // For each eligible leader, get the stake table entry - let eligible_leaders: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let eligible_leaders = committee_members + .iter() + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() + .collect(); // For each member, get the stake table entry - let members: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let members: Vec::SignatureKey>> = committee_members + .iter() + .filter(|&entry| entry.stake_table_entry.stake() > U256::zero()) + .cloned() + .collect(); // For each da member, get the stake table entry - let da_members: Vec<::StakeTableEntry> = da_members + let da_members: Vec::SignatureKey>> = da_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&entry| entry.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // Index the stake table by public key - let indexed_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = members + let indexed_stake_table = members .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|entry| { + ( + TYPES::SignatureKey::public_key(&entry.stake_table_entry), + entry.clone(), + ) + }) .collect(); // Index the stake table by public key - let indexed_da_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = da_members + let indexed_da_stake_table = da_members .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|entry| { + ( + TYPES::SignatureKey::public_key(&entry.stake_table_entry), + entry.clone(), + ) + }) .collect(); let s = Self { @@ -163,7 +162,7 @@ impl Membership fn stake_table( &self, epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec> { if let Some(epoch) = epoch { let filter = self.make_quorum_filter(epoch); //self.stake_table.clone()s @@ -182,7 +181,7 @@ impl Membership fn da_stake_table( &self, epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec> { if let Some(epoch) = epoch { let filter = self.make_da_quorum_filter(epoch); //self.stake_table.clone()s @@ -209,12 +208,12 @@ impl Membership .iter() .enumerate() .filter(|(idx, _)| filter.contains(idx)) - .map(|(_, v)| TYPES::SignatureKey::public_key(v)) + .map(|(_, v)| TYPES::SignatureKey::public_key(&v.stake_table_entry)) .collect() } else { self.stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|config| TYPES::SignatureKey::public_key(&config.stake_table_entry)) .collect() } } @@ -231,12 +230,12 @@ impl Membership .iter() .enumerate() .filter(|(idx, _)| filter.contains(idx)) - .map(|(_, v)| TYPES::SignatureKey::public_key(v)) + .map(|(_, v)| TYPES::SignatureKey::public_key(&v.stake_table_entry)) .collect() } else { self.da_stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|config| TYPES::SignatureKey::public_key(&config.stake_table_entry)) .collect() } } @@ -255,7 +254,7 @@ impl Membership &self, pub_key: &::SignatureKey, epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option::SignatureKey>> { if let Some(epoch) = epoch { let filter = self.make_quorum_filter(epoch); let actual_members: BTreeSet<_> = self @@ -263,7 +262,7 @@ impl Membership .iter() .enumerate() .filter(|(idx, _)| filter.contains(idx)) - .map(|(_, v)| TYPES::SignatureKey::public_key(v)) + .map(|(_, v)| TYPES::SignatureKey::public_key(&v.stake_table_entry)) .collect(); if actual_members.contains(pub_key) { @@ -283,7 +282,7 @@ impl Membership &self, pub_key: &::SignatureKey, epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option::SignatureKey>> { if let Some(epoch) = epoch { let filter = self.make_da_quorum_filter(epoch); let actual_members: BTreeSet<_> = self @@ -291,7 +290,7 @@ impl Membership .iter() .enumerate() .filter(|(idx, _)| filter.contains(idx)) - .map(|(_, v)| TYPES::SignatureKey::public_key(v)) + .map(|(_, v)| TYPES::SignatureKey::public_key(&v.stake_table_entry)) .collect(); if actual_members.contains(pub_key) { @@ -319,13 +318,13 @@ impl Membership .iter() .enumerate() .filter(|(idx, _)| filter.contains(idx)) - .map(|(_, v)| TYPES::SignatureKey::public_key(v)) + .map(|(_, v)| TYPES::SignatureKey::public_key(&v.stake_table_entry)) .collect(); if actual_members.contains(pub_key) { self.indexed_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } else { // Skip members which aren't included based on the quorum filter false @@ -333,7 +332,7 @@ impl Membership } else { self.indexed_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } } @@ -350,13 +349,13 @@ impl Membership .iter() .enumerate() .filter(|(idx, _)| filter.contains(idx)) - .map(|(_, v)| TYPES::SignatureKey::public_key(v)) + .map(|(_, v)| TYPES::SignatureKey::public_key(&v.stake_table_entry)) .collect(); if actual_members.contains(pub_key) { self.indexed_da_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } else { // Skip members which aren't included based on the quorum filter false @@ -364,7 +363,7 @@ impl Membership } else { self.indexed_da_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } } @@ -392,7 +391,7 @@ impl Membership let res = leader_vec[index].clone(); - Ok(TYPES::SignatureKey::public_key(&res)) + Ok(TYPES::SignatureKey::public_key(&res.stake_table_entry)) } else { let mut rng: StdRng = rand::SeedableRng::seed_from_u64(*view_number); @@ -402,7 +401,7 @@ impl Membership let res = self.eligible_leaders[index].clone(); - Ok(TYPES::SignatureKey::public_key(&res)) + Ok(TYPES::SignatureKey::public_key(&res.stake_table_entry)) } } diff --git a/hotshot/src/traits/election/static_committee.rs b/hotshot/src/traits/election/static_committee.rs index 7bcf0fc431..6b6232a5a6 100644 --- a/hotshot/src/traits/election/static_committee.rs +++ b/hotshot/src/traits/election/static_committee.rs @@ -4,7 +4,11 @@ // You should have received a copy of the MIT License // along with the HotShot repository. If not, see . -use std::{cmp::max, collections::BTreeMap, num::NonZeroU64}; +use std::{ + cmp::max, + collections::{BTreeMap, BTreeSet}, + num::NonZeroU64, +}; use hotshot_types::{ drb::DrbResult, @@ -24,70 +28,68 @@ pub struct StaticCommittee { /// The nodes eligible for leadership. /// NOTE: This is currently a hack because the DA leader needs to be the quorum /// leader but without voting rights. - eligible_leaders: Vec<::StakeTableEntry>, + eligible_leaders: Vec>, /// The nodes on the committee and their stake - stake_table: Vec<::StakeTableEntry>, + stake_table: Vec>, /// The nodes on the committee and their stake - da_stake_table: Vec<::StakeTableEntry>, + da_stake_table: Vec>, /// The nodes on the committee and their stake, indexed by public key - indexed_stake_table: - BTreeMap::StakeTableEntry>, + indexed_stake_table: BTreeMap>, /// The nodes on the committee and their stake, indexed by public key - indexed_da_stake_table: - BTreeMap::StakeTableEntry>, + indexed_da_stake_table: BTreeMap>, } impl Membership for StaticCommittee { type Error = hotshot_utils::anytrace::Error; - /// Create a new election fn new( committee_members: Vec::SignatureKey>>, da_members: Vec::SignatureKey>>, ) -> Self { // For each eligible leader, get the stake table entry - let eligible_leaders: Vec<::StakeTableEntry> = + let eligible_leaders: Vec::SignatureKey>> = committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .clone() + .into_iter() + .filter(|member| member.stake_table_entry.stake() > U256::zero()) .collect(); // For each member, get the stake table entry - let members: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let members: Vec::SignatureKey>> = committee_members + .into_iter() + .filter(|member| member.stake_table_entry.stake() > U256::zero()) + .collect(); // For each member, get the stake table entry - let da_members: Vec<::StakeTableEntry> = da_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + let da_members: Vec::SignatureKey>> = da_members + .into_iter() + .filter(|member| member.stake_table_entry.stake() > U256::zero()) .collect(); // Index the stake table by public key - let indexed_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = members + let indexed_stake_table: BTreeMap = members .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|entry| { + ( + TYPES::SignatureKey::public_key(&entry.stake_table_entry), + entry.clone(), + ) + }) .collect(); // Index the stake table by public key - let indexed_da_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = da_members + let indexed_da_stake_table: BTreeMap = da_members .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|entry| { + ( + TYPES::SignatureKey::public_key(&entry.stake_table_entry), + entry.clone(), + ) + }) .collect(); Self { @@ -103,7 +105,7 @@ impl Membership for StaticCommittee { fn stake_table( &self, _epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec::SignatureKey>> { self.stake_table.clone() } @@ -111,7 +113,7 @@ impl Membership for StaticCommittee { fn da_stake_table( &self, _epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec::SignatureKey>> { self.da_stake_table.clone() } @@ -120,10 +122,10 @@ impl Membership for StaticCommittee { &self, _view_number: ::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|sc| TYPES::SignatureKey::public_key(&sc.stake_table_entry)) .collect() } @@ -132,10 +134,10 @@ impl Membership for StaticCommittee { &self, _view_number: ::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.da_stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|da| TYPES::SignatureKey::public_key(&da.stake_table_entry)) .collect() } @@ -144,10 +146,10 @@ impl Membership for StaticCommittee { &self, _view_number: ::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.eligible_leaders .iter() - .map(TYPES::SignatureKey::public_key) + .map(|leader| TYPES::SignatureKey::public_key(&leader.stake_table_entry)) .collect() } @@ -156,7 +158,7 @@ impl Membership for StaticCommittee { &self, pub_key: &::SignatureKey, _epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option::SignatureKey>> { // Only return the stake if it is above zero self.indexed_stake_table.get(pub_key).cloned() } @@ -166,7 +168,7 @@ impl Membership for StaticCommittee { &self, pub_key: &::SignatureKey, _epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option::SignatureKey>> { // Only return the stake if it is above zero self.indexed_da_stake_table.get(pub_key).cloned() } @@ -179,7 +181,7 @@ impl Membership for StaticCommittee { ) -> bool { self.indexed_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Check if a node has stake in the committee @@ -190,7 +192,7 @@ impl Membership for StaticCommittee { ) -> bool { self.indexed_da_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Index the vector of public keys with the current view number @@ -202,7 +204,7 @@ impl Membership for StaticCommittee { #[allow(clippy::cast_possible_truncation)] let index = *view_number as usize % self.eligible_leaders.len(); let res = self.eligible_leaders[index].clone(); - Ok(TYPES::SignatureKey::public_key(&res)) + Ok(TYPES::SignatureKey::public_key(&res.stake_table_entry)) } /// Get the total number of nodes in the committee diff --git a/hotshot/src/traits/election/static_committee_leader_two_views.rs b/hotshot/src/traits/election/static_committee_leader_two_views.rs index 52412c26d5..37ce00dcd5 100644 --- a/hotshot/src/traits/election/static_committee_leader_two_views.rs +++ b/hotshot/src/traits/election/static_committee_leader_two_views.rs @@ -15,7 +15,10 @@ use hotshot_types::{ }; use hotshot_utils::anytrace::Result; use primitive_types::U256; -use std::{collections::BTreeMap, num::NonZeroU64}; +use std::{ + collections::{BTreeMap, BTreeSet}, + num::NonZeroU64, +}; #[derive(Clone, Debug, Eq, PartialEq, Hash)] @@ -24,71 +27,72 @@ pub struct StaticCommitteeLeaderForTwoViews { /// The nodes eligible for leadership. /// NOTE: This is currently a hack because the DA leader needs to be the quorum /// leader but without voting rights. - eligible_leaders: Vec<::StakeTableEntry>, + eligible_leaders: Vec>, /// The nodes on the committee and their stake - stake_table: Vec<::StakeTableEntry>, + stake_table: Vec>, /// The nodes on the committee and their stake - da_stake_table: Vec<::StakeTableEntry>, + da_stake_table: Vec>, /// The nodes on the committee and their stake, indexed by public key - indexed_stake_table: - BTreeMap::StakeTableEntry>, + indexed_stake_table: BTreeMap>, /// The nodes on the committee and their stake, indexed by public key - indexed_da_stake_table: - BTreeMap::StakeTableEntry>, + indexed_da_stake_table: BTreeMap>, } impl Membership for StaticCommitteeLeaderForTwoViews { type Error = hotshot_utils::anytrace::Error; - /// Create a new election fn new( committee_members: Vec::SignatureKey>>, da_members: Vec::SignatureKey>>, ) -> Self { // For each eligible leader, get the stake table entry - let eligible_leaders: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let eligible_leaders: Vec> = committee_members + .iter() + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() + .collect(); // For each member, get the stake table entry - let members: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let members: Vec> = committee_members + .iter() + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() + .collect(); // For each member, get the stake table entry - let da_members: Vec<::StakeTableEntry> = da_members + let da_members: Vec> = da_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&member| member.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // Index the stake table by public key - let indexed_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = members - .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) - .collect(); + let indexed_stake_table: BTreeMap> = + members + .iter() + .map(|member| { + ( + TYPES::SignatureKey::public_key(&member.stake_table_entry), + member.clone(), + ) + }) + .collect(); // Index the stake table by public key - let indexed_da_stake_table: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = da_members - .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) - .collect(); + let indexed_da_stake_table: BTreeMap> = + da_members + .iter() + .map(|member| { + ( + TYPES::SignatureKey::public_key(&member.stake_table_entry), + member.clone(), + ) + }) + .collect(); Self { eligible_leaders, @@ -103,7 +107,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec::SignatureKey>> { self.stake_table.clone() } @@ -111,7 +115,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec::SignatureKey>> { self.da_stake_table.clone() } @@ -120,10 +124,10 @@ impl Membership for StaticCommitteeLeaderForTwoViews::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|sc| TYPES::SignatureKey::public_key(&sc.stake_table_entry)) .collect() } @@ -132,10 +136,10 @@ impl Membership for StaticCommitteeLeaderForTwoViews::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.da_stake_table .iter() - .map(TYPES::SignatureKey::public_key) + .map(|da| TYPES::SignatureKey::public_key(&da.stake_table_entry)) .collect() } @@ -144,10 +148,10 @@ impl Membership for StaticCommitteeLeaderForTwoViews::View, _epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { self.eligible_leaders .iter() - .map(TYPES::SignatureKey::public_key) + .map(|leader| TYPES::SignatureKey::public_key(&leader.stake_table_entry)) .collect() } @@ -156,7 +160,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::SignatureKey, _epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option> { // Only return the stake if it is above zero self.indexed_stake_table.get(pub_key).cloned() } @@ -166,7 +170,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews::SignatureKey, _epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option> { // Only return the stake if it is above zero self.indexed_da_stake_table.get(pub_key).cloned() } @@ -179,7 +183,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews bool { self.indexed_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Check if a node has stake in the committee @@ -190,7 +194,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews bool { self.indexed_da_stake_table .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Index the vector of public keys with the current view number @@ -203,7 +207,7 @@ impl Membership for StaticCommitteeLeaderForTwoViews Membership for StaticCommitteeLeaderForTwoViews::Epoch>) -> NonZeroU64 { NonZeroU64::new(((self.stake_table.len() as u64 * 9) / 10) + 1).unwrap() } - fn add_drb_result(&mut self, _epoch: ::Epoch, _drb_result: DrbResult) {} } diff --git a/hotshot/src/traits/election/two_static_committees.rs b/hotshot/src/traits/election/two_static_committees.rs index 1c7c583cbc..205a127029 100644 --- a/hotshot/src/traits/election/two_static_committees.rs +++ b/hotshot/src/traits/election/two_static_committees.rs @@ -15,30 +15,28 @@ use hotshot_types::{ }; use hotshot_utils::anytrace::Result; use primitive_types::U256; -use std::{cmp::max, collections::BTreeMap, num::NonZeroU64}; +use std::{ + cmp::max, + collections::{BTreeMap, BTreeSet}, + num::NonZeroU64, +}; /// Tuple type for eligible leaders type EligibleLeaders = ( - Vec<<::SignatureKey as SignatureKey>::StakeTableEntry>, - Vec<<::SignatureKey as SignatureKey>::StakeTableEntry>, + Vec::SignatureKey>>, + Vec::SignatureKey>>, ); /// Tuple type for stake tables type StakeTables = ( - Vec<<::SignatureKey as SignatureKey>::StakeTableEntry>, - Vec<<::SignatureKey as SignatureKey>::StakeTableEntry>, + Vec::SignatureKey>>, + Vec::SignatureKey>>, ); /// Tuple type for indexed stake tables type IndexedStakeTables = ( - BTreeMap< - ::SignatureKey, - <::SignatureKey as SignatureKey>::StakeTableEntry, - >, - BTreeMap< - ::SignatureKey, - <::SignatureKey as SignatureKey>::StakeTableEntry, - >, + BTreeMap<::SignatureKey, PeerConfig<::SignatureKey>>, + BTreeMap<::SignatureKey, PeerConfig<::SignatureKey>>, ); #[derive(Clone, Debug, Eq, PartialEq, Hash)] @@ -64,18 +62,17 @@ pub struct TwoStaticCommittees { impl Membership for TwoStaticCommittees { type Error = hotshot_utils::anytrace::Error; - /// Create a new election fn new( committee_members: Vec::SignatureKey>>, da_members: Vec::SignatureKey>>, ) -> Self { // For each eligible leader, get the stake table entry - let eligible_leaders: Vec<::StakeTableEntry> = + let eligible_leaders: Vec::SignatureKey>> = committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .clone() + .into_iter() + .filter(|member| member.stake_table_entry.stake() > U256::zero()) .collect(); let eligible_leaders1 = eligible_leaders @@ -92,20 +89,19 @@ impl Membership for TwoStaticCommittees { .collect(); // For each member, get the stake table entry - let members: Vec<::StakeTableEntry> = - committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); + let members: Vec::SignatureKey>> = committee_members + .clone() + .into_iter() + .filter(|member| member.stake_table_entry.stake() > U256::zero()) + .collect(); - let members1: Vec<::StakeTableEntry> = members + let members1: Vec::SignatureKey>> = members .iter() .enumerate() .filter(|(idx, _)| idx % 2 == 0) .map(|(_, leader)| leader.clone()) .collect(); - let members2: Vec<::StakeTableEntry> = members + let members2: Vec::SignatureKey>> = members .iter() .enumerate() .filter(|(idx, _)| idx % 2 == 1) @@ -113,19 +109,19 @@ impl Membership for TwoStaticCommittees { .collect(); // For each member, get the stake table entry - let da_members: Vec<::StakeTableEntry> = da_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + let da_members: Vec::SignatureKey>> = da_members + .clone() + .into_iter() + .filter(|member| member.stake_table_entry.stake() > U256::zero()) .collect(); - let da_members1: Vec<::StakeTableEntry> = da_members + let da_members1: Vec::SignatureKey>> = da_members .iter() .enumerate() .filter(|(idx, _)| idx % 2 == 0) .map(|(_, leader)| leader.clone()) .collect(); - let da_members2: Vec<::StakeTableEntry> = da_members + let da_members2: Vec::SignatureKey>> = da_members .iter() .enumerate() .filter(|(idx, _)| idx % 2 == 1) @@ -133,37 +129,45 @@ impl Membership for TwoStaticCommittees { .collect(); // Index the stake table by public key - let indexed_stake_table1: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = members1 + let indexed_stake_table1: BTreeMap = members1 .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|member| { + ( + TYPES::SignatureKey::public_key(&member.stake_table_entry), + member.clone(), + ) + }) .collect(); - let indexed_stake_table2: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = members2 + let indexed_stake_table2: BTreeMap = members2 .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|member| { + ( + TYPES::SignatureKey::public_key(&member.stake_table_entry), + member.clone(), + ) + }) .collect(); // Index the stake table by public key - let indexed_da_stake_table1: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = da_members1 + let indexed_da_stake_table1: BTreeMap = da_members1 .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|member| { + ( + TYPES::SignatureKey::public_key(&member.stake_table_entry), + member.clone(), + ) + }) .collect(); - let indexed_da_stake_table2: BTreeMap< - TYPES::SignatureKey, - ::StakeTableEntry, - > = da_members2 + let indexed_da_stake_table2: BTreeMap = da_members2 .iter() - .map(|entry| (TYPES::SignatureKey::public_key(entry), entry.clone())) + .map(|member| { + ( + TYPES::SignatureKey::public_key(&member.stake_table_entry), + member.clone(), + ) + }) .collect(); Self { @@ -179,7 +183,7 @@ impl Membership for TwoStaticCommittees { fn stake_table( &self, epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec::SignatureKey>> { let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { self.stake_table.0.clone() @@ -192,7 +196,7 @@ impl Membership for TwoStaticCommittees { fn da_stake_table( &self, epoch: Option<::Epoch>, - ) -> Vec<<::SignatureKey as SignatureKey>::StakeTableEntry> { + ) -> Vec::SignatureKey>> { let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { self.da_stake_table.0.clone() @@ -206,19 +210,19 @@ impl Membership for TwoStaticCommittees { &self, _view_number: ::View, epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { self.stake_table .0 .iter() - .map(TYPES::SignatureKey::public_key) + .map(|sc| TYPES::SignatureKey::public_key(&sc.stake_table_entry)) .collect() } else { self.stake_table .1 .iter() - .map(TYPES::SignatureKey::public_key) + .map(|sc| TYPES::SignatureKey::public_key(&sc.stake_table_entry)) .collect() } } @@ -228,19 +232,19 @@ impl Membership for TwoStaticCommittees { &self, _view_number: ::View, epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { self.da_stake_table .0 .iter() - .map(TYPES::SignatureKey::public_key) + .map(|da| TYPES::SignatureKey::public_key(&da.stake_table_entry)) .collect() } else { self.da_stake_table .1 .iter() - .map(TYPES::SignatureKey::public_key) + .map(|da| TYPES::SignatureKey::public_key(&da.stake_table_entry)) .collect() } } @@ -250,19 +254,19 @@ impl Membership for TwoStaticCommittees { &self, _view_number: ::View, epoch: Option<::Epoch>, - ) -> std::collections::BTreeSet<::SignatureKey> { + ) -> BTreeSet<::SignatureKey> { let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { self.eligible_leaders .0 .iter() - .map(TYPES::SignatureKey::public_key) + .map(|leader| TYPES::SignatureKey::public_key(&leader.stake_table_entry)) .collect() } else { self.eligible_leaders .1 .iter() - .map(TYPES::SignatureKey::public_key) + .map(|leader| TYPES::SignatureKey::public_key(&leader.stake_table_entry)) .collect() } } @@ -272,7 +276,7 @@ impl Membership for TwoStaticCommittees { &self, pub_key: &::SignatureKey, epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option::SignatureKey>> { // Only return the stake if it is above zero let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { @@ -287,7 +291,7 @@ impl Membership for TwoStaticCommittees { &self, pub_key: &::SignatureKey, epoch: Option<::Epoch>, - ) -> Option<::StakeTableEntry> { + ) -> Option::SignatureKey>> { // Only return the stake if it is above zero let epoch = epoch.expect("epochs cannot be disabled with TwoStaticCommittees"); if *epoch != 0 && *epoch % 2 == 0 { @@ -308,15 +312,14 @@ impl Membership for TwoStaticCommittees { self.indexed_stake_table .0 .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } else { self.indexed_stake_table .1 .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } } - /// Check if a node has stake in the committee fn has_da_stake( &self, @@ -328,12 +331,12 @@ impl Membership for TwoStaticCommittees { self.indexed_da_stake_table .0 .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } else { self.indexed_da_stake_table .1 .get(pub_key) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } } @@ -348,12 +351,12 @@ impl Membership for TwoStaticCommittees { #[allow(clippy::cast_possible_truncation)] let index = *view_number as usize % self.eligible_leaders.0.len(); let res = self.eligible_leaders.0[index].clone(); - Ok(TYPES::SignatureKey::public_key(&res)) + Ok(TYPES::SignatureKey::public_key(&res.stake_table_entry)) } else { #[allow(clippy::cast_possible_truncation)] let index = *view_number as usize % self.eligible_leaders.1.len(); let res = self.eligible_leaders.1[index].clone(); - Ok(TYPES::SignatureKey::public_key(&res)) + Ok(TYPES::SignatureKey::public_key(&res.stake_table_entry)) } } diff --git a/sequencer-sqlite/Cargo.lock b/sequencer-sqlite/Cargo.lock index c3d92a660a..94186e0c30 100644 --- a/sequencer-sqlite/Cargo.lock +++ b/sequencer-sqlite/Cargo.lock @@ -1573,7 +1573,7 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atomic_store" version = "0.1.3" -source = "git+https://github.com/EspressoSystems/atomicstore.git?tag=0.1.4#64c092596e889b9f376fd4bae8974404c43cd12c" +source = "git+https://github.com/EspressoSystems/atomicstore.git?tag=0.1.5#6d2bbaf0bb3b5cd49e9907e60738bccbd4b8c374" dependencies = [ "ark-serialize 0.4.2", "bincode", diff --git a/sequencer/src/api.rs b/sequencer/src/api.rs index 51f309f97e..900cc937c9 100644 --- a/sequencer/src/api.rs +++ b/sequencer/src/api.rs @@ -18,6 +18,7 @@ use hotshot_events_service::events_source::{ EventFilterSet, EventsSource, EventsStreamer, StartupInfo, }; use hotshot_query_service::data_source::ExtensibleDataSource; +use hotshot_types::traits::election::Membership; use hotshot_types::{ data::ViewNumber, event::Event, @@ -29,8 +30,8 @@ use hotshot_types::{ ValidatedState as _, }, utils::{View, ViewInner}, + PeerConfig, }; -use hotshot_types::{stake_table::StakeTableEntry, traits::election::Membership}; use jf_merkle_tree::MerkleTreeScheme; use std::pin::Pin; use std::sync::Arc; @@ -167,18 +168,17 @@ impl, D: Sync, V: Versions, P: SequencerPersistence> async fn get_stake_table( &self, epoch: Option<::Epoch>, - ) -> Vec::SignatureKey>> { + ) -> Vec::SignatureKey>> { self.as_ref().get_stake_table(epoch).await } /// Get the stake table for the current epoch if not provided async fn get_stake_table_current( &self, - ) -> Vec::SignatureKey>> { + ) -> Vec::SignatureKey>> { self.as_ref().get_stake_table_current().await } } - impl, V: Versions, P: SequencerPersistence> StakeTableDataSource for ApiState { @@ -186,7 +186,7 @@ impl, V: Versions, P: SequencerPersistence> async fn get_stake_table( &self, epoch: Option<::Epoch>, - ) -> Vec::SignatureKey>> { + ) -> Vec::SignatureKey>> { self.consensus() .await .read() @@ -200,7 +200,7 @@ impl, V: Versions, P: SequencerPersistence> /// Get the stake table for the current epoch if not provided async fn get_stake_table_current( &self, - ) -> Vec::SignatureKey>> { + ) -> Vec::SignatureKey>> { let epoch = self.consensus().await.read().await.cur_epoch().await; self.get_stake_table(epoch).await @@ -2342,7 +2342,7 @@ mod test { // ChainConfigs will eventually be resolved if let Some(configs) = configs { tracing::info!(?configs, "configs"); - if height > new_version_first_view { + if height > new_version_first_view + 10 { for config in configs { assert_eq!(config, chain_config_upgrade); } diff --git a/sequencer/src/api/data_source.rs b/sequencer/src/api/data_source.rs index e3703d3874..1232865f7b 100644 --- a/sequencer/src/api/data_source.rs +++ b/sequencer/src/api/data_source.rs @@ -20,7 +20,6 @@ use hotshot_types::{ data::ViewNumber, light_client::StateSignatureRequestBody, network::NetworkConfig, - stake_table::StakeTableEntry, traits::{network::ConnectedNetwork, node_implementation::Versions}, HotShotConfig, PeerConfig, ValidatorConfig, }; @@ -121,12 +120,12 @@ pub(crate) trait StakeTableDataSource { fn get_stake_table( &self, epoch: Option<::Epoch>, - ) -> impl Send + Future>>; + ) -> impl Send + Future>>; /// Get the stake table for the current epoch if not provided fn get_stake_table_current( &self, - ) -> impl Send + Future>>; + ) -> impl Send + Future>>; } pub(crate) trait CatchupDataSource: Sync { diff --git a/sequencer/src/api/endpoints.rs b/sequencer/src/api/endpoints.rs index 35e15d32b6..651a38e796 100644 --- a/sequencer/src/api/endpoints.rs +++ b/sequencer/src/api/endpoints.rs @@ -28,6 +28,7 @@ use hotshot_types::{ use jf_merkle_tree::MerkleTreeScheme; use serde::{de::Error as _, Deserialize, Serialize}; use snafu::OptionExt; + use tagged_base64::TaggedBase64; use tide_disco::{method::ReadState, Api, Error as _, StatusCode}; use vbs::version::{StaticVersion, StaticVersionType}; diff --git a/types/src/v0/impls/l1.rs b/types/src/v0/impls/l1.rs index 7071a9192e..9661dd47ec 100644 --- a/types/src/v0/impls/l1.rs +++ b/types/src/v0/impls/l1.rs @@ -1389,7 +1389,7 @@ mod test { .unwrap(); let result = nodes.stake_table.0[0].clone(); - assert_eq!(result.stake_amount.as_u64(), 1); + assert_eq!(result.stake_table_entry.stake_amount.as_u64(), 1); Ok(()) } diff --git a/types/src/v0/impls/stake_table.rs b/types/src/v0/impls/stake_table.rs index 9bbf03daad..808e5bd54d 100644 --- a/types/src/v0/impls/stake_table.rs +++ b/types/src/v0/impls/stake_table.rs @@ -2,7 +2,6 @@ use std::{ cmp::max, collections::{BTreeMap, BTreeSet, HashMap}, num::NonZeroU64, - str::FromStr, }; use async_trait::async_trait; @@ -27,7 +26,6 @@ use hotshot_types::{ }; use itertools::Itertools; use thiserror::Error; -use url::Url; use super::{ v0_3::{DAMembers, StakeTable, StakeTables}, @@ -80,8 +78,8 @@ impl StakeTables { StakeTableChange::Remove(_) => None, }); - let mut consensus_stake_table: Vec> = vec![]; - let mut da_members: Vec> = vec![]; + let mut consensus_stake_table: Vec> = vec![]; + let mut da_members: Vec> = vec![]; for node in currently_staking { consensus_stake_table.push(node.clone().into()); if node.da { @@ -135,19 +133,19 @@ struct Committee { /// The nodes eligible for leadership. /// NOTE: This is currently a hack because the DA leader needs to be the quorum /// leader but without voting rights. - eligible_leaders: Vec>, + eligible_leaders: Vec>, /// Keys for nodes participating in the network - stake_table: Vec>, + stake_table: Vec>, /// Keys for DA members - da_members: Vec>, + da_members: Vec>, /// Stake entries indexed by public key, for efficient lookup. - indexed_stake_table: HashMap>, + indexed_stake_table: HashMap>, /// DA entries indexed by public key, for efficient lookup. - indexed_da_members: HashMap>, + indexed_da_members: HashMap>, } impl EpochCommittees { @@ -162,28 +160,37 @@ impl EpochCommittees { // more subtlety when start fetching only the events since last update. let stake_table = st.stake_table.0.clone(); - let da_members = st.da_members.0.clone(); let indexed_stake_table: HashMap = st .stake_table .0 .iter() - .map(|entry| (PubKey::public_key(entry), entry.clone())) + .map(|peer_config| { + ( + PubKey::public_key(&peer_config.stake_table_entry), + peer_config.clone(), + ) + }) .collect(); let indexed_da_members: HashMap = st .da_members .0 .iter() - .map(|entry| (PubKey::public_key(entry), entry.clone())) + .map(|peer_config| { + ( + PubKey::public_key(&peer_config.stake_table_entry), + peer_config.clone(), + ) + }) .collect(); let eligible_leaders: Vec<_> = st .stake_table .0 .into_iter() - .filter(|entry| entry.stake() > U256::zero()) + .filter(|peer_config| peer_config.stake_table_entry.stake() > U256::zero()) .collect(); let committee = Committee { @@ -210,34 +217,44 @@ impl EpochCommittees { // For each eligible leader, get the stake table entry let eligible_leaders: Vec<_> = committee_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&peer_config| peer_config.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // For each member, get the stake table entry let stake_table: Vec<_> = committee_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&peer_config| peer_config.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // For each member, get the stake table entry let da_members: Vec<_> = da_members .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) + .filter(|&peer_config| peer_config.stake_table_entry.stake() > U256::zero()) + .cloned() .collect(); // Index the stake table by public key let indexed_stake_table: HashMap = stake_table .iter() - .map(|entry| (PubKey::public_key(entry), entry.clone())) + .map(|peer_config| { + ( + PubKey::public_key(&peer_config.stake_table_entry), + peer_config.clone(), + ) + }) .collect(); // Index the stake table by public key let indexed_da_members: HashMap = da_members .iter() - .map(|entry| (PubKey::public_key(entry), entry.clone())) + .map(|peer_config| { + ( + PubKey::public_key(&peer_config.stake_table_entry), + peer_config.clone(), + ) + }) .collect(); let members = Committee { @@ -279,73 +296,18 @@ pub struct LeaderLookupError; #[async_trait] impl Membership for EpochCommittees { type Error = LeaderLookupError; - // DO NOT USE. Dummy constructor to comply w/ trait. fn new( // TODO remove `new` from trait and remove this fn as well. // https://github.com/EspressoSystems/HotShot/commit/fcb7d54a4443e29d643b3bbc53761856aef4de8b - committee_members: Vec>, - da_members: Vec>, + _committee_members: Vec>, + _da_members: Vec>, ) -> Self { - // For each eligible leader, get the stake table entry - let eligible_leaders: Vec<_> = committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); - - // For each member, get the stake table entry - let stake_table: Vec<_> = committee_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); - - // For each member, get the stake table entry - let da_members: Vec<_> = da_members - .iter() - .map(|member| member.stake_table_entry.clone()) - .filter(|entry| entry.stake() > U256::zero()) - .collect(); - - // Index the stake table by public key - let indexed_stake_table: HashMap = stake_table - .iter() - .map(|entry| (PubKey::public_key(entry), entry.clone())) - .collect(); - - // Index the stake table by public key - let indexed_da_members: HashMap = da_members - .iter() - .map(|entry| (PubKey::public_key(entry), entry.clone())) - .collect(); - - let members = Committee { - eligible_leaders, - stake_table, - da_members, - indexed_stake_table, - indexed_da_members, - }; - - let mut map = HashMap::new(); - map.insert(Epoch::genesis(), members.clone()); - // TODO: remove this, workaround for hotshot asking for stake tables from epoch 1 - map.insert(Epoch::genesis() + 1u64, members.clone()); - - Self { - non_epoch_committee: members, - state: map, - _epoch_size: 12, - l1_client: L1Client::new(vec![Url::from_str("http:://ab.b").unwrap()]) - .expect("Failed to create L1 client"), - contract_address: None, - randomized_committees: BTreeMap::new(), - } + panic!("This function has been replaced with new_stake()"); } /// Get the stake table for the current view - fn stake_table(&self, epoch: Option) -> Vec> { + fn stake_table(&self, epoch: Option) -> Vec> { if let Some(st) = self.state(&epoch) { st.stake_table.clone() } else { @@ -353,7 +315,7 @@ impl Membership for EpochCommittees { } } /// Get the stake table for the current view - fn da_stake_table(&self, epoch: Option) -> Vec> { + fn da_stake_table(&self, epoch: Option) -> Vec> { if let Some(sc) = self.state(&epoch) { sc.da_members.clone() } else { @@ -397,19 +359,19 @@ impl Membership for EpochCommittees { .unwrap() .eligible_leaders .iter() - .map(PubKey::public_key) + .map(|x| PubKey::public_key(&x.stake_table_entry)) .collect() } /// Get the stake table entry for a public key - fn stake(&self, pub_key: &PubKey, epoch: Option) -> Option> { + fn stake(&self, pub_key: &PubKey, epoch: Option) -> Option> { // Only return the stake if it is above zero self.state(&epoch) .and_then(|h| h.indexed_stake_table.get(pub_key).cloned()) } /// Get the DA stake table entry for a public key - fn da_stake(&self, pub_key: &PubKey, epoch: Option) -> Option> { + fn da_stake(&self, pub_key: &PubKey, epoch: Option) -> Option> { // Only return the stake if it is above zero self.state(&epoch) .and_then(|h| h.indexed_da_members.get(pub_key).cloned()) @@ -419,14 +381,14 @@ impl Membership for EpochCommittees { fn has_stake(&self, pub_key: &PubKey, epoch: Option) -> bool { self.state(&epoch) .and_then(|h| h.indexed_stake_table.get(pub_key)) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Check if a node has stake in the committee fn has_da_stake(&self, pub_key: &PubKey, epoch: Option) -> bool { self.state(&epoch) .and_then(|h| h.indexed_da_members.get(pub_key)) - .is_some_and(|x| x.stake() > U256::zero()) + .is_some_and(|x| x.stake_table_entry.stake() > U256::zero()) } /// Index the vector of public keys with the current view number @@ -453,7 +415,7 @@ impl Membership for EpochCommittees { let index = *view_number as usize % leaders.len(); let res = leaders[index].clone(); - Ok(PubKey::public_key(&res)) + Ok(PubKey::public_key(&res.stake_table_entry)) } } @@ -524,8 +486,13 @@ impl Membership for EpochCommittees { return; }; - let randomized_committee = - generate_stake_cdf(raw_stake_table.eligible_leaders.clone(), drb); + let leaders = raw_stake_table + .eligible_leaders + .clone() + .into_iter() + .map(|peer_config| peer_config.stake_table_entry) + .collect::>(); + let randomized_committee = generate_stake_cdf(leaders, drb); self.randomized_committees .insert(epoch, randomized_committee); @@ -557,13 +524,19 @@ mod tests { // The DA stake table contains the DA node only assert_eq!(st.da_members.0.len(), 1); - assert_eq!(st.da_members.0[0].stake_key, da_node.stake_table_key); + assert_eq!( + st.da_members.0[0].stake_table_entry.stake_key, + da_node.stake_table_key + ); // The consensus stake table contains both nodes assert_eq!(st.stake_table.0.len(), 2); - assert_eq!(st.stake_table.0[0].stake_key, da_node.stake_table_key); assert_eq!( - st.stake_table.0[1].stake_key, + st.stake_table.0[0].stake_table_entry.stake_key, + da_node.stake_table_key + ); + assert_eq!( + st.stake_table.0[1].stake_table_entry.stake_key, consensus_node.stake_table_key ); @@ -580,13 +553,25 @@ mod tests { // The DA stake stable now contains both nodes assert_eq!(st.da_members.0.len(), 2); - assert_eq!(st.da_members.0[0].stake_key, da_node.stake_table_key); - assert_eq!(st.da_members.0[1].stake_key, new_da_node.stake_table_key); + assert_eq!( + st.da_members.0[0].stake_table_entry.stake_key, + da_node.stake_table_key + ); + assert_eq!( + st.da_members.0[1].stake_table_entry.stake_key, + new_da_node.stake_table_key + ); // The consensus stake stable (still) contains both nodes assert_eq!(st.stake_table.0.len(), 2); - assert_eq!(st.stake_table.0[0].stake_key, da_node.stake_table_key); - assert_eq!(st.stake_table.0[1].stake_key, new_da_node.stake_table_key); + assert_eq!( + st.stake_table.0[0].stake_table_entry.stake_key, + da_node.stake_table_key + ); + assert_eq!( + st.stake_table.0[1].stake_table_entry.stake_key, + new_da_node.stake_table_key + ); // Simulate removing the second node updates.push(StakersUpdated { @@ -597,11 +582,17 @@ mod tests { // The DA stake table contains only the original DA node assert_eq!(st.da_members.0.len(), 1); - assert_eq!(st.da_members.0[0].stake_key, da_node.stake_table_key); + assert_eq!( + st.da_members.0[0].stake_table_entry.stake_key, + da_node.stake_table_key + ); // The consensus stake table also contains only the original DA node assert_eq!(st.stake_table.0.len(), 1); - assert_eq!(st.stake_table.0[0].stake_key, da_node.stake_table_key); + assert_eq!( + st.stake_table.0[0].stake_table_entry.stake_key, + da_node.stake_table_key + ); } // TODO: test that repeatedly removes and adds more nodes diff --git a/types/src/v0/v0_3/stake_table.rs b/types/src/v0/v0_3/stake_table.rs index 336093f3a1..a8027869ce 100644 --- a/types/src/v0/v0_3/stake_table.rs +++ b/types/src/v0/v0_3/stake_table.rs @@ -1,7 +1,7 @@ use crate::PubKey; use derive_more::derive::{From, Into}; use hotshot_contract_adapter::stake_table::NodeInfoJf; -use hotshot_types::{network::PeerConfigKeys, stake_table::StakeTableEntry}; +use hotshot_types::{network::PeerConfigKeys, PeerConfig}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, From)] @@ -13,11 +13,11 @@ pub struct CombinedStakeTable(Vec>); #[derive(Clone, Debug, From, Into)] /// NewType to disambiguate DA Membership -pub struct DAMembers(pub Vec>); +pub struct DAMembers(pub Vec>); #[derive(Clone, Debug, From, Into)] /// NewType to disambiguate StakeTable -pub struct StakeTable(pub Vec>); +pub struct StakeTable(pub Vec>); #[derive(Clone, Debug)] pub struct StakeTables {