1#![allow(unused_assignments)]
10use std::{fmt::Debug, future::Future, num::NonZeroUsize, pin::Pin, time::Duration};
11
12use alloy::primitives::U256;
13use bincode::Options;
14use displaydoc::Display;
15use serde::{Deserialize, Serialize};
16use stake_table::HSStakeTable;
17use tracing::error;
18use traits::{
19 node_implementation::NodeType,
20 signature_key::{SignatureKey, StateSignatureKey},
21};
22use url::Url;
23use vbs::version::Version;
24use vec1::Vec1;
25
26use crate::{addr::NetAddr, utils::bincode_opts};
27
28pub mod addr;
29pub mod bundle;
30pub mod consensus;
31pub mod constants;
32pub mod data;
33pub mod drb;
35pub mod epoch_membership;
37pub mod error;
38pub mod event;
39pub mod hotshot_config_file;
41pub mod light_client;
42pub mod message;
43pub mod new_protocol;
44
45pub mod network;
47pub mod qc;
48pub mod request_response;
49pub mod signature_key;
50pub mod simple_certificate;
51pub mod simple_vote;
52pub mod stake_table;
53pub mod traits;
54
55pub mod storage_metrics;
56pub mod upgrade_config;
58pub mod utils;
59pub mod vid;
60pub mod vote;
61pub mod x25519;
62
63pub type BoxSyncFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
65
66pub fn assert_future<T, F>(future: F) -> F
68where
69 F: Future<Output = T>,
70{
71 future
72}
73pub fn boxed_sync<'a, F>(fut: F) -> BoxSyncFuture<'a, F::Output>
75where
76 F: Future + Sized + Send + Sync + 'a,
77{
78 assert_future::<F::Output, _>(Box::pin(fut))
79}
80
81#[derive(Clone, Debug, Display)]
83pub struct ValidatorConfig<TYPES: NodeType> {
84 pub public_key: TYPES::SignatureKey,
86 pub private_key: <TYPES::SignatureKey as SignatureKey>::PrivateKey,
88 pub stake_value: U256,
90 pub state_public_key: TYPES::StateSignatureKey,
92 pub state_private_key: <TYPES::StateSignatureKey as StateSignatureKey>::StatePrivateKey,
94 pub is_da: bool,
96 pub x25519_keypair: Option<x25519::Keypair>,
98 pub p2p_addr: Option<NetAddr>,
100}
101
102impl<TYPES: NodeType> ValidatorConfig<TYPES> {
103 pub fn generated_from_seed_indexed(
105 seed: [u8; 32],
106 index: u64,
107 stake_value: U256,
108 is_da: bool,
109 ) -> Self {
110 let (public_key, private_key) =
111 TYPES::SignatureKey::generated_from_seed_indexed(seed, index);
112 let (state_public_key, state_private_key) =
113 TYPES::StateSignatureKey::generated_from_seed_indexed(seed, index);
114 Self {
115 public_key,
116 private_key,
117 stake_value,
118 state_public_key,
119 state_private_key,
120 is_da,
121 p2p_addr: None,
122 x25519_keypair: None,
123 }
124 }
125
126 pub fn public_config(&self) -> PeerConfig<TYPES> {
128 PeerConfig {
129 stake_table_entry: self.public_key.stake_table_entry(self.stake_value),
130 state_ver_key: self.state_public_key.clone(),
131 connect_info: self
132 .x25519_keypair
133 .as_ref()
134 .map(|k| k.public_key())
135 .and_then(|p| {
136 let a = self.p2p_addr.clone()?;
137 Some(PeerConnectInfo {
138 x25519_key: p,
139 p2p_addr: a,
140 })
141 }),
142 }
143 }
144
145 pub fn test_default() -> Self {
147 Self::generated_from_seed_indexed([0u8; 32], 0, U256::from(1), true)
148 }
149}
150
151#[derive(Clone, Debug, Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
152pub struct PeerConnectInfo {
153 pub x25519_key: x25519::PublicKey,
155 pub p2p_addr: NetAddr,
157}
158
159#[derive(Clone, Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
161#[serde(bound(deserialize = ""))]
162pub struct PeerConfig<TYPES: NodeType> {
163 pub stake_table_entry: <TYPES::SignatureKey as SignatureKey>::StakeTableEntry,
166 pub state_ver_key: TYPES::StateSignatureKey,
169 pub connect_info: Option<PeerConnectInfo>,
170}
171
172impl<TYPES: NodeType> PeerConfig<TYPES> {
173 pub fn test_default() -> Self {
175 let default_validator_config = ValidatorConfig::<TYPES>::test_default();
176 default_validator_config.public_config()
177 }
178
179 pub fn to_bytes(config: &Self) -> Vec<u8> {
181 let x = bincode_opts().serialize(config);
182 match x {
183 Ok(x) => x,
184 Err(e) => {
185 error!(?e, "Failed to serialize public key");
186 vec![]
187 },
188 }
189 }
190
191 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
195 let x: Result<PeerConfig<TYPES>, _> = bincode_opts().deserialize(bytes);
196 match x {
197 Ok(pub_key) => Some(pub_key),
198 Err(e) => {
199 error!(?e, "Failed to deserialize public key");
200 None
201 },
202 }
203 }
204}
205
206impl<TYPES: NodeType> Debug for PeerConfig<TYPES> {
207 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
208 f.debug_struct("PeerConfig")
209 .field("stake_table_entry", &self.stake_table_entry)
210 .field("state_ver_key", &format_args!("{}", self.state_ver_key))
211 .field("connect_info", &self.connect_info)
212 .finish()
213 }
214}
215
216#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
217#[serde(bound(deserialize = ""))]
218pub struct VersionedDaCommittee<TYPES: NodeType> {
219 #[serde(with = "version_ser")]
220 pub start_version: Version,
221 pub start_epoch: u64,
222 pub committee: Vec<PeerConfig<TYPES>>,
223}
224
225#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
227#[serde(bound(deserialize = ""))]
228pub struct HotShotConfig<TYPES: NodeType> {
229 pub start_threshold: (u64, u64),
232 pub num_nodes_with_stake: NonZeroUsize,
235 pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
237 pub known_da_nodes: Vec<PeerConfig<TYPES>>,
239 pub da_committees: Vec<VersionedDaCommittee<TYPES>>,
241 pub da_staked_committee_size: usize,
243 pub fixed_leader_for_gpuvid: usize,
245 pub next_view_timeout: u64,
247 pub view_sync_timeout: Duration,
249 pub num_bootstrap: usize,
251 pub builder_timeout: Duration,
253 pub data_request_delay: Duration,
255 pub builder_urls: Vec1<Url>,
257 pub start_proposing_view: u64,
259 pub stop_proposing_view: u64,
261 pub start_voting_view: u64,
263 pub stop_voting_view: u64,
265 pub start_proposing_time: u64,
267 pub stop_proposing_time: u64,
269 pub start_voting_time: u64,
271 pub stop_voting_time: u64,
273 pub epoch_height: u64,
275 #[serde(default = "default_epoch_start_block")]
277 pub epoch_start_block: u64,
278 #[serde(default = "default_stake_table_capacity")]
280 pub stake_table_capacity: usize,
281 pub drb_difficulty: u64,
283 pub drb_upgrade_difficulty: u64,
285}
286
287fn default_epoch_start_block() -> u64 {
288 1
289}
290
291fn default_stake_table_capacity() -> usize {
292 crate::light_client::DEFAULT_STAKE_TABLE_CAPACITY
293}
294
295impl<TYPES: NodeType> HotShotConfig<TYPES> {
296 pub fn set_view_upgrade(&mut self, view: u64) {
298 self.start_proposing_view = view;
299 self.stop_proposing_view = view + 1;
300 self.start_voting_view = view.saturating_sub(1);
301 self.stop_voting_view = view + 10;
302 self.start_proposing_time = 0;
303 self.stop_proposing_time = u64::MAX;
304 self.start_voting_time = 0;
305 self.stop_voting_time = u64::MAX;
306 }
307
308 pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
310 self.known_nodes_with_stake.clone().into()
311 }
312}
313
314pub mod version_ser {
315
316 use serde::{Deserialize, Deserializer, Serializer, de};
317 use vbs::version::Version;
318
319 pub fn serialize<S>(ver: &Version, serializer: S) -> Result<S::Ok, S::Error>
320 where
321 S: Serializer,
322 {
323 serializer.serialize_str(&ver.to_string())
324 }
325
326 pub fn deserialize<'de, D>(deserializer: D) -> Result<Version, D::Error>
327 where
328 D: Deserializer<'de>,
329 {
330 let version_str = String::deserialize(deserializer)?;
331
332 let version: Vec<_> = version_str.split('.').collect();
333
334 let version = Version {
335 major: version[0]
336 .parse()
337 .map_err(|_| de::Error::custom("invalid version format"))?,
338 minor: version[1]
339 .parse()
340 .map_err(|_| de::Error::custom("invalid version format"))?,
341 };
342
343 Ok(version)
344 }
345}