Skip to main content

tycho_core/
global_config.rs

1use std::path::Path;
2
3use anyhow::Result;
4use serde::{Deserialize, Serialize};
5use tycho_network::{OverlayId, PeerInfo};
6use tycho_types::cell::HashBytes;
7use tycho_types::models::{BlockId, ConsensusConfig, GenesisInfo, ShardIdent};
8
9use crate::proto::blockchain::OverlayIdData;
10
11#[derive(Default, Clone, Debug, Serialize, Deserialize)]
12pub struct GlobalConfig {
13    pub bootstrap_peers: Vec<PeerInfo>,
14    pub zerostate: ZerostateId,
15    #[serde(default)]
16    pub mempool: Option<MempoolGlobalConfig>,
17}
18
19impl GlobalConfig {
20    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
21        tycho_util::serde_helpers::load_json_from_file(path)
22    }
23
24    pub fn validate(&self, now: u32) -> Result<()> {
25        for peer in &self.bootstrap_peers {
26            anyhow::ensure!(peer.verify(now), "invalid peer info for {}", peer.id);
27        }
28        Ok(())
29    }
30}
31
32#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
33pub struct ZerostateId {
34    #[serde(default)]
35    pub seqno: u32,
36    pub root_hash: HashBytes,
37    pub file_hash: HashBytes,
38}
39
40impl ZerostateId {
41    pub fn as_block_id(&self) -> BlockId {
42        BlockId {
43            shard: ShardIdent::MASTERCHAIN,
44            seqno: self.seqno,
45            root_hash: self.root_hash,
46            file_hash: self.file_hash,
47        }
48    }
49
50    pub fn compute_public_overlay_id(&self) -> OverlayId {
51        OverlayId(tl_proto::hash(OverlayIdData {
52            zerostate_root_hash: self.root_hash.0,
53            zerostate_file_hash: self.file_hash.0,
54        }))
55    }
56}
57
58/// Default zeros for start round and genesis time are the same in
59/// [`ConsensusInfo`](tycho_types::models::ConsensusInfo).
60///
61/// This will replace genesis from master chain data only if this has time greater than in mc.
62/// Also, this genesis must have round not less than in last applied mc block.
63#[derive(Clone, Debug, Serialize, Deserialize)]
64pub struct MempoolGlobalConfig {
65    /// start round must be set to the `processed_to_anchor_id` from last applied master chain block
66    /// actual genesis round may be greater (or still equal) after alignment;
67    /// millis must be set not less than last applied mc block time, or better use actual time
68    #[serde(flatten)]
69    pub genesis_info: GenesisInfo,
70    /// To restart a stale consensus with a new config, the majority of nodes has to provide
71    /// new common genesis and settings in a global config file.
72    /// Then an external message must be sent to update blockchain config contract ASAP in order to
73    /// issue a key block with updated consensus config and persist it in blockchain state.
74    /// Until then "mempool" part of the global config file must contain all the same data.
75    ///
76    /// It's because a block can include any settings only when config contract is called,
77    /// otherwise contract state will not match.
78    /// Quite the opposite is a recovery genesis info: it is immediately included
79    /// into the first master chain block as an "extra" part, and makes it a key block.
80    #[serde(flatten)]
81    pub consensus_config: Option<ConsensusConfig>,
82}