1use std::{fmt::Debug, future::Future, num::NonZeroUsize, pin::Pin, time::Duration};
9
10use alloy::primitives::U256;
11use bincode::Options;
12use displaydoc::Display;
13use stake_table::HSStakeTable;
14use tracing::error;
15use traits::{
16 node_implementation::NodeType,
17 signature_key::{SignatureKey, StateSignatureKey},
18};
19use url::Url;
20use vbs::version::Version;
21use vec1::Vec1;
22
23use crate::utils::bincode_opts;
24pub mod bundle;
25pub mod consensus;
26pub mod constants;
27pub mod data;
28pub mod drb;
30pub mod epoch_membership;
32pub mod error;
33pub mod event;
34pub mod hotshot_config_file;
36pub mod light_client;
37pub mod message;
38
39pub mod network;
41pub mod qc;
42pub mod request_response;
43pub mod signature_key;
44pub mod simple_certificate;
45pub mod simple_vote;
46pub mod stake_table;
47pub mod traits;
48
49pub mod storage_metrics;
50pub mod upgrade_config;
52pub mod utils;
53pub mod vid;
54pub mod vote;
55
56pub type BoxSyncFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
58
59pub fn assert_future<T, F>(future: F) -> F
61where
62 F: Future<Output = T>,
63{
64 future
65}
66pub fn boxed_sync<'a, F>(fut: F) -> BoxSyncFuture<'a, F::Output>
68where
69 F: Future + Sized + Send + Sync + 'a,
70{
71 assert_future::<F::Output, _>(Box::pin(fut))
72}
73
74#[derive(Clone, Debug, Display)]
75pub struct ValidatorConfig<TYPES: NodeType> {
77 pub public_key: TYPES::SignatureKey,
79 pub private_key: <TYPES::SignatureKey as SignatureKey>::PrivateKey,
81 pub stake_value: U256,
83 pub state_public_key: TYPES::StateSignatureKey,
85 pub state_private_key: <TYPES::StateSignatureKey as StateSignatureKey>::StatePrivateKey,
87 pub is_da: bool,
89}
90
91impl<TYPES: NodeType> ValidatorConfig<TYPES> {
92 #[must_use]
94 pub fn generated_from_seed_indexed(
95 seed: [u8; 32],
96 index: u64,
97 stake_value: U256,
98 is_da: bool,
99 ) -> Self {
100 let (public_key, private_key) =
101 TYPES::SignatureKey::generated_from_seed_indexed(seed, index);
102 let (state_public_key, state_private_key) =
103 TYPES::StateSignatureKey::generated_from_seed_indexed(seed, index);
104 Self {
105 public_key,
106 private_key,
107 stake_value,
108 state_public_key,
109 state_private_key,
110 is_da,
111 }
112 }
113
114 pub fn public_config(&self) -> PeerConfig<TYPES> {
116 PeerConfig {
117 stake_table_entry: self.public_key.stake_table_entry(self.stake_value),
118 state_ver_key: self.state_public_key.clone(),
119 }
120 }
121}
122
123impl<TYPES: NodeType> Default for ValidatorConfig<TYPES> {
124 fn default() -> Self {
125 Self::generated_from_seed_indexed([0u8; 32], 0, U256::from(1), true)
126 }
127}
128
129#[derive(serde::Serialize, serde::Deserialize, Clone, Display, PartialEq, Eq, Hash)]
130#[serde(bound(deserialize = ""))]
131pub struct PeerConfig<TYPES: NodeType> {
133 pub stake_table_entry: <TYPES::SignatureKey as SignatureKey>::StakeTableEntry,
136 pub state_ver_key: TYPES::StateSignatureKey,
139}
140
141impl<TYPES: NodeType> PeerConfig<TYPES> {
142 pub fn to_bytes(config: &Self) -> Vec<u8> {
144 let x = bincode_opts().serialize(config);
145 match x {
146 Ok(x) => x,
147 Err(e) => {
148 error!(?e, "Failed to serialize public key");
149 vec![]
150 },
151 }
152 }
153
154 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
158 let x: Result<PeerConfig<TYPES>, _> = bincode_opts().deserialize(bytes);
159 match x {
160 Ok(pub_key) => Some(pub_key),
161 Err(e) => {
162 error!(?e, "Failed to deserialize public key");
163 None
164 },
165 }
166 }
167}
168
169impl<TYPES: NodeType> Default for PeerConfig<TYPES> {
170 fn default() -> Self {
171 let default_validator_config = ValidatorConfig::<TYPES>::default();
172 default_validator_config.public_config()
173 }
174}
175
176impl<TYPES: NodeType> Debug for PeerConfig<TYPES> {
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 f.debug_struct("PeerConfig")
179 .field("stake_table_entry", &self.stake_table_entry)
180 .field("state_ver_key", &format_args!("{}", self.state_ver_key))
181 .finish()
182 }
183}
184
185#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
186#[serde(bound(deserialize = ""))]
187pub struct VersionedDaCommittee<TYPES: NodeType> {
188 #[serde(with = "version_ser")]
189 pub start_version: Version,
190 pub start_epoch: u64,
191 pub committee: Vec<PeerConfig<TYPES>>,
192}
193
194#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
196#[serde(bound(deserialize = ""))]
197pub struct HotShotConfig<TYPES: NodeType> {
198 pub start_threshold: (u64, u64),
201 pub num_nodes_with_stake: NonZeroUsize,
204 pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
206 pub known_da_nodes: Vec<PeerConfig<TYPES>>,
208 pub da_committees: Vec<VersionedDaCommittee<TYPES>>,
210 pub da_staked_committee_size: usize,
212 pub fixed_leader_for_gpuvid: usize,
214 pub next_view_timeout: u64,
216 pub view_sync_timeout: Duration,
218 pub num_bootstrap: usize,
220 pub builder_timeout: Duration,
222 pub data_request_delay: Duration,
224 pub builder_urls: Vec1<Url>,
226 pub start_proposing_view: u64,
228 pub stop_proposing_view: u64,
230 pub start_voting_view: u64,
232 pub stop_voting_view: u64,
234 pub start_proposing_time: u64,
236 pub stop_proposing_time: u64,
238 pub start_voting_time: u64,
240 pub stop_voting_time: u64,
242 pub epoch_height: u64,
244 #[serde(default = "default_epoch_start_block")]
246 pub epoch_start_block: u64,
247 #[serde(default = "default_stake_table_capacity")]
249 pub stake_table_capacity: usize,
250 pub drb_difficulty: u64,
252 pub drb_upgrade_difficulty: u64,
254}
255
256fn default_epoch_start_block() -> u64 {
257 1
258}
259
260fn default_stake_table_capacity() -> usize {
261 crate::light_client::DEFAULT_STAKE_TABLE_CAPACITY
262}
263
264impl<TYPES: NodeType> HotShotConfig<TYPES> {
265 pub fn set_view_upgrade(&mut self, view: u64) {
267 self.start_proposing_view = view;
268 self.stop_proposing_view = view + 1;
269 self.start_voting_view = view.saturating_sub(1);
270 self.stop_voting_view = view + 10;
271 self.start_proposing_time = 0;
272 self.stop_proposing_time = u64::MAX;
273 self.start_voting_time = 0;
274 self.stop_voting_time = u64::MAX;
275 }
276
277 pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
279 self.known_nodes_with_stake.clone().into()
280 }
281}
282
283pub mod version_ser {
284
285 use serde::{de, Deserialize, Deserializer, Serializer};
286 use vbs::version::Version;
287
288 pub fn serialize<S>(ver: &Version, serializer: S) -> Result<S::Ok, S::Error>
289 where
290 S: Serializer,
291 {
292 serializer.serialize_str(&ver.to_string())
293 }
294
295 pub fn deserialize<'de, D>(deserializer: D) -> Result<Version, D::Error>
296 where
297 D: Deserializer<'de>,
298 {
299 let version_str = String::deserialize(deserializer)?;
300
301 let version: Vec<_> = version_str.split('.').collect();
302
303 let version = Version {
304 major: version[0]
305 .parse()
306 .map_err(|_| de::Error::custom("invalid version format"))?,
307 minor: version[1]
308 .parse()
309 .map_err(|_| de::Error::custom("invalid version format"))?,
310 };
311
312 Ok(version)
313 }
314}