Skip to content

Commit

Permalink
Implement transaction count based shared object congestion control (M…
Browse files Browse the repository at this point in the history
…ystenLabs#17832)

## Description 

This PR adds another mode in `PerObjectCongestionControlMode`,
`TotalTxCount`, which uses total transaction count
that operate on a object to limit the critical path of shared object
transaction in a consensus commit.

The logic is the same as
`PerObjectCongestionControlMode::TotalGasBudget`, except that now a
transaction
cost is 1 instead of the gas budget.

## Test plan 

Unit test.
Integration test.

---

## 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:
  • Loading branch information
halfprice authored May 30, 2024
1 parent 1bffd36 commit 1c0270e
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 144 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/sui-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ expect-test.workspace = true
fs_extra.workspace = true
more-asserts.workspace = true
pretty_assertions.workspace = true
rstest.workspace = true
serde-reflection.workspace = true
serde_yaml.workspace = true
num-bigint = "0.4.4"
Expand Down
77 changes: 30 additions & 47 deletions crates/sui-core/src/authority/authority_per_epoch_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ use prometheus::IntCounter;
use std::str::FromStr;
use sui_execution::{self, Executor};
use sui_macros::fail_point;
use sui_protocol_config::{Chain, PerObjectCongestionControlMode, ProtocolConfig, ProtocolVersion};
use sui_protocol_config::{Chain, ProtocolConfig, ProtocolVersion};
use sui_storage::mutex_table::{MutexGuard, MutexTable};
use sui_types::effects::TransactionEffects;
use sui_types::executable_transaction::{
Expand Down Expand Up @@ -1617,45 +1617,28 @@ impl AuthorityPerEpochStore {
));
}

// Defer transaction if it uses shared objects that are congested.
match self.protocol_config().per_object_congestion_control_mode() {
PerObjectCongestionControlMode::None => None,
PerObjectCongestionControlMode::TotalGasBudget => {
if let Some((deferral_key, congested_objects)) = shared_object_congestion_tracker
.should_defer_due_to_object_congestion(
cert,
self.protocol_config()
.max_accumulated_txn_cost_per_object_in_checkpoint(),
previously_deferred_tx_digests,
commit_round,
)
{
Some((
deferral_key,
DeferralReason::SharedObjectCongestion(congested_objects),
))
} else {
None
}
}
}
}

// Update shared objects' execution cost used in `cert` using `cert`'s execution cost.
// This is called when `cert` is scheduled for execution.
fn update_object_execution_cost(
&self,
cert: &VerifiedExecutableTransaction,
shared_object_congestion_tracker: &mut SharedObjectCongestionTracker,
) {
match self.protocol_config().per_object_congestion_control_mode() {
PerObjectCongestionControlMode::None => {}
PerObjectCongestionControlMode::TotalGasBudget => {
shared_object_congestion_tracker.bump_object_execution_cost(
&cert.shared_input_objects().collect::<Vec<_>>(),
cert.gas_budget(),
);
if let Some(max_accumulated_txn_cost_per_object_in_checkpoint) = self
.protocol_config()
.max_accumulated_txn_cost_per_object_in_checkpoint_as_option()
{
// Defer transaction if it uses shared objects that are congested.
if let Some((deferral_key, congested_objects)) = shared_object_congestion_tracker
.should_defer_due_to_object_congestion(
cert,
max_accumulated_txn_cost_per_object_in_checkpoint,
previously_deferred_tx_digests,
commit_round,
)
{
Some((
deferral_key,
DeferralReason::SharedObjectCongestion(congested_objects),
))
} else {
None
}
} else {
None
}
}

Expand Down Expand Up @@ -2820,10 +2803,13 @@ impl AuthorityPerEpochStore {

// We track transaction execution cost separately for regular transactions and transactions using randomness, since
// they will be in different checkpoints.
let mut shared_object_congestion_tracker: SharedObjectCongestionTracker =
Default::default();
let mut shared_object_using_randomness_congestion_tracker: SharedObjectCongestionTracker =
Default::default();
let mut shared_object_congestion_tracker = SharedObjectCongestionTracker::new(
self.protocol_config().per_object_congestion_control_mode(),
);
let mut shared_object_using_randomness_congestion_tracker =
SharedObjectCongestionTracker::new(
self.protocol_config().per_object_congestion_control_mode(),
);

fail_point_arg!(
"initial_congestion_tracker",
Expand Down Expand Up @@ -3199,10 +3185,7 @@ impl AuthorityPerEpochStore {

// This certificate will be scheduled. Update object execution cost.
if certificate.contains_shared_object() {
self.update_object_execution_cost(
&certificate,
shared_object_congestion_tracker,
);
shared_object_congestion_tracker.bump_object_execution_cost(&certificate);
}

Ok(ConsensusCertificateResult::SuiTransaction(certificate))
Expand Down
Loading

0 comments on commit 1c0270e

Please sign in to comment.