consensus_config/
consensus_protocol_config.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4/// Identifies the chain of the network.
5/// Mirrors `sui_protocol_config::Chain`.
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
7pub enum ChainType {
8    #[default]
9    Unknown,
10    Testnet,
11    Mainnet,
12}
13
14/// Protocol configuration values that consensus reads. This is a standalone
15/// struct so that `consensus-core` does not depend on `sui-protocol-config`
16/// (and transitively on the Move VM).
17#[derive(Clone, Debug)]
18pub struct ConsensusProtocolConfig {
19    protocol_version: u64,
20    chain: ChainType,
21    max_transaction_size_bytes: u64,
22    max_transactions_in_block_bytes: u64,
23    max_num_transactions_in_block: u64,
24    gc_depth: u32,
25    transaction_voting_enabled: bool,
26    num_leaders_per_round: Option<usize>,
27    bad_nodes_stake_threshold: u64,
28    /// Whether to enable V3 logic.
29    enable_v3: bool,
30    /// Number of recent commits retained for leader schedule sliding-window scoring.
31    leader_schedule_window_size: u32,
32    /// Number of commit indices that use the same Mysticeti v3 leader schedule.
33    leader_schedule_update_interval: u32,
34}
35
36impl Default for ConsensusProtocolConfig {
37    fn default() -> Self {
38        Self {
39            protocol_version: 0,
40            chain: ChainType::Unknown,
41            max_transaction_size_bytes: 256 * 1024,
42            max_transactions_in_block_bytes: if cfg!(msim) { 256 * 1024 } else { 512 * 1024 },
43            max_num_transactions_in_block: if cfg!(msim) { 8 } else { 512 },
44            gc_depth: 0,
45            transaction_voting_enabled: false,
46            num_leaders_per_round: None,
47            bad_nodes_stake_threshold: 0,
48            enable_v3: false,
49            leader_schedule_window_size: 600,
50            leader_schedule_update_interval: 60,
51        }
52    }
53}
54
55impl ConsensusProtocolConfig {
56    pub fn new(
57        protocol_version: u64,
58        chain: ChainType,
59        max_transaction_size_bytes: u64,
60        max_transactions_in_block_bytes: u64,
61        max_num_transactions_in_block: u64,
62        gc_depth: u32,
63        transaction_voting_enabled: bool,
64        num_leaders_per_round: Option<usize>,
65        bad_nodes_stake_threshold: u64,
66        enable_v3: bool,
67        leader_schedule_window_size: u32,
68        leader_schedule_update_interval: u32,
69    ) -> Self {
70        Self {
71            protocol_version,
72            chain,
73            max_transaction_size_bytes,
74            max_transactions_in_block_bytes,
75            max_num_transactions_in_block,
76            gc_depth,
77            transaction_voting_enabled,
78            num_leaders_per_round,
79            bad_nodes_stake_threshold,
80            enable_v3,
81            leader_schedule_window_size,
82            leader_schedule_update_interval,
83        }
84    }
85
86    /// Returns a config with all features enabled and reasonable defaults
87    /// for use in tests.
88    pub fn for_testing() -> Self {
89        Self {
90            protocol_version: u64::MAX,
91            chain: ChainType::Unknown,
92            max_transaction_size_bytes: 256 * 1024,
93            max_transactions_in_block_bytes: if cfg!(msim) { 256 * 1024 } else { 512 * 1024 },
94            max_num_transactions_in_block: if cfg!(msim) { 8 } else { 512 },
95            gc_depth: if cfg!(msim) { 6 } else { 60 },
96            transaction_voting_enabled: true,
97            num_leaders_per_round: Some(1),
98            bad_nodes_stake_threshold: 30,
99            enable_v3: false,
100            leader_schedule_window_size: 600,
101            leader_schedule_update_interval: 60,
102        }
103    }
104
105    // Getter methods
106
107    pub fn protocol_version(&self) -> u64 {
108        self.protocol_version
109    }
110
111    pub fn chain(&self) -> ChainType {
112        self.chain
113    }
114
115    pub fn max_transaction_size_bytes(&self) -> u64 {
116        self.max_transaction_size_bytes
117    }
118
119    pub fn max_transactions_in_block_bytes(&self) -> u64 {
120        self.max_transactions_in_block_bytes
121    }
122
123    pub fn max_num_transactions_in_block(&self) -> u64 {
124        self.max_num_transactions_in_block
125    }
126
127    pub fn gc_depth(&self) -> u32 {
128        self.gc_depth
129    }
130
131    pub fn transaction_voting_enabled(&self) -> bool {
132        self.transaction_voting_enabled
133    }
134
135    pub fn num_leaders_per_round(&self) -> Option<usize> {
136        self.num_leaders_per_round
137    }
138
139    pub fn bad_nodes_stake_threshold(&self) -> u64 {
140        self.bad_nodes_stake_threshold
141    }
142
143    pub fn enable_v3(&self) -> bool {
144        self.enable_v3
145    }
146
147    // Clamped to ≥ 1: downstream code (LeaderScheduleV3) uses these as window
148    // sizes and modulus operands, so a 0 config would divide by zero or be
149    // an empty window. Treat 0 as "effectively 1" instead of panicking.
150    pub fn leader_schedule_window_size(&self) -> u32 {
151        self.leader_schedule_window_size.max(1)
152    }
153
154    pub fn leader_schedule_update_interval(&self) -> u32 {
155        self.leader_schedule_update_interval.max(1)
156    }
157
158    // Test setter methods
159
160    pub fn set_gc_depth_for_testing(&mut self, val: u32) {
161        self.gc_depth = val;
162    }
163
164    pub fn set_transaction_voting_enabled_for_testing(&mut self, val: bool) {
165        self.transaction_voting_enabled = val;
166    }
167
168    pub fn set_max_transaction_size_bytes_for_testing(&mut self, val: u64) {
169        self.max_transaction_size_bytes = val;
170    }
171
172    pub fn set_max_transactions_in_block_bytes_for_testing(&mut self, val: u64) {
173        self.max_transactions_in_block_bytes = val;
174    }
175
176    pub fn set_max_num_transactions_in_block_for_testing(&mut self, val: u64) {
177        self.max_num_transactions_in_block = val;
178    }
179
180    pub fn set_bad_nodes_stake_threshold_for_testing(&mut self, val: u64) {
181        self.bad_nodes_stake_threshold = val;
182    }
183
184    pub fn set_num_leaders_per_round_for_testing(&mut self, val: Option<usize>) {
185        self.num_leaders_per_round = val;
186    }
187
188    pub fn set_enable_v3_for_testing(&mut self, val: bool) {
189        self.enable_v3 = val;
190    }
191
192    pub fn set_leader_schedule_window_size_for_testing(&mut self, val: u32) {
193        self.leader_schedule_window_size = val;
194    }
195
196    pub fn set_leader_schedule_update_interval_for_testing(&mut self, val: u32) {
197        self.leader_schedule_update_interval = val;
198    }
199}