Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub mod testing {
let config: HotShotConfig<SeqTypes> = HotShotConfig {
num_nodes_with_stake: NonZeroUsize::new(num_nodes_with_stake).unwrap(),
known_da_nodes: known_nodes_with_stake.clone(),
da_committees: Default::default(),
known_nodes_with_stake: known_nodes_with_stake.clone(),
next_view_timeout: Duration::from_secs(5).as_millis() as u64,
num_bootstrap: 1usize,
Expand Down
2 changes: 1 addition & 1 deletion crates/builder/src/non_permissioned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub fn build_instance_state<V: Versions>(
let coordinator = EpochMembershipCoordinator::new(
Arc::new(RwLock::new(EpochCommittees::new_stake(
vec![],
vec![],
Default::default(),
None,
fetcher,
genesis.epoch_height.unwrap_or_default(),
Expand Down
42 changes: 42 additions & 0 deletions crates/hotshot/task-impls/src/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use hotshot_types::{
simple_vote::{UpgradeProposalData, UpgradeVote},
traits::{
block_contents::BlockHeader,
election::Membership,
node_implementation::{ConsensusTime, NodeType, Versions},
signature_key::SignatureKey,
},
Expand Down Expand Up @@ -450,3 +451,44 @@ impl<TYPES: NodeType, V: Versions> TaskState for UpgradeTaskState<TYPES, V> {

fn cancel_subtasks(&mut self) {}
}

// Test function. This doesn't belong here. Should be called once we accept an upgrade.
async fn slice_membership_da_committees_for_upgrade<TYPES: NodeType>(
cur_epoch: Epoch,
version: Version,
da_committees: &BTreeMap<Version, BTreeMap<u64, Vec<PeerConfig<TYPES>>>>,
membership: &mut dyn Membership<TYPES>, // Needs to go through EpochMembershipCoordinator
) {
if version < RotatingDaCommitteeVersion::VERSION {
return; // We aren't ready to start adding DA committees yet
}

let Some(committees) = da_committees.get(&version) else {
return; // No new da committees for this version
};

//let mut res = committees.range(cur_epoch + 1..).collect();
let mut res = BTreeMap::new();

for (epoch, committee) in committees.iter().reverse() {
if *epoch <= cur_epoch {
// We only want future epochs.
let should_add = if let Some((&k, _)) = res.first_key_value() {
k > cur_epoch + 1 // We should add an extra epoch if there's space between (cur_epoch + 1) and the next da_committee epoch
} else {
true
};

if should_add {
// This allows for the case where we transitioned into a new version partway into
// the defined epochs for that version.
res.insert(cur_epoch + 1, committee.clone());
}

break;
}
res.insert(*epoch, committee.clone());
}

membership.write().await.update_da_committees(res);
}
1 change: 1 addition & 0 deletions crates/hotshot/testing/src/test_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub fn default_hotshot_config<TYPES: NodeType>(
start_threshold: (1, 1),
num_nodes_with_stake: NonZeroUsize::new(known_nodes_with_stake.len()).unwrap(),
known_da_nodes: known_da_nodes.clone(),
da_committees: Default::default(),
num_bootstrap: num_bootstrap_nodes,
known_nodes_with_stake: known_nodes_with_stake.clone(),
da_staked_committee_size: known_da_nodes.len(),
Expand Down
8 changes: 7 additions & 1 deletion crates/hotshot/types/src/hotshot_config_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
// You should have received a copy of the MIT License
// along with the HotShot repository. If not, see <https://mit-license.org/>.

use std::{num::NonZeroUsize, time::Duration};
use std::{collections::BTreeMap, num::NonZeroUsize, time::Duration};

use alloy::primitives::U256;
use url::Url;
use vbs::version::Version;
use vec1::Vec1;

use crate::{
Expand Down Expand Up @@ -45,6 +46,9 @@ pub struct HotShotConfigFile<TYPES: NodeType> {
#[serde(skip)]
/// The known DA nodes' public key and stake values
pub known_da_nodes: Vec<PeerConfig<TYPES>>,
#[serde(skip)]
/// The known DA nodes' public keys and stake values, by start epoch
pub da_committees: BTreeMap<Version, BTreeMap<u64, Vec<PeerConfig<TYPES>>>>,
/// Number of staking DA nodes
pub staked_da_nodes: usize,
/// Number of fixed leaders for GPU VID
Expand Down Expand Up @@ -89,6 +93,7 @@ impl<TYPES: NodeType> From<HotShotConfigFile<TYPES>> for HotShotConfig<TYPES> {
start_threshold: val.start_threshold,
num_nodes_with_stake: val.num_nodes_with_stake,
known_da_nodes: val.known_da_nodes,
da_committees: val.da_committees,
known_nodes_with_stake: val.known_nodes_with_stake,
da_staked_committee_size: val.staked_da_nodes,
fixed_leader_for_gpuvid: val.fixed_leader_for_gpuvid,
Expand Down Expand Up @@ -154,6 +159,7 @@ impl<TYPES: NodeType> HotShotConfigFile<TYPES> {
known_nodes_with_stake: gen_known_nodes_with_stake,
staked_da_nodes,
known_da_nodes,
da_committees: Default::default(),
fixed_leader_for_gpuvid: 1,
next_view_timeout: 10000,
view_sync_timeout: Duration::from_millis(1000),
Expand Down
14 changes: 13 additions & 1 deletion crates/hotshot/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
// along with the HotShot repository. If not, see <https://mit-license.org/>.

//! Types and Traits for the `HotShot` consensus module
use std::{fmt::Debug, future::Future, num::NonZeroUsize, pin::Pin, time::Duration};
use std::{
collections::BTreeMap, fmt::Debug, future::Future, num::NonZeroUsize, pin::Pin, time::Duration,
};

use alloy::primitives::U256;
use bincode::Options;
Expand All @@ -17,6 +19,7 @@ use traits::{
signature_key::{SignatureKey, StateSignatureKey},
};
use url::Url;
use vbs::version::Version;
use vec1::Vec1;

use crate::utils::bincode_opts;
Expand Down Expand Up @@ -195,6 +198,8 @@ pub struct HotShotConfig<TYPES: NodeType> {
pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
/// All public keys known to be DA nodes
pub known_da_nodes: Vec<PeerConfig<TYPES>>,
/// All public keys known to be DA nodes, by start epoch
pub da_committees: BTreeMap<Version, BTreeMap<u64, Vec<PeerConfig<TYPES>>>>,
/// List of DA committee (staking)nodes for static DA committee
pub da_staked_committee_size: usize,
/// Number of fixed leaders for GPU VID, normally it will be 0, it's only used when running GPU VID
Expand Down Expand Up @@ -266,4 +271,11 @@ impl<TYPES: NodeType> HotShotConfig<TYPES> {
pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
self.known_nodes_with_stake.clone().into()
}

pub fn build_da_committees(&self) -> Vec<PeerConfig<TYPES>> {
// TODO: THIS IS A TEMPORARY FIX WITH THE WRONG RETURN TYPE.
// It's done so that we can start using this function and have the existing behavior
// (use known_da_nodes) while we transition to using da_committees.
self.known_da_nodes.clone()
}
}
14 changes: 13 additions & 1 deletion crates/hotshot/types/src/traits/election.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
// along with the HotShot repository. If not, see <https://mit-license.org/>.

//! The election trait, used to decide which node is the leader and determine if a vote is valid.
use std::{collections::BTreeSet, fmt::Debug, sync::Arc};
use std::{
collections::{BTreeMap, BTreeSet},
fmt::Debug,
sync::Arc,
};

use alloy::primitives::U256;
use async_lock::RwLock;
use committable::{Commitment, Committable};
use hotshot_utils::anytrace::Result;
use vbs::version::Version;

use super::node_implementation::NodeType;
use crate::{
Expand Down Expand Up @@ -199,6 +204,13 @@ pub trait Membership<TYPES: NodeType>: Debug + Send + Sync {
fn stake_table_hash(&self, _epoch: TYPES::Epoch) -> Option<Commitment<Self::StakeTableHash>> {
None
}

fn update_da_committees(
&mut self,
da_committees: BTreeMap<TYPES::Epoch, Vec<PeerConfig<TYPES>>>,
) {
// TODO: Make this not defaulted
}
}

pub fn membership_spawn_add_epoch_root<TYPES: NodeType>(
Expand Down
1 change: 1 addition & 0 deletions hotshot-query-service/examples/simple-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ async fn init_consensus(
next_view_timeout: 10000,
num_bootstrap: 0,
known_da_nodes: known_nodes_with_stake.clone(),
da_committees: Default::default(),
da_staked_committee_size: pub_keys.len(),
data_request_delay: Duration::from_millis(200),
view_sync_timeout: Duration::from_millis(250),
Expand Down
1 change: 1 addition & 0 deletions hotshot-query-service/src/testing/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ impl<D: DataSourceLifeCycle + UpdateStatusData, V: Versions> MockNetwork<D, V> {
num_bootstrap: 0,
da_staked_committee_size: pub_keys.len(),
known_da_nodes: known_nodes_with_stake.clone(),
da_committees: Default::default(),
data_request_delay: Duration::from_millis(200),
view_sync_timeout: Duration::from_millis(250),
start_threshold: (
Expand Down
49 changes: 47 additions & 2 deletions sequencer/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use std::{
use alloy::primitives::Address;
use anyhow::{Context, Ok};
use espresso_types::{
v0_3::ChainConfig, FeeAccount, FeeAmount, GenesisHeader, L1BlockInfo, L1Client, Timestamp,
Upgrade,
v0_3::ChainConfig, FeeAccount, FeeAmount, GenesisHeader, L1BlockInfo, L1Client, SeqTypes,
Timestamp, Upgrade,
};
use hotshot_types::traits::node_implementation::NodeType;
use serde::{Deserialize, Serialize};
use vbs::version::Version;

Expand Down Expand Up @@ -44,6 +45,48 @@ pub enum L1Finalized {
Timestamp { timestamp: Timestamp },
}

/// Helper type to deal with TOML keys that are u64 but represented as strings
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TomlKeyU64(u64);

impl<'de> Deserialize<'de> for TomlKeyU64 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
tracing::warn!("Using TomlKeyU64::deserialize");
let s = String::deserialize(deserializer)?;

let n = s
.parse::<u64>()
.map_err(|_| serde::de::Error::custom("invalid epoch"))?;

std::result::Result::Ok(TomlKeyU64(n))
}
}

impl Serialize for TomlKeyU64 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.0.to_string())
}
}

impl From<&TomlKeyU64> for u64 {
fn from(val: &TomlKeyU64) -> Self {
val.0
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PeerConfigData {
pub stake_table_key: <SeqTypes as NodeType>::SignatureKey,
pub state_ver_key: <SeqTypes as NodeType>::StateSignatureKey,
pub stake: u64,
}

/// Genesis of an Espresso chain.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Genesis {
Expand All @@ -67,6 +110,8 @@ pub struct Genesis {
#[serde(rename = "upgrade", with = "upgrade_ser")]
#[serde(default)]
pub upgrades: BTreeMap<Version, Upgrade>,
#[serde(default)]
pub da_committees: Option<BTreeMap<Version, BTreeMap<TomlKeyU64, Vec<PeerConfigData>>>>,
}

impl Genesis {
Expand Down
34 changes: 32 additions & 2 deletions sequencer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ use hotshot_types::{
epoch_membership::EpochMembershipCoordinator,
light_client::{StateKeyPair, StateSignKey},
signature_key::{BLSPrivKey, BLSPubKey},
stake_table::StakeTableEntry,
traits::{
metrics::{Metrics, NoMetrics},
network::ConnectedNetwork,
Expand Down Expand Up @@ -390,6 +391,34 @@ where
network_config.config.epoch_start_block = epoch_start_block;
network_config.config.stake_table_capacity = stake_table_capacity;

if let Some(da_committees) = &genesis.da_committees {
tracing::warn!("setting da_committees from genesis");
network_config.config.da_committees = da_committees
.iter()
.map(|(k, v)| {
(
*k,
v.iter()
.map(|(k, v)| {
(
k.into(),
v.iter()
.map(|pcd| hotshot_types::PeerConfig {
stake_table_entry: StakeTableEntry {
stake_key: pcd.stake_table_key,
stake_amount: U256::from(pcd.stake),
},
state_ver_key: pcd.state_ver_key.clone(),
})
.collect(),
)
})
.collect(),
)
})
.collect();
}

// If the `Libp2p` bootstrap nodes were supplied via the command line, override those
// present in the config file.
if let Some(bootstrap_nodes) = network_params.libp2p_bootstrap_nodes {
Expand Down Expand Up @@ -529,7 +558,7 @@ where
// Create the HotShot membership
let mut membership = EpochCommittees::new_stake(
network_config.config.known_nodes_with_stake.clone(),
network_config.config.known_da_nodes.clone(),
network_config.config.build_da_committees(),
block_reward,
fetcher,
epoch_height,
Expand Down Expand Up @@ -1020,6 +1049,7 @@ pub mod testing {
fixed_leader_for_gpuvid: 0,
num_nodes_with_stake: num_nodes.try_into().unwrap(),
known_da_nodes: known_nodes_with_stake.clone(),
da_committees: Default::default(),
known_nodes_with_stake: known_nodes_with_stake.clone(),
next_view_timeout: Duration::from_secs(5).as_millis() as u64,
num_bootstrap: 1usize,
Expand Down Expand Up @@ -1269,7 +1299,7 @@ pub mod testing {
let block_reward = fetcher.fetch_fixed_block_reward().await.ok();
let mut membership = EpochCommittees::new_stake(
config.known_nodes_with_stake.clone(),
config.known_da_nodes.clone(),
config.build_da_committees(),
block_reward,
fetcher,
config.epoch_height,
Expand Down
1 change: 1 addition & 0 deletions sequencer/src/restart_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ impl TestNetwork {
.into_iter()
.collect(),
genesis_version: Version { major: 0, minor: 1 },
da_committees: None,
};

let node_params = (0..da_nodes + regular_nodes)
Expand Down
1 change: 1 addition & 0 deletions sequencer/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ mod test {
epoch_start_block: None,
stake_table_capacity: None,
genesis_version: Version { major: 0, minor: 1 },
da_committees: None,
};
genesis.to_file(&genesis_file).unwrap();

Expand Down
Loading
Loading