1use std::{num::NonZeroUsize, time::Duration};
2
3use hotshot_types::{
4 network::{
5 BuilderType, CombinedNetworkConfig, Libp2pConfig, NetworkConfig, RandomBuilderConfig,
6 },
7 HotShotConfig, PeerConfig, ValidatorConfig, VersionedDaCommittee,
8};
9use serde::{Deserialize, Serialize};
10use tide_disco::Url;
11use vec1::Vec1;
12
13use crate::{PubKey, SeqTypes};
14
15#[derive(Clone, Debug, Deserialize, Serialize)]
18pub struct PublicValidatorConfig {
19 public_key: PubKey,
20 stake_value: u64,
21 is_da: bool,
22 private_key: String,
23 state_public_key: String,
24 state_key_pair: String,
25}
26
27impl From<ValidatorConfig<SeqTypes>> for PublicValidatorConfig {
28 fn from(v: ValidatorConfig<SeqTypes>) -> Self {
29 let ValidatorConfig::<SeqTypes> {
30 public_key,
31 private_key: _,
32 stake_value,
33 state_public_key,
34 state_private_key: _,
35 is_da,
36 } = v;
37
38 Self {
39 public_key,
40 stake_value: stake_value.to::<u64>(),
41 is_da,
42 state_public_key: state_public_key.to_string(),
43 private_key: "*****".into(),
44 state_key_pair: "*****".into(),
45 }
46 }
47}
48
49#[derive(Clone, Debug, Deserialize, Serialize)]
53pub struct PublicHotShotConfig {
54 start_threshold: (u64, u64),
55 num_nodes_with_stake: NonZeroUsize,
56 known_nodes_with_stake: Vec<PeerConfig<SeqTypes>>,
57 known_da_nodes: Vec<PeerConfig<SeqTypes>>,
58 #[serde(default)]
59 da_committees: Vec<VersionedDaCommittee<SeqTypes>>,
60 da_staked_committee_size: usize,
61 fixed_leader_for_gpuvid: usize,
62 next_view_timeout: u64,
63 view_sync_timeout: Duration,
64 num_bootstrap: usize,
65 builder_timeout: Duration,
66 data_request_delay: Duration,
67 builder_urls: Vec1<Url>,
68 start_proposing_view: u64,
69 stop_proposing_view: u64,
70 start_voting_view: u64,
71 stop_voting_view: u64,
72 start_proposing_time: u64,
73 stop_proposing_time: u64,
74 start_voting_time: u64,
75 stop_voting_time: u64,
76 epoch_height: u64,
77 epoch_start_block: u64,
78 #[serde(default = "default_stake_table_capacity")]
79 stake_table_capacity: usize,
80 #[serde(default = "default_drb_difficulty")]
81 drb_difficulty: u64,
82 #[serde(default = "default_drb_upgrade_difficulty")]
83 drb_upgrade_difficulty: u64,
84}
85
86fn default_stake_table_capacity() -> usize {
87 hotshot_types::light_client::DEFAULT_STAKE_TABLE_CAPACITY
88}
89
90fn default_drb_difficulty() -> u64 {
92 0
93}
94
95fn default_drb_upgrade_difficulty() -> u64 {
97 0
98}
99
100impl From<HotShotConfig<SeqTypes>> for PublicHotShotConfig {
101 fn from(v: HotShotConfig<SeqTypes>) -> Self {
102 let HotShotConfig::<SeqTypes> {
106 start_threshold,
107 num_nodes_with_stake,
108 known_nodes_with_stake,
109 known_da_nodes,
110 da_committees,
111 da_staked_committee_size,
112 fixed_leader_for_gpuvid,
113 next_view_timeout,
114 view_sync_timeout,
115 num_bootstrap,
116 builder_timeout,
117 data_request_delay,
118 builder_urls,
119 start_proposing_view,
120 stop_proposing_view,
121 start_voting_view,
122 stop_voting_view,
123 start_proposing_time,
124 stop_proposing_time,
125 start_voting_time,
126 stop_voting_time,
127 epoch_height,
128 epoch_start_block,
129 stake_table_capacity,
130 drb_difficulty,
131 drb_upgrade_difficulty,
132 } = v;
133
134 Self {
135 start_threshold,
136 num_nodes_with_stake,
137 known_nodes_with_stake,
138 known_da_nodes,
139 da_committees,
140 da_staked_committee_size,
141 fixed_leader_for_gpuvid,
142 next_view_timeout,
143 view_sync_timeout,
144 num_bootstrap,
145 builder_timeout,
146 data_request_delay,
147 builder_urls,
148 start_proposing_view,
149 stop_proposing_view,
150 start_voting_view,
151 stop_voting_view,
152 start_proposing_time,
153 stop_proposing_time,
154 start_voting_time,
155 stop_voting_time,
156 epoch_height,
157 epoch_start_block,
158 stake_table_capacity,
159 drb_difficulty,
160 drb_upgrade_difficulty,
161 }
162 }
163}
164
165impl PublicHotShotConfig {
166 pub fn into_hotshot_config(self) -> HotShotConfig<SeqTypes> {
167 HotShotConfig {
168 start_threshold: self.start_threshold,
169 num_nodes_with_stake: self.num_nodes_with_stake,
170 known_nodes_with_stake: self.known_nodes_with_stake,
171 known_da_nodes: self.known_da_nodes,
172 da_committees: self.da_committees,
173 da_staked_committee_size: self.da_staked_committee_size,
174 fixed_leader_for_gpuvid: self.fixed_leader_for_gpuvid,
175 next_view_timeout: self.next_view_timeout,
176 view_sync_timeout: self.view_sync_timeout,
177 num_bootstrap: self.num_bootstrap,
178 builder_timeout: self.builder_timeout,
179 data_request_delay: self.data_request_delay,
180 builder_urls: self.builder_urls,
181 start_proposing_view: self.start_proposing_view,
182 stop_proposing_view: self.stop_proposing_view,
183 start_voting_view: self.start_voting_view,
184 stop_voting_view: self.stop_voting_view,
185 start_proposing_time: self.start_proposing_time,
186 stop_proposing_time: self.stop_proposing_time,
187 start_voting_time: self.start_voting_time,
188 stop_voting_time: self.stop_voting_time,
189 epoch_height: self.epoch_height,
190 epoch_start_block: self.epoch_start_block,
191 stake_table_capacity: self.stake_table_capacity,
192 drb_difficulty: self.drb_difficulty,
193 drb_upgrade_difficulty: self.drb_upgrade_difficulty,
194 }
195 }
196
197 pub fn known_nodes_with_stake(&self) -> Vec<PeerConfig<SeqTypes>> {
198 self.known_nodes_with_stake.clone()
199 }
200
201 pub fn known_da_nodes(&self) -> Vec<PeerConfig<SeqTypes>> {
202 self.known_da_nodes.clone()
203 }
204
205 pub fn blocks_per_epoch(&self) -> u64 {
206 self.epoch_height
207 }
208
209 pub fn epoch_start_block(&self) -> u64 {
210 self.epoch_start_block
211 }
212}
213
214#[derive(Clone, Debug, Deserialize, Serialize)]
215pub struct PublicNetworkConfig {
216 rounds: usize,
217 indexed_da: bool,
218 transactions_per_round: usize,
219 manual_start_password: Option<String>,
220 num_bootrap: usize,
221 next_view_timeout: u64,
222 view_sync_timeout: Duration,
223 builder_timeout: Duration,
224 data_request_delay: Duration,
225 node_index: u64,
226 seed: [u8; 32],
227 transaction_size: usize,
228 key_type_name: String,
229 libp2p_config: Option<Libp2pConfig>,
230 config: PublicHotShotConfig,
231 cdn_marshal_address: Option<String>,
232 combined_network_config: Option<CombinedNetworkConfig>,
233 commit_sha: String,
234 builder: BuilderType,
235 random_builder: Option<RandomBuilderConfig>,
236}
237
238impl From<NetworkConfig<SeqTypes>> for PublicNetworkConfig {
239 fn from(cfg: NetworkConfig<SeqTypes>) -> Self {
240 Self {
241 rounds: cfg.rounds,
242 indexed_da: cfg.indexed_da,
243 transactions_per_round: cfg.transactions_per_round,
244 manual_start_password: Some("*****".into()),
245 num_bootrap: cfg.num_bootrap,
246 next_view_timeout: cfg.next_view_timeout,
247 view_sync_timeout: cfg.view_sync_timeout,
248 builder_timeout: cfg.builder_timeout,
249 data_request_delay: cfg.data_request_delay,
250 node_index: cfg.node_index,
251 seed: cfg.seed,
252 transaction_size: cfg.transaction_size,
253 key_type_name: cfg.key_type_name,
254 libp2p_config: cfg.libp2p_config,
255 config: cfg.config.into(),
256 cdn_marshal_address: cfg.cdn_marshal_address,
257 combined_network_config: cfg.combined_network_config,
258 commit_sha: cfg.commit_sha,
259 builder: cfg.builder,
260 random_builder: cfg.random_builder,
261 }
262 }
263}
264
265impl PublicNetworkConfig {
266 pub fn into_network_config(
267 self,
268 my_own_validator_config: ValidatorConfig<SeqTypes>,
269 ) -> anyhow::Result<NetworkConfig<SeqTypes>> {
270 let node_index = self
271 .config
272 .known_nodes_with_stake
273 .iter()
274 .position(|peer| peer.stake_table_entry.stake_key == my_own_validator_config.public_key)
275 .unwrap_or(0) as u64;
276
277 Ok(NetworkConfig {
278 rounds: self.rounds,
279 indexed_da: self.indexed_da,
280 transactions_per_round: self.transactions_per_round,
281 manual_start_password: self.manual_start_password,
282 num_bootrap: self.num_bootrap,
283 next_view_timeout: self.next_view_timeout,
284 view_sync_timeout: self.view_sync_timeout,
285 builder_timeout: self.builder_timeout,
286 data_request_delay: self.data_request_delay,
287 node_index,
288 seed: self.seed,
289 transaction_size: self.transaction_size,
290 key_type_name: self.key_type_name,
291 libp2p_config: self.libp2p_config,
292 config: self.config.into_hotshot_config(),
293 cdn_marshal_address: self.cdn_marshal_address,
294 combined_network_config: self.combined_network_config,
295 commit_sha: self.commit_sha,
296 builder: self.builder,
297 random_builder: self.random_builder,
298 public_keys: Vec::new(),
299 })
300 }
301
302 pub fn hotshot_config(&self) -> PublicHotShotConfig {
303 self.config.clone()
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 use super::PublicNetworkConfig;
310
311 #[test]
312 fn test_deserialize_from_old_config() {
313 let json_str = r#"
315 {
316 "rounds": 100,
317 "indexed_da": false,
318 "transactions_per_round": 10,
319 "manual_start_password": "*****",
320 "num_bootrap": 5,
321 "next_view_timeout": 10,
322 "view_sync_timeout": {
323 "secs": 2,
324 "nanos": 0
325 },
326 "builder_timeout": {
327 "secs": 10,
328 "nanos": 0
329 },
330 "data_request_delay": {
331 "secs": 2,
332 "nanos": 500000000
333 },
334 "node_index": 1,
335 "seed": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
336 "transaction_size": 100,
337 "key_type_name": "jf_signature::bls_over_bn254::VerKey",
338 "libp2p_config": {
339 "bootstrap_nodes": []
340 },
341 "config": {
342 "start_threshold": [100, 100],
343 "num_nodes_with_stake": 100,
344 "known_nodes_with_stake": [],
345 "known_da_nodes": [],
346 "da_staked_committee_size": 100,
347 "fixed_leader_for_gpuvid": 1,
348 "next_view_timeout": 12000,
349 "view_sync_timeout": {
350 "secs": 1,
351 "nanos": 0
352 },
353 "num_bootstrap": 5,
354 "builder_timeout": {
355 "secs": 8,
356 "nanos": 0
357 },
358 "data_request_delay": {
359 "secs": 5,
360 "nanos": 0
361 },
362 "builder_urls": [
363 "https://builder.decaf.testnet.espresso.network/"
364 ],
365 "start_proposing_view": 0,
366 "stop_proposing_view": 0,
367 "start_voting_view": 0,
368 "stop_voting_view": 0,
369 "start_proposing_time": 0,
370 "stop_proposing_time": 0,
371 "start_voting_time": 0,
372 "stop_voting_time": 0,
373 "epoch_height": 3000,
374 "epoch_start_block": 3160636
375 },
376 "cdn_marshal_address": null,
377 "combined_network_config": null,
378 "commit_sha": "",
379 "builder": "Simple",
380 "random_builder": null
381}
382 "#;
383 let _public_config: PublicNetworkConfig = serde_json::from_str(json_str).unwrap();
384 }
385}