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