Skip to content

Commit 51714ea

Browse files
committed
load da_committee from genesis file
1 parent ba5a1ba commit 51714ea

File tree

11 files changed

+126
-10
lines changed

11 files changed

+126
-10
lines changed

crates/builder/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ pub mod testing {
120120
let config: HotShotConfig<SeqTypes> = HotShotConfig {
121121
num_nodes_with_stake: NonZeroUsize::new(num_nodes_with_stake).unwrap(),
122122
known_da_nodes: known_nodes_with_stake.clone(),
123+
da_committees: Default::default(),
123124
known_nodes_with_stake: known_nodes_with_stake.clone(),
124125
next_view_timeout: Duration::from_secs(5).as_millis() as u64,
125126
num_bootstrap: 1usize,

crates/builder/src/non_permissioned.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn build_instance_state<V: Versions>(
6666
let coordinator = EpochMembershipCoordinator::new(
6767
Arc::new(RwLock::new(EpochCommittees::new_stake(
6868
vec![],
69-
vec![],
69+
Default::default(),
7070
None,
7171
fetcher,
7272
genesis.epoch_height.unwrap_or_default(),

crates/hotshot/testing/src/test_builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub fn default_hotshot_config<TYPES: NodeType>(
7070
start_threshold: (1, 1),
7171
num_nodes_with_stake: NonZeroUsize::new(known_nodes_with_stake.len()).unwrap(),
7272
known_da_nodes: known_da_nodes.clone(),
73+
da_committees: Default::default(),
7374
num_bootstrap: num_bootstrap_nodes,
7475
known_nodes_with_stake: known_nodes_with_stake.clone(),
7576
da_staked_committee_size: known_da_nodes.len(),

crates/hotshot/types/src/hotshot_config_file.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// You should have received a copy of the MIT License
55
// along with the HotShot repository. If not, see <https://mit-license.org/>.
66

7-
use std::{num::NonZeroUsize, time::Duration};
7+
use std::{collections::BTreeMap, num::NonZeroUsize, time::Duration};
88

99
use alloy::primitives::U256;
1010
use url::Url;
@@ -45,6 +45,8 @@ pub struct HotShotConfigFile<TYPES: NodeType> {
4545
#[serde(skip)]
4646
/// The known DA nodes' public key and stake values
4747
pub known_da_nodes: Vec<PeerConfig<TYPES>>,
48+
/// The known DA nodes' public keys and stake values, by start epoch
49+
pub da_committees: BTreeMap<u64, Vec<PeerConfig<TYPES>>>,
4850
/// Number of staking DA nodes
4951
pub staked_da_nodes: usize,
5052
/// Number of fixed leaders for GPU VID
@@ -89,6 +91,7 @@ impl<TYPES: NodeType> From<HotShotConfigFile<TYPES>> for HotShotConfig<TYPES> {
8991
start_threshold: val.start_threshold,
9092
num_nodes_with_stake: val.num_nodes_with_stake,
9193
known_da_nodes: val.known_da_nodes,
94+
da_committees: val.da_committees,
9295
known_nodes_with_stake: val.known_nodes_with_stake,
9396
da_staked_committee_size: val.staked_da_nodes,
9497
fixed_leader_for_gpuvid: val.fixed_leader_for_gpuvid,
@@ -154,6 +157,7 @@ impl<TYPES: NodeType> HotShotConfigFile<TYPES> {
154157
known_nodes_with_stake: gen_known_nodes_with_stake,
155158
staked_da_nodes,
156159
known_da_nodes,
160+
da_committees: Default::default(),
157161
fixed_leader_for_gpuvid: 1,
158162
next_view_timeout: 10000,
159163
view_sync_timeout: Duration::from_millis(1000),

crates/hotshot/types/src/lib.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
// along with the HotShot repository. If not, see <https://mit-license.org/>.
66

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

1012
use alloy::primitives::U256;
1113
use bincode::Options;
@@ -19,7 +21,7 @@ use traits::{
1921
use url::Url;
2022
use vec1::Vec1;
2123

22-
use crate::utils::bincode_opts;
24+
use crate::{traits::node_implementation::ConsensusTime, utils::bincode_opts};
2325
pub mod bundle;
2426
pub mod consensus;
2527
pub mod constants;
@@ -195,6 +197,8 @@ pub struct HotShotConfig<TYPES: NodeType> {
195197
pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
196198
/// All public keys known to be DA nodes
197199
pub known_da_nodes: Vec<PeerConfig<TYPES>>,
200+
/// All public keys known to be DA nodes, by start epoch
201+
pub da_committees: BTreeMap<u64, Vec<PeerConfig<TYPES>>>,
198202
/// List of DA committee (staking)nodes for static DA committee
199203
pub da_staked_committee_size: usize,
200204
/// Number of fixed leaders for GPU VID, normally it will be 0, it's only used when running GPU VID
@@ -266,4 +270,26 @@ impl<TYPES: NodeType> HotShotConfig<TYPES> {
266270
pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
267271
self.known_nodes_with_stake.clone().into()
268272
}
273+
274+
pub fn build_da_committees(&self) -> BTreeMap<TYPES::Epoch, Vec<PeerConfig<TYPES>>> {
275+
if self.da_committees.is_empty() {
276+
tracing::warn!(
277+
"da_committees is not set, falling back to known_da_nodes, which is deprecated."
278+
);
279+
280+
[(TYPES::Epoch::new(0), self.known_da_nodes.clone())].into()
281+
} else {
282+
if !self.known_da_nodes.is_empty() {
283+
tracing::warn!(
284+
"Both known_da_nodes and da_committees are set, known_da_nodes is deprecated \
285+
and will be ignored."
286+
);
287+
}
288+
289+
self.da_committees
290+
.iter()
291+
.map(|(k, v)| (TYPES::Epoch::new(*k), v.clone()))
292+
.collect()
293+
}
294+
}
269295
}

hotshot-query-service/src/testing/consensus.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ impl<D: DataSourceLifeCycle + UpdateStatusData, V: Versions> MockNetwork<D, V> {
141141
num_bootstrap: 0,
142142
da_staked_committee_size: pub_keys.len(),
143143
known_da_nodes: known_nodes_with_stake.clone(),
144+
da_committees: Default::default(),
144145
data_request_delay: Duration::from_millis(200),
145146
view_sync_timeout: Duration::from_millis(250),
146147
start_threshold: (

sequencer/src/genesis.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use std::{
66
use alloy::primitives::Address;
77
use anyhow::{Context, Ok};
88
use espresso_types::{
9-
v0_3::ChainConfig, FeeAccount, FeeAmount, GenesisHeader, L1BlockInfo, L1Client, Timestamp,
10-
Upgrade,
9+
v0_3::ChainConfig, FeeAccount, FeeAmount, GenesisHeader, L1BlockInfo, L1Client, SeqTypes,
10+
Timestamp, Upgrade,
1111
};
12+
use hotshot_types::traits::node_implementation::NodeType;
1213
use serde::{Deserialize, Serialize};
1314
use vbs::version::Version;
1415

@@ -44,6 +45,48 @@ pub enum L1Finalized {
4445
Timestamp { timestamp: Timestamp },
4546
}
4647

48+
/// Helper type to deal with TOML keys that are u64 but represented as strings
49+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
50+
pub struct TomlKeyU64(u64);
51+
52+
impl<'de> Deserialize<'de> for TomlKeyU64 {
53+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
54+
where
55+
D: serde::Deserializer<'de>,
56+
{
57+
tracing::warn!("Using TomlKeyU64::deserialize");
58+
let s = String::deserialize(deserializer)?;
59+
60+
let n = s
61+
.parse::<u64>()
62+
.map_err(|_| serde::de::Error::custom("invalid epoch"))?;
63+
64+
std::result::Result::Ok(TomlKeyU64(n))
65+
}
66+
}
67+
68+
impl Serialize for TomlKeyU64 {
69+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70+
where
71+
S: serde::Serializer,
72+
{
73+
serializer.serialize_str(&self.0.to_string())
74+
}
75+
}
76+
77+
impl Into<u64> for &TomlKeyU64 {
78+
fn into(self) -> u64 {
79+
self.0
80+
}
81+
}
82+
83+
#[derive(Clone, Debug, Deserialize, Serialize)]
84+
pub struct PeerConfigData {
85+
pub stake_table_key: <SeqTypes as NodeType>::SignatureKey,
86+
pub state_ver_key: <SeqTypes as NodeType>::StateSignatureKey,
87+
pub stake: u64,
88+
}
89+
4790
/// Genesis of an Espresso chain.
4891
#[derive(Clone, Debug, Deserialize, Serialize)]
4992
pub struct Genesis {
@@ -67,6 +110,7 @@ pub struct Genesis {
67110
#[serde(rename = "upgrade", with = "upgrade_ser")]
68111
#[serde(default)]
69112
pub upgrades: BTreeMap<Version, Upgrade>,
113+
pub da_committees: Option<BTreeMap<TomlKeyU64, Vec<PeerConfigData>>>,
70114
}
71115

72116
impl Genesis {

sequencer/src/lib.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ use hotshot_types::{
5757
epoch_membership::EpochMembershipCoordinator,
5858
light_client::{StateKeyPair, StateSignKey},
5959
signature_key::{BLSPrivKey, BLSPubKey},
60+
stake_table::StakeTableEntry,
6061
traits::{
6162
metrics::{Metrics, NoMetrics},
6263
network::ConnectedNetwork,
@@ -390,6 +391,27 @@ where
390391
network_config.config.epoch_start_block = epoch_start_block;
391392
network_config.config.stake_table_capacity = stake_table_capacity;
392393

394+
if let Some(da_committees) = &genesis.da_committees {
395+
tracing::warn!("setting da_committees from genesis");
396+
network_config.config.da_committees = da_committees
397+
.iter()
398+
.map(|(k, v)| {
399+
(
400+
k.into(),
401+
v.iter()
402+
.map(|pcd| hotshot_types::PeerConfig {
403+
stake_table_entry: StakeTableEntry {
404+
stake_key: pcd.stake_table_key,
405+
stake_amount: U256::from(pcd.stake),
406+
},
407+
state_ver_key: pcd.state_ver_key.clone(),
408+
})
409+
.collect(),
410+
)
411+
})
412+
.collect();
413+
}
414+
393415
// If the `Libp2p` bootstrap nodes were supplied via the command line, override those
394416
// present in the config file.
395417
if let Some(bootstrap_nodes) = network_params.libp2p_bootstrap_nodes {
@@ -529,7 +551,7 @@ where
529551
// Create the HotShot membership
530552
let mut membership = EpochCommittees::new_stake(
531553
network_config.config.known_nodes_with_stake.clone(),
532-
network_config.config.known_da_nodes.clone(),
554+
network_config.config.build_da_committees(),
533555
block_reward,
534556
fetcher,
535557
epoch_height,

types/src/v0/config.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{num::NonZeroUsize, time::Duration};
1+
use std::{collections::BTreeMap, num::NonZeroUsize, time::Duration};
22

33
use hotshot_types::{
44
network::{
@@ -55,6 +55,7 @@ pub struct PublicHotShotConfig {
5555
num_nodes_with_stake: NonZeroUsize,
5656
known_nodes_with_stake: Vec<PeerConfig<SeqTypes>>,
5757
known_da_nodes: Vec<PeerConfig<SeqTypes>>,
58+
da_committees: BTreeMap<u64, Vec<PeerConfig<SeqTypes>>>,
5859
da_staked_committee_size: usize,
5960
fixed_leader_for_gpuvid: usize,
6061
next_view_timeout: u64,
@@ -105,6 +106,7 @@ impl From<HotShotConfig<SeqTypes>> for PublicHotShotConfig {
105106
num_nodes_with_stake,
106107
known_nodes_with_stake,
107108
known_da_nodes,
109+
da_committees,
108110
da_staked_committee_size,
109111
fixed_leader_for_gpuvid,
110112
next_view_timeout,
@@ -133,6 +135,7 @@ impl From<HotShotConfig<SeqTypes>> for PublicHotShotConfig {
133135
num_nodes_with_stake,
134136
known_nodes_with_stake,
135137
known_da_nodes,
138+
da_committees,
136139
da_staked_committee_size,
137140
fixed_leader_for_gpuvid,
138141
next_view_timeout,
@@ -165,6 +168,7 @@ impl PublicHotShotConfig {
165168
num_nodes_with_stake: self.num_nodes_with_stake,
166169
known_nodes_with_stake: self.known_nodes_with_stake,
167170
known_da_nodes: self.known_da_nodes,
171+
da_committees: self.da_committees,
168172
da_staked_committee_size: self.da_staked_committee_size,
169173
fixed_leader_for_gpuvid: self.fixed_leader_for_gpuvid,
170174
next_view_timeout: self.next_view_timeout,
@@ -196,9 +200,15 @@ impl PublicHotShotConfig {
196200
pub fn known_da_nodes(&self) -> Vec<PeerConfig<SeqTypes>> {
197201
self.known_da_nodes.clone()
198202
}
203+
204+
pub fn da_committees(&self) -> BTreeMap<u64, Vec<PeerConfig<SeqTypes>>> {
205+
self.da_committees.clone()
206+
}
207+
199208
pub fn blocks_per_epoch(&self) -> u64 {
200209
self.epoch_height
201210
}
211+
202212
pub fn epoch_start_block(&self) -> u64 {
203213
self.epoch_start_block
204214
}

types/src/v0/impls/stake_table.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1689,11 +1689,18 @@ impl EpochCommittees {
16891689
// TODO remove `new` from trait and rename this to `new`.
16901690
// https://github.com/EspressoSystems/HotShot/commit/fcb7d54a4443e29d643b3bbc53761856aef4de8b
16911691
committee_members: Vec<PeerConfig<SeqTypes>>,
1692-
da_members: Vec<PeerConfig<SeqTypes>>,
1692+
da_committees: BTreeMap<Epoch, Vec<PeerConfig<SeqTypes>>>,
16931693
fixed_block_reward: Option<RewardAmount>,
16941694
fetcher: Fetcher,
16951695
epoch_height: u64,
16961696
) -> Self {
1697+
// TODO: Store da_committees in EpochCommittees. Currently we just pull da_members back out, but we
1698+
// will need to figure out how to integrate da_committees into EpochCommittee and the like.
1699+
let da_members = da_committees
1700+
.get(&Epoch::new(0))
1701+
.cloned()
1702+
.expect("Should always have an epoch 0 DA committee");
1703+
16971704
// For each member, get the stake table entry
16981705
let stake_table: Vec<_> = committee_members
16991706
.iter()

0 commit comments

Comments
 (0)