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