1#![allow(unused_assignments)]
10use std::{fmt::Debug, num::NonZeroUsize, 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 initializer;
42pub mod light_client;
43pub mod message;
44pub mod new_protocol;
45
46pub mod network;
48pub mod qc;
49pub mod request_response;
50pub mod signature_key;
51pub mod simple_certificate;
52pub mod simple_vote;
53pub mod stake_table;
54pub mod traits;
55
56pub mod storage_metrics;
57pub mod upgrade_config;
59pub mod utils;
60pub mod vid;
61pub mod vote;
62pub mod x25519;
63
64#[derive(Clone, Debug, Display)]
66pub struct ValidatorConfig<TYPES: NodeType> {
67 pub public_key: TYPES::SignatureKey,
69 pub private_key: <TYPES::SignatureKey as SignatureKey>::PrivateKey,
71 pub stake_value: U256,
73 pub state_public_key: TYPES::StateSignatureKey,
75 pub state_private_key: <TYPES::StateSignatureKey as StateSignatureKey>::StatePrivateKey,
77 pub is_da: bool,
79 pub x25519_keypair: Option<x25519::Keypair>,
81 pub p2p_addr: Option<NetAddr>,
83}
84
85impl<TYPES: NodeType> ValidatorConfig<TYPES> {
86 pub fn generated_from_seed_indexed(
88 seed: [u8; 32],
89 index: u64,
90 stake_value: U256,
91 is_da: bool,
92 ) -> Self {
93 let (public_key, private_key) =
94 TYPES::SignatureKey::generated_from_seed_indexed(seed, index);
95 let (state_public_key, state_private_key) =
96 TYPES::StateSignatureKey::generated_from_seed_indexed(seed, index);
97 Self {
98 public_key,
99 private_key,
100 stake_value,
101 state_public_key,
102 state_private_key,
103 is_da,
104 p2p_addr: None,
105 x25519_keypair: None,
106 }
107 }
108
109 pub fn public_config(&self) -> PeerConfig<TYPES> {
111 PeerConfig {
112 stake_table_entry: self.public_key.stake_table_entry(self.stake_value),
113 state_ver_key: self.state_public_key.clone(),
114 connect_info: self
115 .x25519_keypair
116 .as_ref()
117 .map(|k| k.public_key())
118 .and_then(|p| {
119 let a = self.p2p_addr.clone()?;
120 Some(PeerConnectInfo {
121 x25519_key: p,
122 p2p_addr: a,
123 })
124 }),
125 }
126 }
127
128 pub fn test_default() -> Self {
130 Self::generated_from_seed_indexed([0u8; 32], 0, U256::from(1), true)
131 }
132}
133
134#[derive(Clone, Debug, Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
135pub struct PeerConnectInfo {
136 pub x25519_key: x25519::PublicKey,
138 pub p2p_addr: NetAddr,
140}
141
142#[derive(Clone, Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
144#[serde(bound(deserialize = ""))]
145pub struct PeerConfig<TYPES: NodeType> {
146 pub stake_table_entry: <TYPES::SignatureKey as SignatureKey>::StakeTableEntry,
149 pub state_ver_key: TYPES::StateSignatureKey,
152 pub connect_info: Option<PeerConnectInfo>,
153}
154
155impl<TYPES: NodeType> PeerConfig<TYPES> {
156 pub fn test_default() -> Self {
158 let default_validator_config = ValidatorConfig::<TYPES>::test_default();
159 default_validator_config.public_config()
160 }
161
162 pub fn to_bytes(config: &Self) -> Vec<u8> {
164 let x = bincode_opts().serialize(config);
165 match x {
166 Ok(x) => x,
167 Err(e) => {
168 error!(?e, "Failed to serialize public key");
169 vec![]
170 },
171 }
172 }
173
174 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
178 let x: Result<PeerConfig<TYPES>, _> = bincode_opts().deserialize(bytes);
179 match x {
180 Ok(pub_key) => Some(pub_key),
181 Err(e) => {
182 error!(?e, "Failed to deserialize public key");
183 None
184 },
185 }
186 }
187}
188
189impl<TYPES: NodeType> Debug for PeerConfig<TYPES> {
190 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191 f.debug_struct("PeerConfig")
192 .field("stake_table_entry", &self.stake_table_entry)
193 .field("state_ver_key", &format_args!("{}", self.state_ver_key))
194 .field("connect_info", &self.connect_info)
195 .finish()
196 }
197}
198
199#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
200#[serde(bound(deserialize = ""))]
201pub struct VersionedDaCommittee<TYPES: NodeType> {
202 #[serde(with = "version_ser")]
203 pub start_version: Version,
204 pub start_epoch: u64,
205 pub committee: Vec<PeerConfig<TYPES>>,
206}
207
208#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
210#[serde(bound(deserialize = ""))]
211pub struct HotShotConfig<TYPES: NodeType> {
212 pub start_threshold: (u64, u64),
215 pub num_nodes_with_stake: NonZeroUsize,
218 pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
220 pub known_da_nodes: Vec<PeerConfig<TYPES>>,
222 pub da_committees: Vec<VersionedDaCommittee<TYPES>>,
224 pub da_staked_committee_size: usize,
226 pub fixed_leader_for_gpuvid: usize,
228 pub next_view_timeout: u64,
230 pub view_sync_timeout: Duration,
232 pub num_bootstrap: usize,
234 pub builder_timeout: Duration,
236 pub data_request_delay: Duration,
238 pub builder_urls: Vec1<Url>,
240 pub start_proposing_view: u64,
242 pub stop_proposing_view: u64,
244 pub start_voting_view: u64,
246 pub stop_voting_view: u64,
248 pub start_proposing_time: u64,
250 pub stop_proposing_time: u64,
252 pub start_voting_time: u64,
254 pub stop_voting_time: u64,
256 pub epoch_height: u64,
258 #[serde(default = "default_epoch_start_block")]
260 pub epoch_start_block: u64,
261 #[serde(default = "default_stake_table_capacity")]
263 pub stake_table_capacity: usize,
264 pub drb_difficulty: u64,
266 pub drb_upgrade_difficulty: u64,
268}
269
270fn default_epoch_start_block() -> u64 {
271 1
272}
273
274fn default_stake_table_capacity() -> usize {
275 crate::light_client::DEFAULT_STAKE_TABLE_CAPACITY
276}
277
278impl<TYPES: NodeType> HotShotConfig<TYPES> {
279 pub fn set_view_upgrade(&mut self, view: u64) {
281 self.start_proposing_view = view;
282 self.stop_proposing_view = view + 1;
283 self.start_voting_view = view.saturating_sub(1);
284 self.stop_voting_view = view + 10;
285 self.start_proposing_time = 0;
286 self.stop_proposing_time = u64::MAX;
287 self.start_voting_time = 0;
288 self.stop_voting_time = u64::MAX;
289 }
290
291 pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
293 self.known_nodes_with_stake.clone().into()
294 }
295}
296
297pub mod arc_bytes {
302 use std::{borrow::Cow, sync::Arc};
303
304 use serde::{Deserializer, Serializer};
305
306 pub fn serialize<S>(bytes: &Arc<[u8]>, serializer: S) -> Result<S::Ok, S::Error>
310 where
311 S: Serializer,
312 {
313 serde_bytes::serialize(bytes.as_ref(), serializer)
314 }
315
316 pub fn deserialize<'de, D>(deserializer: D) -> Result<Arc<[u8]>, D::Error>
320 where
321 D: Deserializer<'de>,
322 {
323 serde_bytes::deserialize::<Cow<[u8]>, _>(deserializer).map(|bytes| Arc::from(&*bytes))
324 }
325}
326
327pub mod version_ser {
328
329 use serde::{Deserialize, Deserializer, Serializer, de};
330 use vbs::version::Version;
331
332 pub fn serialize<S>(ver: &Version, serializer: S) -> Result<S::Ok, S::Error>
333 where
334 S: Serializer,
335 {
336 serializer.serialize_str(&ver.to_string())
337 }
338
339 pub fn deserialize<'de, D>(deserializer: D) -> Result<Version, D::Error>
340 where
341 D: Deserializer<'de>,
342 {
343 let version_str = String::deserialize(deserializer)?;
344
345 let version: Vec<_> = version_str.split('.').collect();
346
347 let version = Version {
348 major: version[0]
349 .parse()
350 .map_err(|_| de::Error::custom("invalid version format"))?,
351 minor: version[1]
352 .parse()
353 .map_err(|_| de::Error::custom("invalid version format"))?,
354 };
355
356 Ok(version)
357 }
358}