Skip to content

Commit 4dffddb

Browse files
halfpriceebmifa
andauthored
Create a separate congestion control consensus commit limit for Mysticeti (#18648)
## Description Since mysticeti has different commit rate than Narwhal, we want to use different transaction count limit for shared object congestion control in consensus commit. Therefore, I created a different config for mysticeti, and the consensus handler will choose to use different limit based on the current consensus algorithm. We also turn on shared object congestion control on testnet. ## Test plan simtest updated cluster testing --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: --------- Co-authored-by: Eugene Boguslavsky <[email protected]>
1 parent b677505 commit 4dffddb

File tree

12 files changed

+96
-41
lines changed

12 files changed

+96
-41
lines changed

crates/sui-benchmark/tests/simtest.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,15 +466,21 @@ mod test {
466466
config.set_per_object_congestion_control_mode_for_testing(mode);
467467
match mode {
468468
PerObjectCongestionControlMode::None => panic!("Congestion control mode cannot be None in test_simulated_load_shared_object_congestion_control"),
469-
PerObjectCongestionControlMode::TotalGasBudget =>
470-
config.set_max_accumulated_txn_cost_per_object_in_checkpoint_for_testing(
471-
checkpoint_budget_factor
469+
PerObjectCongestionControlMode::TotalGasBudget => {
470+
let total_gas_limit = checkpoint_budget_factor
472471
* DEFAULT_VALIDATOR_GAS_PRICE
473-
* TEST_ONLY_GAS_UNIT_FOR_HEAVY_COMPUTATION_STORAGE,
474-
),
475-
PerObjectCongestionControlMode::TotalTxCount => config.set_max_accumulated_txn_cost_per_object_in_checkpoint_for_testing(
476-
txn_count_limit
477-
),
472+
* TEST_ONLY_GAS_UNIT_FOR_HEAVY_COMPUTATION_STORAGE;
473+
config.set_max_accumulated_txn_cost_per_object_in_narwhal_commit_for_testing(total_gas_limit);
474+
config.set_max_accumulated_txn_cost_per_object_in_mysticeti_commit_for_testing(total_gas_limit);
475+
},
476+
PerObjectCongestionControlMode::TotalTxCount => {
477+
config.set_max_accumulated_txn_cost_per_object_in_narwhal_commit_for_testing(
478+
txn_count_limit
479+
);
480+
config.set_max_accumulated_txn_cost_per_object_in_mysticeti_commit_for_testing(
481+
txn_count_limit
482+
);
483+
},
478484
}
479485
config.set_max_deferral_rounds_for_congestion_control_for_testing(max_deferral_rounds);
480486
config

crates/sui-core/src/authority/authority_per_epoch_store.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
2020
use std::future::Future;
2121
use std::path::{Path, PathBuf};
2222
use std::sync::Arc;
23-
use sui_config::node::ExpensiveSafetyCheckConfig;
23+
use sui_config::node::{ConsensusProtocol, ExpensiveSafetyCheckConfig};
2424
use sui_macros::fail_point_arg;
2525
use sui_types::accumulator::Accumulator;
2626
use sui_types::authenticator_state::{get_authenticator_state, ActiveJwk};
@@ -66,6 +66,7 @@ use crate::consensus_handler::{
6666
ConsensusCommitInfo, SequencedConsensusTransaction, SequencedConsensusTransactionKey,
6767
SequencedConsensusTransactionKind, VerifiedSequencedConsensusTransaction,
6868
};
69+
use crate::consensus_manager::ConsensusManager;
6970
use crate::epoch::epoch_metrics::EpochMetrics;
7071
use crate::epoch::randomness::{
7172
DkgStatus, RandomnessManager, RandomnessReporter, VersionedProcessedMessage,
@@ -1748,6 +1749,17 @@ impl AuthorityPerEpochStore {
17481749
.collect::<Result<Vec<_>, _>>()?)
17491750
}
17501751

1752+
fn get_max_accumulated_txn_cost_per_object_in_commit(&self) -> Option<u64> {
1753+
match ConsensusManager::get_consensus_protocol_in_epoch(self) {
1754+
ConsensusProtocol::Narwhal => self
1755+
.protocol_config()
1756+
.max_accumulated_txn_cost_per_object_in_narwhal_commit_as_option(),
1757+
ConsensusProtocol::Mysticeti => self
1758+
.protocol_config()
1759+
.max_accumulated_txn_cost_per_object_in_mysticeti_commit_as_option(),
1760+
}
1761+
}
1762+
17511763
fn should_defer(
17521764
&self,
17531765
cert: &VerifiedExecutableTransaction,
@@ -1774,15 +1786,14 @@ impl AuthorityPerEpochStore {
17741786
));
17751787
}
17761788

1777-
if let Some(max_accumulated_txn_cost_per_object_in_checkpoint) = self
1778-
.protocol_config()
1779-
.max_accumulated_txn_cost_per_object_in_checkpoint_as_option()
1789+
if let Some(max_accumulated_txn_cost_per_object_in_commit) =
1790+
self.get_max_accumulated_txn_cost_per_object_in_commit()
17801791
{
17811792
// Defer transaction if it uses shared objects that are congested.
17821793
if let Some((deferral_key, congested_objects)) = shared_object_congestion_tracker
17831794
.should_defer_due_to_object_congestion(
17841795
cert,
1785-
max_accumulated_txn_cost_per_object_in_checkpoint,
1796+
max_accumulated_txn_cost_per_object_in_commit,
17861797
previously_deferred_tx_digests,
17871798
commit_round,
17881799
)

crates/sui-core/src/authority/shared_object_congestion_tracker.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl SharedObjectCongestionTracker {
7474
pub fn should_defer_due_to_object_congestion(
7575
&self,
7676
cert: &VerifiedExecutableTransaction,
77-
max_accumulated_txn_cost_per_object_in_checkpoint: u64,
77+
max_accumulated_txn_cost_per_object_in_commit: u64,
7878
previously_deferred_tx_digests: &HashMap<TransactionDigest, DeferralKey>,
7979
commit_round: Round,
8080
) -> Option<(DeferralKey, Vec<ObjectID>)> {
@@ -89,7 +89,7 @@ impl SharedObjectCongestionTracker {
8989
}
9090
let start_cost = self.compute_tx_start_at_cost(&shared_input_objects);
9191

92-
if start_cost + tx_cost <= max_accumulated_txn_cost_per_object_in_checkpoint {
92+
if start_cost + tx_cost <= max_accumulated_txn_cost_per_object_in_commit {
9393
return None;
9494
}
9595

@@ -273,8 +273,8 @@ mod object_cost_tests {
273273

274274
let tx_gas_budget = 100;
275275

276-
// Set max_accumulated_txn_cost_per_object_in_checkpoint to only allow 1 transaction to go through.
277-
let max_accumulated_txn_cost_per_object_in_checkpoint = match mode {
276+
// Set max_accumulated_txn_cost_per_object_in_commit to only allow 1 transaction to go through.
277+
let max_accumulated_txn_cost_per_object_in_commit = match mode {
278278
PerObjectCongestionControlMode::None => unreachable!(),
279279
PerObjectCongestionControlMode::TotalGasBudget => tx_gas_budget + 1,
280280
PerObjectCongestionControlMode::TotalTxCount => 2,
@@ -310,7 +310,7 @@ mod object_cost_tests {
310310
if let Some((_, congested_objects)) = shared_object_congestion_tracker
311311
.should_defer_due_to_object_congestion(
312312
&tx,
313-
max_accumulated_txn_cost_per_object_in_checkpoint,
313+
max_accumulated_txn_cost_per_object_in_commit,
314314
&HashMap::new(),
315315
0,
316316
)
@@ -328,7 +328,7 @@ mod object_cost_tests {
328328
assert!(shared_object_congestion_tracker
329329
.should_defer_due_to_object_congestion(
330330
&tx,
331-
max_accumulated_txn_cost_per_object_in_checkpoint,
331+
max_accumulated_txn_cost_per_object_in_commit,
332332
&HashMap::new(),
333333
0,
334334
)
@@ -345,7 +345,7 @@ mod object_cost_tests {
345345
if let Some((_, congested_objects)) = shared_object_congestion_tracker
346346
.should_defer_due_to_object_congestion(
347347
&tx,
348-
max_accumulated_txn_cost_per_object_in_checkpoint,
348+
max_accumulated_txn_cost_per_object_in_commit,
349349
&HashMap::new(),
350350
0,
351351
)
@@ -370,7 +370,7 @@ mod object_cost_tests {
370370
let shared_obj_0 = ObjectID::random();
371371
let tx = build_transaction(&[(shared_obj_0, true)], 100);
372372
// Make should_defer_due_to_object_congestion always defer transactions.
373-
let max_accumulated_txn_cost_per_object_in_checkpoint = 0;
373+
let max_accumulated_txn_cost_per_object_in_commit = 0;
374374
let shared_object_congestion_tracker = SharedObjectCongestionTracker::new(mode);
375375

376376
// Insert a random pre-existing transaction.
@@ -392,7 +392,7 @@ mod object_cost_tests {
392392
_,
393393
)) = shared_object_congestion_tracker.should_defer_due_to_object_congestion(
394394
&tx,
395-
max_accumulated_txn_cost_per_object_in_checkpoint,
395+
max_accumulated_txn_cost_per_object_in_commit,
396396
&previously_deferred_tx_digests,
397397
10,
398398
) {
@@ -419,7 +419,7 @@ mod object_cost_tests {
419419
_,
420420
)) = shared_object_congestion_tracker.should_defer_due_to_object_congestion(
421421
&tx,
422-
max_accumulated_txn_cost_per_object_in_checkpoint,
422+
max_accumulated_txn_cost_per_object_in_commit,
423423
&previously_deferred_tx_digests,
424424
10,
425425
) {
@@ -447,7 +447,7 @@ mod object_cost_tests {
447447
_,
448448
)) = shared_object_congestion_tracker.should_defer_due_to_object_congestion(
449449
&tx,
450-
max_accumulated_txn_cost_per_object_in_checkpoint,
450+
max_accumulated_txn_cost_per_object_in_commit,
451451
&previously_deferred_tx_digests,
452452
10,
453453
) {

crates/sui-core/src/consensus_manager/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ impl ConsensusManager {
152152
}
153153

154154
// Picks the consensus protocol based on the protocol config and the epoch.
155-
fn pick_protocol(&self, epoch_store: &AuthorityPerEpochStore) -> ConsensusProtocol {
155+
pub fn get_consensus_protocol_in_epoch(
156+
epoch_store: &AuthorityPerEpochStore,
157+
) -> ConsensusProtocol {
156158
let protocol_config = epoch_store.protocol_config();
157159
if protocol_config.version >= ProtocolVersion::new(36) {
158160
if let Ok(consensus_choice) = std::env::var("CONSENSUS") {
@@ -205,7 +207,7 @@ impl ConsensusManagerTrait for ConsensusManager {
205207
"Cannot start consensus. ConsensusManager protocol {index} is already running"
206208
);
207209
});
208-
let protocol = self.pick_protocol(&epoch_store);
210+
let protocol = Self::get_consensus_protocol_in_epoch(&epoch_store);
209211
info!("Starting consensus protocol {protocol:?} ...");
210212
match protocol {
211213
ConsensusProtocol::Narwhal => {

crates/sui-core/src/unit_tests/authority_tests.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5812,10 +5812,17 @@ async fn test_consensus_handler_per_object_congestion_control(
58125812
PerObjectCongestionControlMode::None => unreachable!(),
58135813
PerObjectCongestionControlMode::TotalGasBudget => {
58145814
protocol_config
5815-
.set_max_accumulated_txn_cost_per_object_in_checkpoint_for_testing(200_000_000);
5815+
.set_max_accumulated_txn_cost_per_object_in_narwhal_commit_for_testing(200_000_000);
5816+
protocol_config
5817+
.set_max_accumulated_txn_cost_per_object_in_mysticeti_commit_for_testing(
5818+
200_000_000,
5819+
);
58165820
}
58175821
PerObjectCongestionControlMode::TotalTxCount => {
5818-
protocol_config.set_max_accumulated_txn_cost_per_object_in_checkpoint_for_testing(2);
5822+
protocol_config
5823+
.set_max_accumulated_txn_cost_per_object_in_narwhal_commit_for_testing(2);
5824+
protocol_config
5825+
.set_max_accumulated_txn_cost_per_object_in_mysticeti_commit_for_testing(2);
58195826
}
58205827
}
58215828
protocol_config.set_max_deferral_rounds_for_congestion_control_for_testing(1000); // Set to a large number so that we don't hit this limit.
@@ -6034,7 +6041,10 @@ async fn test_consensus_handler_congestion_control_transaction_cancellation() {
60346041
protocol_config.set_per_object_congestion_control_mode_for_testing(
60356042
PerObjectCongestionControlMode::TotalGasBudget,
60366043
);
6037-
protocol_config.set_max_accumulated_txn_cost_per_object_in_checkpoint_for_testing(100_000_000);
6044+
protocol_config
6045+
.set_max_accumulated_txn_cost_per_object_in_narwhal_commit_for_testing(100_000_000);
6046+
protocol_config
6047+
.set_max_accumulated_txn_cost_per_object_in_mysticeti_commit_for_testing(100_000_000);
60386048
protocol_config.set_max_deferral_rounds_for_congestion_control_for_testing(2);
60396049
let authority = TestAuthorityBuilder::new()
60406050
.with_reference_gas_price(1000)

crates/sui-core/src/unit_tests/congestion_control_tests.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ impl TestSetup {
5656
);
5757

5858
// Set shared object congestion control such that it only allows 1 transaction to go through.
59-
let max_accumulated_txn_cost_per_object_in_checkpoint =
59+
let max_accumulated_txn_cost_per_object_in_commit =
6060
TEST_ONLY_GAS_PRICE * TEST_ONLY_GAS_UNIT;
61-
protocol_config.set_max_accumulated_txn_cost_per_object_in_checkpoint_for_testing(
62-
max_accumulated_txn_cost_per_object_in_checkpoint,
61+
protocol_config.set_max_accumulated_txn_cost_per_object_in_narwhal_commit_for_testing(
62+
max_accumulated_txn_cost_per_object_in_commit,
63+
);
64+
protocol_config.set_max_accumulated_txn_cost_per_object_in_mysticeti_commit_for_testing(
65+
max_accumulated_txn_cost_per_object_in_commit,
6366
);
6467

6568
// Set max deferral rounds to 0 to testr cancellation. All deferred transactions will be cancelled.

crates/sui-open-rpc/spec/openrpc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,8 @@
16611661
"hmac_hmac_sha3_256_input_cost_per_byte": {
16621662
"u64": "2"
16631663
},
1664-
"max_accumulated_txn_cost_per_object_in_checkpoint": null,
1664+
"max_accumulated_txn_cost_per_object_in_mysticeti_commit": null,
1665+
"max_accumulated_txn_cost_per_object_in_narwhal_commit": null,
16651666
"max_age_of_jwk_in_epochs": null,
16661667
"max_arguments": {
16671668
"u32": "512"

crates/sui-protocol-config/src/lib.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ const MAX_PROTOCOL_VERSION: u64 = 53;
163163
// Enable deny list v2 on testnet and mainnet.
164164
// Version 53: Add feature flag to decide whether to attempt to finalize bridge committee
165165
// Enable consensus commit prologue V3 on testnet.
166+
// Turn on shared object congestion control in testnet.
166167

167168
#[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
168169
pub struct ProtocolVersion(u64);
@@ -1147,9 +1148,11 @@ pub struct ProtocolConfig {
11471148
/// The maximum size of transactions included in a consensus proposed block
11481149
consensus_max_transactions_in_block_bytes: Option<u64>,
11491150

1150-
/// The max accumulated txn execution cost per object in a checkpoint. Transactions
1151+
/// The max accumulated txn execution cost per object in a Narwhal commit. Transactions
11511152
/// in a checkpoint will be deferred once their touch shared objects hit this limit.
1152-
max_accumulated_txn_cost_per_object_in_checkpoint: Option<u64>,
1153+
/// This config is meant to be used when consensus protocol is Narwhal, where each
1154+
/// consensus commit corresponding to 1 checkpoint (or 2 if randomness is enabled)
1155+
max_accumulated_txn_cost_per_object_in_narwhal_commit: Option<u64>,
11531156

11541157
/// The max number of consensus rounds a transaction can be deferred due to shared object congestion.
11551158
/// Transactions will be cancelled after this many rounds.
@@ -1168,6 +1171,12 @@ pub struct ProtocolConfig {
11681171
// Note: this is not a feature flag because we want to distinguish between
11691172
// `None` and `Some(false)`, as committee was already finalized on Testnet.
11701173
bridge_should_try_to_finalize_committee: Option<bool>,
1174+
1175+
/// The max accumulated txn execution cost per object in a mysticeti. Transactions
1176+
/// in a commit will be deferred once their touch shared objects hit this limit.
1177+
/// This config plays the same role as `max_accumulated_txn_cost_per_object_in_narwhal_commit`
1178+
/// but for mysticeti commits due to that mysticeti has higher commit rate.
1179+
max_accumulated_txn_cost_per_object_in_mysticeti_commit: Option<u64>,
11711180
}
11721181

11731182
// feature flags
@@ -1937,7 +1946,7 @@ impl ProtocolConfig {
19371946

19381947
consensus_max_transactions_in_block_bytes: None,
19391948

1940-
max_accumulated_txn_cost_per_object_in_checkpoint: None,
1949+
max_accumulated_txn_cost_per_object_in_narwhal_commit: None,
19411950

19421951
max_deferral_rounds_for_congestion_control: None,
19431952

@@ -1948,6 +1957,8 @@ impl ProtocolConfig {
19481957
max_soft_bundle_size: None,
19491958

19501959
bridge_should_try_to_finalize_committee: None,
1960+
1961+
max_accumulated_txn_cost_per_object_in_mysticeti_commit: None,
19511962
// When adding a new constant, set it to None in the earliest version, like this:
19521963
// new_constant: None,
19531964
};
@@ -2470,7 +2481,7 @@ impl ProtocolConfig {
24702481

24712482
// Turn on shared object congestion control in devnet.
24722483
if chain != Chain::Testnet && chain != Chain::Mainnet {
2473-
cfg.max_accumulated_txn_cost_per_object_in_checkpoint = Some(100);
2484+
cfg.max_accumulated_txn_cost_per_object_in_narwhal_commit = Some(100);
24742485
cfg.feature_flags.per_object_congestion_control_mode =
24752486
PerObjectCongestionControlMode::TotalTxCount;
24762487
}
@@ -2515,6 +2526,14 @@ impl ProtocolConfig {
25152526
if chain == Chain::Unknown {
25162527
cfg.feature_flags.authority_capabilities_v2 = true;
25172528
}
2529+
2530+
// Turns on shared object congestion control on testnet.
2531+
if chain != Chain::Mainnet {
2532+
cfg.max_accumulated_txn_cost_per_object_in_narwhal_commit = Some(100);
2533+
cfg.max_accumulated_txn_cost_per_object_in_mysticeti_commit = Some(10);
2534+
cfg.feature_flags.per_object_congestion_control_mode =
2535+
PerObjectCongestionControlMode::TotalTxCount;
2536+
}
25182537
}
25192538
// Use this template when making changes:
25202539
//

crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_53.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ feature_flags:
4545
enable_coin_deny_list: true
4646
enable_group_ops_native_functions: true
4747
reject_mutable_random_on_entry_functions: true
48+
per_object_congestion_control_mode: TotalTxCount
4849
consensus_choice: Mysticeti
4950
consensus_network: Tonic
5051
zklogin_max_epoch_upper_bound_delta: 30
@@ -282,9 +283,11 @@ random_beacon_min_round_interval_ms: 200
282283
random_beacon_dkg_version: 1
283284
consensus_max_transaction_size_bytes: 262144
284285
consensus_max_transactions_in_block_bytes: 6291456
286+
max_accumulated_txn_cost_per_object_in_narwhal_commit: 100
285287
max_deferral_rounds_for_congestion_control: 10
286288
min_checkpoint_interval_ms: 200
287289
checkpoint_summary_version_specific_data: 1
288290
max_soft_bundle_size: 5
289291
bridge_should_try_to_finalize_committee: true
292+
max_accumulated_txn_cost_per_object_in_mysticeti_commit: 10
290293

crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_52.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ random_beacon_min_round_interval_ms: 200
291291
random_beacon_dkg_version: 1
292292
consensus_max_transaction_size_bytes: 262144
293293
consensus_max_transactions_in_block_bytes: 6291456
294-
max_accumulated_txn_cost_per_object_in_checkpoint: 100
294+
max_accumulated_txn_cost_per_object_in_narwhal_commit: 100
295295
max_deferral_rounds_for_congestion_control: 10
296296
min_checkpoint_interval_ms: 200
297297
checkpoint_summary_version_specific_data: 1

0 commit comments

Comments
 (0)