Skip to content

Commit

Permalink
feat(congestion_control) - relax congestion control - part 2 (#12430)
Browse files Browse the repository at this point in the history
relaxing the congestion control to allow more gas (receipts) in the
delayed receipts queue.

Please note I'm adding it directly to protocol version 73 because it
wasn't released yet. @staffik Will it be possible to get it into 2.4?
  • Loading branch information
wacban authored Nov 11, 2024
1 parent 6d3f812 commit a844646
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 32 deletions.
4 changes: 2 additions & 2 deletions core/parameters/res/runtime_configs/73.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ wasm_yield_resume_byte: { old: 1_195_627_285_210 , new: 47_683_715 }

# Congestion Control

# 40 PGAS
# 400 PGAS
max_congestion_incoming_gas: {
old : 20_000_000_000_000_000,
new : 40_000_000_000_000_000,
new : 400_000_000_000_000_000,
}

# 0.7
Expand Down
2 changes: 1 addition & 1 deletion core/parameters/res/runtime_configs/parameters.snap
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ vm_kind NearVm
eth_implicit_accounts true
yield_resume true
discard_custom_sections true
max_congestion_incoming_gas 40_000_000_000_000_000
max_congestion_incoming_gas 400_000_000_000_000_000
max_congestion_outgoing_gas 10_000_000_000_000_000
max_congestion_memory_consumption 1_000_000_000
max_congestion_missed_chunks 5
Expand Down
16 changes: 15 additions & 1 deletion core/parameters/src/config_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::config::{CongestionControlConfig, RuntimeConfig};
use crate::parameter_table::{ParameterTable, ParameterTableDiff};
use crate::vm;
use near_primitives_core::types::ProtocolVersion;
use near_primitives_core::version::PROTOCOL_VERSION;
use near_primitives_core::version::{ProtocolFeature, PROTOCOL_VERSION};
use std::collections::BTreeMap;
use std::ops::Bound;
use std::sync::Arc;
Expand Down Expand Up @@ -158,6 +158,20 @@ impl RuntimeConfigStore {
config_store.store.insert(PROTOCOL_VERSION, Arc::new(config));
config_store
}
near_primitives_core::chains::CONGESTION_CONTROL_TEST => {
let mut config_store = Self::new(None);

// Get the original congestion control config. The nayduck tests
// are tuned to this config.
let source_protocol_version = ProtocolFeature::CongestionControl.protocol_version();
let source_runtime_config = config_store.get_config(source_protocol_version);

let mut config = RuntimeConfig::clone(config_store.get_config(PROTOCOL_VERSION));
config.congestion_control_config = source_runtime_config.congestion_control_config;

config_store.store.insert(PROTOCOL_VERSION, Arc::new(config));
config_store
}
_ => Self::new(None),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ expression: config_view
"registrar_account_id": "registrar"
},
"congestion_control_config": {
"max_congestion_incoming_gas": 40000000000000000,
"max_congestion_incoming_gas": 400000000000000000,
"max_congestion_outgoing_gas": 10000000000000000,
"max_congestion_memory_consumption": 1000000000,
"max_congestion_missed_chunks": 5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ expression: config_view
"registrar_account_id": "registrar"
},
"congestion_control_config": {
"max_congestion_incoming_gas": 40000000000000000,
"max_congestion_incoming_gas": 400000000000000000,
"max_congestion_outgoing_gas": 10000000000000000,
"max_congestion_memory_consumption": 1000000000,
"max_congestion_missed_chunks": 5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ expression: config_view
"registrar_account_id": "registrar"
},
"congestion_control_config": {
"max_congestion_incoming_gas": 40000000000000000,
"max_congestion_incoming_gas": 400000000000000000,
"max_congestion_outgoing_gas": 10000000000000000,
"max_congestion_memory_consumption": 1000000000,
"max_congestion_missed_chunks": 5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ expression: config_view
"registrar_account_id": "registrar"
},
"congestion_control_config": {
"max_congestion_incoming_gas": 40000000000000000,
"max_congestion_incoming_gas": 400000000000000000,
"max_congestion_outgoing_gas": 10000000000000000,
"max_congestion_memory_consumption": 1000000000,
"max_congestion_missed_chunks": 5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ expression: "&view"
"registrar_account_id": "registrar"
},
"congestion_control_config": {
"max_congestion_incoming_gas": 40000000000000000,
"max_congestion_incoming_gas": 400000000000000000,
"max_congestion_outgoing_gas": 10000000000000000,
"max_congestion_memory_consumption": 1000000000,
"max_congestion_missed_chunks": 5,
Expand Down
3 changes: 3 additions & 0 deletions core/primitives-core/src/chains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ pub const MOCKNET: &str = "mocknet";

/// Used by ft-benchmark. http://go/crt-benchmark
pub const BENCHMARKNET: &str = "benchmarknet";

/// Used by congestion control tests in nayduck.
pub const CONGESTION_CONTROL_TEST: &str = "congestion_control_test";
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ expression: "&view"
"registrar_account_id": "registrar"
},
"congestion_control_config": {
"max_congestion_incoming_gas": 40000000000000000,
"max_congestion_incoming_gas": 400000000000000000,
"max_congestion_outgoing_gas": 10000000000000000,
"max_congestion_memory_consumption": 1000000000,
"max_congestion_missed_chunks": 5,
Expand Down
62 changes: 42 additions & 20 deletions integration-tests/src/tests/client/features/congestion_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,26 @@ fn get_runtime_config(
let mut config = config_store.get_config(protocol_version).clone();
let mut_config = Arc::make_mut(&mut config);

adjust_runtime_config(mut_config);
set_wasm_cost(mut_config);

config
}

// Make 1 wasm op cost ~4 GGas, to let "loop_forever" finish more quickly.
fn adjust_runtime_config(config: &mut RuntimeConfig) {
fn set_wasm_cost(config: &mut RuntimeConfig) {
let wasm_config = Arc::make_mut(&mut config.wasm_config);
wasm_config.regular_op_cost = u32::MAX;
}

// Set the default congestion control parameters for the given runtime config.
// This is important to prevent needing to fix the congestion control tests
// every time the parameters are updated.
fn set_default_congestion_control(config_store: &RuntimeConfigStore, config: &mut RuntimeConfig) {
let cc_protocol_version = ProtocolFeature::CongestionControl.protocol_version();
let cc_config = get_runtime_config(&config_store, cc_protocol_version);
config.congestion_control_config = cc_config.congestion_control_config;
}

/// Set up the test runtime with the given protocol version and runtime configs.
/// The test version of runtime has custom gas cost.
fn setup_test_runtime(sender_id: AccountId, protocol_version: ProtocolVersion) -> TestEnv {
Expand All @@ -53,10 +62,12 @@ fn setup_test_runtime(sender_id: AccountId, protocol_version: ProtocolVersion) -
// Chain must be sharded to test cross-shard congestion control.
genesis.config.shard_layout = ShardLayout::v1_test();

let config_store = RuntimeConfigStore::new(None);
let mut config = RuntimeConfig::test_protocol_version(protocol_version);
adjust_runtime_config(&mut config);
let runtime_configs = vec![RuntimeConfigStore::with_one_config(config)];
set_wasm_cost(&mut config);
set_default_congestion_control(&config_store, &mut config);

let runtime_configs = vec![RuntimeConfigStore::with_one_config(config)];
TestEnv::builder(&genesis.config)
.nightshade_runtimes_with_runtime_config_store(&genesis, runtime_configs)
.build()
Expand All @@ -73,9 +84,14 @@ fn setup_real_runtime(sender_id: AccountId, protocol_version: ProtocolVersion) -
// Chain must be sharded to test cross-shard congestion control.
genesis.config.shard_layout = ShardLayout::v1_test();

// Get the runtime configs for before and after the protocol upgrade.
let config_store = RuntimeConfigStore::new(None);
let pre_config = get_runtime_config(&config_store, protocol_version);
let post_config = get_runtime_config(&config_store, PROTOCOL_VERSION);
let mut post_config = get_runtime_config(&config_store, PROTOCOL_VERSION);

// Use the original congestion control parameters for the post config.
let post_runtime_config = Arc::get_mut(&mut post_config).unwrap();
set_default_congestion_control(&config_store, post_runtime_config);

// Checking the migration from Receipt to StateStoredReceipt requires the
// relevant config to be disabled before the protocol upgrade and enabled
Expand Down Expand Up @@ -520,13 +536,10 @@ fn test_transaction_limit_for_local_congestion() {
if !ProtocolFeature::CongestionControl.enabled(PROTOCOL_VERSION) {
return;
}
let runtime_config_store = RuntimeConfigStore::new(None);

// Fix the initial configuration of congestion control for the tests.
let protocol_version = ProtocolFeature::CongestionControl.protocol_version();
let config = runtime_config_store.get_config(protocol_version);
// We don't want to go into the TX rejection limit in this test.
let upper_limit_congestion = config.congestion_control_config.reject_tx_congestion_threshold;
let upper_limit_congestion = UpperLimitCongestion::BelowRejectThreshold;

// For this test, the contract and the sender are on the same shard, even
// the same account.
Expand Down Expand Up @@ -572,13 +585,12 @@ fn test_transaction_limit_for_local_congestion() {
/// rejection.
#[test]
fn test_transaction_limit_for_remote_congestion() {
init_test_logger();
if !ProtocolFeature::CongestionControl.enabled(PROTOCOL_VERSION) {
return;
}
let runtime_config_store = RuntimeConfigStore::new(None);
let config = runtime_config_store.get_config(PROTOCOL_VERSION);
// We don't want to go into the TX rejection limit in this test.
let upper_limit_congestion = config.congestion_control_config.reject_tx_congestion_threshold;
let upper_limit_congestion = UpperLimitCongestion::BelowRejectThreshold;

let (
remote_tx_included_without_congestion,
Expand Down Expand Up @@ -612,11 +624,8 @@ fn test_transaction_filtering() {
if !ProtocolFeature::CongestionControl.enabled(PROTOCOL_VERSION) {
return;
}
let runtime_config_store = RuntimeConfigStore::new(None);
let config = runtime_config_store.get_config(PROTOCOL_VERSION);
// This test should go beyond into the TX rejection limit in this test.
let upper_limit_congestion =
3.0 * config.congestion_control_config.reject_tx_congestion_threshold;
let upper_limit_congestion = UpperLimitCongestion::AboveRejectThreshold;

let (
remote_tx_included_without_congestion,
Expand All @@ -638,8 +647,15 @@ fn test_transaction_filtering() {
assert_eq!(remote_tx_included_with_congestion, 0);
}

enum UpperLimitCongestion {
BelowRejectThreshold,
AboveRejectThreshold,
}

/// Calls [`measure_tx_limit`] with accounts on three different shards.
fn measure_remote_tx_limit(upper_limit_congestion: f64) -> (usize, usize, usize, usize) {
fn measure_remote_tx_limit(
upper_limit_congestion: UpperLimitCongestion,
) -> (usize, usize, usize, usize) {
let remote_id: AccountId = "test0".parse().unwrap();
let contract_id: AccountId = CONTRACT_ID.parse().unwrap();
let dummy_id: AccountId = "a_dummy_receiver".parse().unwrap();
Expand Down Expand Up @@ -677,7 +693,7 @@ fn measure_tx_limit(
remote_id: AccountId,
contract_id: AccountId,
dummy_receiver: AccountId,
upper_limit_congestion: f64,
upper_limit_congestion: UpperLimitCongestion,
) -> (usize, usize, usize, usize) {
let remote_signer =
InMemorySigner::from_seed(remote_id.clone(), KeyType::ED25519, remote_id.as_str());
Expand All @@ -694,6 +710,11 @@ fn measure_tx_limit(
// put in enough transactions to create up to
// `reject_tx_congestion_threshold` incoming congestion
let config = head_congestion_control_config(&env);
let upper_limit_congestion = match upper_limit_congestion {
UpperLimitCongestion::BelowRejectThreshold => config.reject_tx_congestion_threshold,
UpperLimitCongestion::AboveRejectThreshold => config.reject_tx_congestion_threshold * 2.0,
};

let num_full_congestion = config.max_congestion_incoming_gas / (100 * 10u64.pow(12));
let n = num_full_congestion as f64 * upper_limit_congestion;
// Key of new account starts at block_height * 1_000_000
Expand All @@ -714,10 +735,11 @@ fn measure_tx_limit(
let height = tip.height + i;
env.produce_block(0, height);

let sender_chunk = head_chunk(&env, remote_shard_id);
let remote_chunk = head_chunk(&env, remote_shard_id);
let contract_chunk = head_chunk(&env, contract_shard_id);
let remote_num_tx = sender_chunk.transactions().len();
let remote_num_tx = remote_chunk.transactions().len();
let local_num_tx = contract_chunk.transactions().len();

if i == 2 {
remote_tx_included_without_congestion = remote_num_tx;
local_tx_included_without_congestion = local_num_tx;
Expand Down
7 changes: 6 additions & 1 deletion pytest/tests/sanity/congestion_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def __check_setup(self, node, accounts):
def __run_under_congestion(self, node):
logger.info("Checking the chain under congestion")
(start_height, _) = node.get_latest_block()
target = start_height + 20
target = start_height + 10
for height, hash in poll_blocks(node, __target=target):
# Wait for a few blocks to congest the chain.
if height < start_height + 5:
Expand Down Expand Up @@ -265,6 +265,11 @@ def __setup_node(self) -> BaseNode:
genesis_config_changes = [
("epoch_length", epoch_length),
("shard_layout", SHARD_LAYOUT),
# This is a custom chain id that will set the congestion control
# runtime parameters to their original values. This is needed so
# that the test doesn't need to be updated every time the parameters
# are changed.
("chain_id", "congestion_control_test"),
]
client_config_changes = {
0: {
Expand Down
2 changes: 1 addition & 1 deletion runtime/runtime/src/tests/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2308,7 +2308,7 @@ fn test_congestion_buffering() {
.get_mut(&receiver_shard)
.unwrap()
.congestion_info
.remove_delayed_receipt_gas(10)
.remove_delayed_receipt_gas(100)
.unwrap();

let min_outgoing_gas: Gas = apply_state.config.congestion_control_config.min_outgoing_gas;
Expand Down

0 comments on commit a844646

Please sign in to comment.