hotshot_types/
hotshot_config_file.rs

1// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
2// This file is part of the HotShot repository.
3
4// You should have received a copy of the MIT License
5// along with the HotShot repository. If not, see <https://mit-license.org/>.
6
7use std::{num::NonZeroUsize, time::Duration};
8
9use alloy::primitives::U256;
10use url::Url;
11use vec1::Vec1;
12
13use crate::{
14    constants::REQUEST_DATA_DELAY, upgrade_config::UpgradeConfig, HotShotConfig, NodeType,
15    PeerConfig, ValidatorConfig,
16};
17
18/// Default builder URL, used as placeholder
19fn default_builder_urls() -> Vec1<Url> {
20    vec1::vec1![Url::parse("http://0.0.0.0:3311").unwrap()]
21}
22
23/// Holds configuration for a `HotShot`
24#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
25#[serde(bound(deserialize = ""))]
26pub struct HotShotConfigFile<TYPES: NodeType> {
27    /// The proportion of nodes required before the orchestrator issues the ready signal,
28    /// expressed as (numerator, denominator)
29    pub start_threshold: (u64, u64),
30    /// Total number of staked nodes in the network
31    pub num_nodes_with_stake: NonZeroUsize,
32    #[serde(skip)]
33    /// The known nodes' public key and stake value
34    pub known_nodes_with_stake: Vec<PeerConfig<TYPES>>,
35    #[serde(skip)]
36    /// The known DA nodes' public key and stake values
37    pub known_da_nodes: Vec<PeerConfig<TYPES>>,
38    /// Number of staking DA nodes
39    pub staked_da_nodes: usize,
40    /// Number of fixed leaders for GPU VID
41    pub fixed_leader_for_gpuvid: usize,
42    /// Base duration for next-view timeout, in milliseconds
43    pub next_view_timeout: u64,
44    /// Duration for view sync round timeout
45    pub view_sync_timeout: Duration,
46    /// Number of network bootstrap nodes
47    pub num_bootstrap: usize,
48    /// The maximum amount of time a leader can wait to get a block from a builder
49    pub builder_timeout: Duration,
50    /// Time to wait until we request data associated with a proposal
51    pub data_request_delay: Option<Duration>,
52    /// Builder API base URL
53    #[serde(default = "default_builder_urls")]
54    pub builder_urls: Vec1<Url>,
55    /// Upgrade config
56    pub upgrade: UpgradeConfig,
57    /// Number of blocks in an epoch, zero means there are no epochs
58    pub epoch_height: u64,
59    /// Epoch start block
60    pub epoch_start_block: u64,
61}
62
63impl<TYPES: NodeType> From<HotShotConfigFile<TYPES>> for HotShotConfig<TYPES> {
64    fn from(val: HotShotConfigFile<TYPES>) -> Self {
65        HotShotConfig {
66            start_threshold: val.start_threshold,
67            num_nodes_with_stake: val.num_nodes_with_stake,
68            known_da_nodes: val.known_da_nodes,
69            known_nodes_with_stake: val.known_nodes_with_stake,
70            da_staked_committee_size: val.staked_da_nodes,
71            fixed_leader_for_gpuvid: val.fixed_leader_for_gpuvid,
72            next_view_timeout: val.next_view_timeout,
73            view_sync_timeout: val.view_sync_timeout,
74            num_bootstrap: val.num_bootstrap,
75            builder_timeout: val.builder_timeout,
76            data_request_delay: val
77                .data_request_delay
78                .unwrap_or(Duration::from_millis(REQUEST_DATA_DELAY)),
79            builder_urls: val.builder_urls,
80            start_proposing_view: val.upgrade.start_proposing_view,
81            stop_proposing_view: val.upgrade.stop_proposing_view,
82            start_voting_view: val.upgrade.start_voting_view,
83            stop_voting_view: val.upgrade.stop_voting_view,
84            start_proposing_time: val.upgrade.start_proposing_time,
85            stop_proposing_time: val.upgrade.stop_proposing_time,
86            start_voting_time: val.upgrade.start_voting_time,
87            stop_voting_time: val.upgrade.stop_voting_time,
88            epoch_height: val.epoch_height,
89            epoch_start_block: val.epoch_start_block,
90        }
91    }
92}
93
94impl<TYPES: NodeType> HotShotConfigFile<TYPES> {
95    /// Creates a new `HotShotConfigFile` with 5 nodes and 10 DA nodes.
96    ///
97    /// # Panics
98    ///
99    /// Cannot panic, but will if `NonZeroUsize` is somehow an error.
100    #[must_use]
101    pub fn hotshot_config_5_nodes_10_da() -> Self {
102        let staked_da_nodes: usize = 5;
103
104        let mut known_da_nodes = Vec::new();
105
106        let gen_known_nodes_with_stake = (0..10)
107            .map(|node_id| {
108                let mut cur_validator_config: ValidatorConfig<TYPES> =
109                    ValidatorConfig::generated_from_seed_indexed(
110                        [0u8; 32],
111                        node_id,
112                        U256::from(1),
113                        false,
114                    );
115
116                if node_id < staked_da_nodes as u64 {
117                    known_da_nodes.push(cur_validator_config.public_config());
118                    cur_validator_config.is_da = true;
119                }
120
121                cur_validator_config.public_config()
122            })
123            .collect();
124
125        Self {
126            num_nodes_with_stake: NonZeroUsize::new(10).unwrap(),
127            start_threshold: (1, 1),
128            known_nodes_with_stake: gen_known_nodes_with_stake,
129            staked_da_nodes,
130            known_da_nodes,
131            fixed_leader_for_gpuvid: 1,
132            next_view_timeout: 10000,
133            view_sync_timeout: Duration::from_millis(1000),
134            num_bootstrap: 5,
135            builder_timeout: Duration::from_secs(10),
136            data_request_delay: Some(Duration::from_millis(REQUEST_DATA_DELAY)),
137            builder_urls: default_builder_urls(),
138            upgrade: UpgradeConfig::default(),
139            epoch_height: 0,
140            epoch_start_block: 0,
141        }
142    }
143}