Skip to main content

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    /// Whether validators emit slim (ancestor-compressed) blocks on the block
26    /// subscription stream.
27    slim_block_propagation_enabled: bool,
28    transaction_voting_enabled: bool,
29    num_leaders_per_round: Option<usize>,
30    bad_nodes_stake_threshold: u64,
31    /// Whether to enable V3 logic.
32    enable_v3: bool,
33    /// Number of recent commits retained for leader schedule sliding-window scoring.
34    leader_schedule_window_size: u32,
35    /// Number of commit indices that use the same Mysticeti v3 leader schedule.
36    leader_schedule_update_interval: u32,
37}
38
39impl Default for ConsensusProtocolConfig {
40    fn default() -> Self {
41        Self {
42            protocol_version: 0,
43            chain: ChainType::Unknown,
44            max_transaction_size_bytes: 256 * 1024,
45            max_transactions_in_block_bytes: if cfg!(msim) { 256 * 1024 } else { 512 * 1024 },
46            max_num_transactions_in_block: if cfg!(msim) { 8 } else { 512 },
47            gc_depth: 0,
48            slim_block_propagation_enabled: false,
49            transaction_voting_enabled: false,
50            num_leaders_per_round: None,
51            bad_nodes_stake_threshold: 0,
52            enable_v3: false,
53            leader_schedule_window_size: 600,
54            leader_schedule_update_interval: 60,
55        }
56    }
57}
58
59impl ConsensusProtocolConfig {
60    pub fn new(
61        protocol_version: u64,
62        chain: ChainType,
63        max_transaction_size_bytes: u64,
64        max_transactions_in_block_bytes: u64,
65        max_num_transactions_in_block: u64,
66        gc_depth: u32,
67        slim_block_propagation_enabled: bool,
68        transaction_voting_enabled: bool,
69        num_leaders_per_round: Option<usize>,
70        bad_nodes_stake_threshold: u64,
71        enable_v3: bool,
72        leader_schedule_window_size: u32,
73        leader_schedule_update_interval: u32,
74    ) -> Self {
75        Self {
76            protocol_version,
77            chain,
78            max_transaction_size_bytes,
79            max_transactions_in_block_bytes,
80            max_num_transactions_in_block,
81            gc_depth,
82            slim_block_propagation_enabled,
83            transaction_voting_enabled,
84            num_leaders_per_round,
85            bad_nodes_stake_threshold,
86            enable_v3,
87            leader_schedule_window_size,
88            leader_schedule_update_interval,
89        }
90    }
91
92    /// Returns a config with all features enabled and reasonable defaults
93    /// for use in tests.
94    pub fn for_testing() -> Self {
95        Self {
96            protocol_version: u64::MAX,
97            chain: ChainType::Unknown,
98            max_transaction_size_bytes: 256 * 1024,
99            max_transactions_in_block_bytes: if cfg!(msim) { 256 * 1024 } else { 512 * 1024 },
100            max_num_transactions_in_block: if cfg!(msim) { 8 } else { 512 },
101            gc_depth: if cfg!(msim) { 6 } else { 60 },
102            slim_block_propagation_enabled: false,
103            transaction_voting_enabled: true,
104            num_leaders_per_round: Some(1),
105            bad_nodes_stake_threshold: 30,
106            enable_v3: false,
107            leader_schedule_window_size: 600,
108            leader_schedule_update_interval: 60,
109        }
110    }
111
112    // Getter methods
113
114    pub fn protocol_version(&self) -> u64 {
115        self.protocol_version
116    }
117
118    pub fn chain(&self) -> ChainType {
119        self.chain
120    }
121
122    pub fn max_transaction_size_bytes(&self) -> u64 {
123        self.max_transaction_size_bytes
124    }
125
126    pub fn max_transactions_in_block_bytes(&self) -> u64 {
127        self.max_transactions_in_block_bytes
128    }
129
130    pub fn max_num_transactions_in_block(&self) -> u64 {
131        self.max_num_transactions_in_block
132    }
133
134    pub fn gc_depth(&self) -> u32 {
135        self.gc_depth
136    }
137
138    pub fn slim_block_propagation_enabled(&self) -> bool {
139        self.slim_block_propagation_enabled
140    }
141
142    pub fn transaction_voting_enabled(&self) -> bool {
143        self.transaction_voting_enabled
144    }
145
146    pub fn num_leaders_per_round(&self) -> Option<usize> {
147        self.num_leaders_per_round
148    }
149
150    pub fn bad_nodes_stake_threshold(&self) -> u64 {
151        self.bad_nodes_stake_threshold
152    }
153
154    pub fn enable_v3(&self) -> bool {
155        self.enable_v3
156    }
157
158    // Clamped to ≥ 1: downstream code (LeaderScheduleV3) uses these as window
159    // sizes and modulus operands, so a 0 config would divide by zero or be
160    // an empty window. Treat 0 as "effectively 1" instead of panicking.
161    pub fn leader_schedule_window_size(&self) -> u32 {
162        self.leader_schedule_window_size.max(1)
163    }
164
165    pub fn leader_schedule_update_interval(&self) -> u32 {
166        self.leader_schedule_update_interval.max(1)
167    }
168
169    // Test setter methods
170
171    pub fn set_gc_depth_for_testing(&mut self, val: u32) {
172        self.gc_depth = val;
173    }
174
175    pub fn set_slim_block_propagation_enabled_for_testing(&mut self, val: bool) {
176        self.slim_block_propagation_enabled = val;
177    }
178
179    pub fn set_transaction_voting_enabled_for_testing(&mut self, val: bool) {
180        self.transaction_voting_enabled = val;
181    }
182
183    pub fn set_max_transaction_size_bytes_for_testing(&mut self, val: u64) {
184        self.max_transaction_size_bytes = val;
185    }
186
187    pub fn set_max_transactions_in_block_bytes_for_testing(&mut self, val: u64) {
188        self.max_transactions_in_block_bytes = val;
189    }
190
191    pub fn set_max_num_transactions_in_block_for_testing(&mut self, val: u64) {
192        self.max_num_transactions_in_block = val;
193    }
194
195    pub fn set_bad_nodes_stake_threshold_for_testing(&mut self, val: u64) {
196        self.bad_nodes_stake_threshold = val;
197    }
198
199    pub fn set_num_leaders_per_round_for_testing(&mut self, val: Option<usize>) {
200        self.num_leaders_per_round = val;
201    }
202
203    pub fn set_enable_v3_for_testing(&mut self, val: bool) {
204        self.enable_v3 = val;
205    }
206
207    pub fn set_leader_schedule_window_size_for_testing(&mut self, val: u32) {
208        self.leader_schedule_window_size = val;
209    }
210
211    pub fn set_leader_schedule_update_interval_for_testing(&mut self, val: u32) {
212        self.leader_schedule_update_interval = val;
213    }
214}