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 vec1::Vec1;
21
22use crate::utils::bincode_opts;
23pub mod bundle;
24pub mod consensus;
25pub mod constants;
26pub mod data;
27pub mod drb;
29pub mod epoch_membership;
31pub mod error;
32pub mod event;
33pub mod hotshot_config_file;
35pub mod light_client;
36pub mod message;
37
38pub mod network;
40pub mod qc;
41pub mod request_response;
42pub mod signature_key;
43pub mod simple_certificate;
44pub mod simple_vote;
45pub mod stake_table;
46pub mod traits;
47
48pub mod storage_metrics;
49pub mod upgrade_config;
51pub mod utils;
52pub mod vid;
53pub mod vote;
54
55pub type BoxSyncFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
57
58pub fn assert_future<T, F>(future: F) -> F
60where
61 F: Future<Output = T>,
62{
63 future
64}
65pub fn boxed_sync<'a, F>(fut: F) -> BoxSyncFuture<'a, F::Output>
67where
68 F: Future + Sized + Send + Sync + 'a,
69{
70 assert_future::<F::Output, _>(Box::pin(fut))
71}
72
73#[derive(Clone, Debug, Display)]
74pub struct ValidatorConfig<TYPES: NodeType> {
76 pub public_key: TYPES::SignatureKey,
78 pub private_key: <TYPES::SignatureKey as SignatureKey>::PrivateKey,
80 pub stake_value: U256,
82 pub state_public_key: TYPES::StateSignatureKey,
84 pub state_private_key: <TYPES::StateSignatureKey as StateSignatureKey>::StatePrivateKey,
86 pub is_da: bool,
88}
89
90impl<TYPES: NodeType> ValidatorConfig<TYPES> {
91 #[must_use]
93 pub fn generated_from_seed_indexed(
94 seed: [u8; 32],
95 index: u64,
96 stake_value: U256,
97 is_da: bool,
98 ) -> Self {
99 let (public_key, private_key) =
100 TYPES::SignatureKey::generated_from_seed_indexed(seed, index);
101 let (state_public_key, state_private_key) =
102 TYPES::StateSignatureKey::generated_from_seed_indexed(seed, index);
103 Self {
104 public_key,
105 private_key,
106 stake_value,
107 state_public_key,
108 state_private_key,
109 is_da,
110 }
111 }
112
113 pub fn public_config(&self) -> PeerConfig<TYPES> {
115 PeerConfig {
116 stake_table_entry: self.public_key.stake_table_entry(self.stake_value),
117 state_ver_key: self.state_public_key.clone(),
118 }
119 }
120}
121
122impl<TYPES: NodeType> Default for ValidatorConfig<TYPES> {
123 fn default() -> Self {
124 Self::generated_from_seed_indexed([0u8; 32], 0, U256::from(1), true)
125 }
126}
127
128#[derive(serde::Serialize, serde::Deserialize, Clone, Display, PartialEq, Eq, Hash)]
129#[serde(bound(deserialize = ""))]
130pub struct PeerConfig<TYPES: NodeType> {
132 pub stake_table_entry: <TYPES::SignatureKey as SignatureKey>::StakeTableEntry,
135 pub state_ver_key: TYPES::StateSignatureKey,
138}
139
140impl<TYPES: NodeType> PeerConfig<TYPES> {
141 pub fn to_bytes(config: &Self) -> Vec<u8> {
143 let x = bincode_opts().serialize(config);
144 match x {
145 Ok(x) => x,
146 Err(e) => {
147 error!(?e, "Failed to serialize public key");
148 vec![]
149 },
150 }
151 }
152
153 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
157 let x: Result<PeerConfig<TYPES>, _> = bincode_opts().deserialize(bytes);
158 match x {
159 Ok(pub_key) => Some(pub_key),
160 Err(e) => {
161 error!(?e, "Failed to deserialize public key");
162 None
163 },
164 }
165 }
166}
167
168impl<TYPES: NodeType> Default for PeerConfig<TYPES> {
169 fn default() -> Self {
170 let default_validator_config = ValidatorConfig::<TYPES>::default();
171 default_validator_config.public_config()
172 }
173}
174
175impl<TYPES: NodeType> Debug for PeerConfig<TYPES> {
176 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177 f.debug_struct("PeerConfig")
178 .field("stake_table_entry", &self.stake_table_entry)
179 .field("state_ver_key", &format_args!("{}", self.state_ver_key))
180 .finish()
181 }
182}
183
184#[derive(Clone, derive_more::Debug, serde::Serialize, serde::Deserialize)]
186#[serde(bound(deserialize = ""))]
187pub struct HotShotConfig<TYPES: NodeType> {
188 pub start_threshold: (u64, u64),
191 pub num_nodes_with_stake: NonZeroUsize,
194 pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
196 pub known_da_nodes: Vec<PeerConfig<TYPES>>,
198 pub da_staked_committee_size: usize,
200 pub fixed_leader_for_gpuvid: usize,
202 pub next_view_timeout: u64,
204 pub view_sync_timeout: Duration,
206 pub num_bootstrap: usize,
208 pub builder_timeout: Duration,
210 pub data_request_delay: Duration,
212 pub builder_urls: Vec1<Url>,
214 pub start_proposing_view: u64,
216 pub stop_proposing_view: u64,
218 pub start_voting_view: u64,
220 pub stop_voting_view: u64,
222 pub start_proposing_time: u64,
224 pub stop_proposing_time: u64,
226 pub start_voting_time: u64,
228 pub stop_voting_time: u64,
230 pub epoch_height: u64,
232 #[serde(default = "default_epoch_start_block")]
234 pub epoch_start_block: u64,
235 #[serde(default = "default_stake_table_capacity")]
237 pub stake_table_capacity: usize,
238 pub drb_difficulty: u64,
240 pub drb_upgrade_difficulty: u64,
242}
243
244fn default_epoch_start_block() -> u64 {
245 1
246}
247
248fn default_stake_table_capacity() -> usize {
249 crate::light_client::DEFAULT_STAKE_TABLE_CAPACITY
250}
251
252impl<TYPES: NodeType> HotShotConfig<TYPES> {
253 pub fn set_view_upgrade(&mut self, view: u64) {
255 self.start_proposing_view = view;
256 self.stop_proposing_view = view + 1;
257 self.start_voting_view = view.saturating_sub(1);
258 self.stop_voting_view = view + 10;
259 self.start_proposing_time = 0;
260 self.stop_proposing_time = u64::MAX;
261 self.start_voting_time = 0;
262 self.stop_voting_time = u64::MAX;
263 }
264
265 pub fn hotshot_stake_table(&self) -> HSStakeTable<TYPES> {
267 self.known_nodes_with_stake.clone().into()
268 }
269}