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;
43
44pub mod network;
46pub mod qc;
47pub mod request_response;
48pub mod signature_key;
49pub mod simple_certificate;
50pub mod simple_vote;
51pub mod stake_table;
52pub mod traits;
53
54pub mod storage_metrics;
55pub mod upgrade_config;
57pub mod utils;
58pub mod vid;
59pub mod vote;
60pub mod x25519;
61
62pub type BoxSyncFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
64
65pub fn assert_future<T, F>(future: F) -> F
67where
68 F: Future<Output = T>,
69{
70 future
71}
72pub fn boxed_sync<'a, F>(fut: F) -> BoxSyncFuture<'a, F::Output>
74where
75 F: Future + Sized + Send + Sync + 'a,
76{
77 assert_future::<F::Output, _>(Box::pin(fut))
78}
79
80#[derive(Clone, Debug, Display)]
82pub struct ValidatorConfig<TYPES: NodeType> {
83 pub public_key: TYPES::SignatureKey,
85 pub private_key: <TYPES::SignatureKey as SignatureKey>::PrivateKey,
87 pub stake_value: U256,
89 pub state_public_key: TYPES::StateSignatureKey,
91 pub state_private_key: <TYPES::StateSignatureKey as StateSignatureKey>::StatePrivateKey,
93 pub is_da: bool,
95 pub x25519_keypair: Option<x25519::Keypair>,
97 pub p2p_addr: Option<NetAddr>,
99}
100
101impl<TYPES: NodeType> ValidatorConfig<TYPES> {
102 pub fn generated_from_seed_indexed(
104 seed: [u8; 32],
105 index: u64,
106 stake_value: U256,
107 is_da: bool,
108 ) -> Self {
109 let (public_key, private_key) =
110 TYPES::SignatureKey::generated_from_seed_indexed(seed, index);
111 let (state_public_key, state_private_key) =
112 TYPES::StateSignatureKey::generated_from_seed_indexed(seed, index);
113 Self {
114 public_key,
115 private_key,
116 stake_value,
117 state_public_key,
118 state_private_key,
119 is_da,
120 p2p_addr: None,
121 x25519_keypair: None,
122 }
123 }
124
125 pub fn public_config(&self) -> PeerConfig<TYPES> {
127 PeerConfig {
128 stake_table_entry: self.public_key.stake_table_entry(self.stake_value),
129 state_ver_key: self.state_public_key.clone(),
130 connect_info: self
131 .x25519_keypair
132 .as_ref()
133 .map(|k| k.public_key())
134 .and_then(|p| {
135 let a = self.p2p_addr.clone()?;
136 Some(PeerConnectInfo {
137 x25519_key: p,
138 p2p_addr: a,
139 })
140 }),
141 }
142 }
143
144 pub fn test_default() -> Self {
146 Self::generated_from_seed_indexed([0u8; 32], 0, U256::from(1), true)
147 }
148}
149
150#[derive(Clone, Debug, Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
151pub struct PeerConnectInfo {
152 pub x25519_key: x25519::PublicKey,
154 pub p2p_addr: NetAddr,
156}
157
158#[derive(Clone, Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
160#[serde(bound(deserialize = ""))]
161pub struct PeerConfig<TYPES: NodeType> {
162 pub stake_table_entry: <TYPES::SignatureKey as SignatureKey>::StakeTableEntry,
165 pub state_ver_key: TYPES::StateSignatureKey,
168 pub connect_info: Option<PeerConnectInfo>,
169}
170
171impl<TYPES: NodeType> PeerConfig<TYPES> {
172 pub fn test_default() -> Self {
174 let default_validator_config = ValidatorConfig::<TYPES>::test_default();
175 default_validator_config.public_config()
176 }
177
178 pub fn to_bytes(config: &Self) -> Vec<u8> {
180 let x = bincode_opts().serialize(config);
181 match x {
182 Ok(x) => x,
183 Err(e) => {
184 error!(?e, "Failed to serialize public key");
185 vec![]
186 },
187 }
188 }
189
190 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
194 let x: Result<PeerConfig<TYPES>, _> = bincode_opts().deserialize(bytes);
195 match x {
196 Ok(pub_key) => Some(pub_key),
197 Err(e) => {
198 error!(?e, "Failed to deserialize public key");
199 None
200 },
201 }
202 }
203}
204
205impl<TYPES: NodeType> Debug for PeerConfig<TYPES> {
206 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207 f.debug_struct("PeerConfig")
208 .field("stake_table_entry", &self.stake_table_entry)
209 .field("state_ver_key", &format_args!("{}", self.state_ver_key))
210 .field("connect_info", &self.connect_info)
211 .finish()
212 }
213}
214
215#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
216#[serde(bound(deserialize = ""))]
217pub struct VersionedDaCommittee<TYPES: NodeType> {
218 #[serde(with = "version_ser")]
219 pub start_version: Version,
220 pub start_epoch: u64,
221 pub committee: Vec<PeerConfig<TYPES>>,
222}
223
224#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
226#[serde(bound(deserialize = ""))]
227pub struct HotShotConfig<TYPES: NodeType> {
228 pub start_threshold: (u64, u64),
231 pub num_nodes_with_stake: NonZeroUsize,
234 pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
236 pub known_da_nodes: Vec<PeerConfig<TYPES>>,
238 pub da_committees: Vec<VersionedDaCommittee<TYPES>>,
240 pub da_staked_committee_size: usize,
242 pub fixed_leader_for_gpuvid: usize,
244 pub next_view_timeout: u64,
246 pub view_sync_timeout: Duration,
248 pub num_bootstrap: usize,
250 pub builder_timeout: Duration,
252 pub data_request_delay: Duration,
254 pub builder_urls: Vec1<Url>,
256 pub start_proposing_view: u64,
258 pub stop_proposing_view: u64,
260 pub start_voting_view: u64,
262 pub stop_voting_view: u64,
264 pub start_proposing_time: u64,
266 pub stop_proposing_time: u64,
268 pub start_voting_time: u64,
270 pub stop_voting_time: u64,
272 pub epoch_height: u64,
274 #[serde(default = "default_epoch_start_block")]
276 pub epoch_start_block: u64,
277 #[serde(default = "default_stake_table_capacity")]
279 pub stake_table_capacity: usize,
280 pub drb_difficulty: u64,
282 pub drb_upgrade_difficulty: u64,
284}
285
286fn default_epoch_start_block() -> u64 {
287 1
288}
289
290fn default_stake_table_capacity() -> usize {
291 crate::light_client::DEFAULT_STAKE_TABLE_CAPACITY
292}
293
294impl<TYPES: NodeType> HotShotConfig<TYPES> {
295 pub fn set_view_upgrade(&mut self, view: u64) {
297 self.start_proposing_view = view;
298 self.stop_proposing_view = view + 1;
299 self.start_voting_view = view.saturating_sub(1);
300 self.stop_voting_view = view + 10;
301 self.start_proposing_time = 0;
302 self.stop_proposing_time = u64::MAX;
303 self.start_voting_time = 0;
304 self.stop_voting_time = u64::MAX;
305 }
306
307 pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
309 self.known_nodes_with_stake.clone().into()
310 }
311}
312
313pub mod version_ser {
314
315 use serde::{Deserialize, Deserializer, Serializer, de};
316 use vbs::version::Version;
317
318 pub fn serialize<S>(ver: &Version, serializer: S) -> Result<S::Ok, S::Error>
319 where
320 S: Serializer,
321 {
322 serializer.serialize_str(&ver.to_string())
323 }
324
325 pub fn deserialize<'de, D>(deserializer: D) -> Result<Version, D::Error>
326 where
327 D: Deserializer<'de>,
328 {
329 let version_str = String::deserialize(deserializer)?;
330
331 let version: Vec<_> = version_str.split('.').collect();
332
333 let version = Version {
334 major: version[0]
335 .parse()
336 .map_err(|_| de::Error::custom("invalid version format"))?,
337 minor: version[1]
338 .parse()
339 .map_err(|_| de::Error::custom("invalid version format"))?,
340 };
341
342 Ok(version)
343 }
344}