Skip to content

Commit 355dc80

Browse files
apollo_consensus_orchestrator: make SNIP-35 fee target a dynamic config (#14220)
1 parent 4ce21e5 commit 355dc80

8 files changed

Lines changed: 39 additions & 13 deletions

File tree

crates/apollo_consensus_orchestrator/src/dynamic_gas_price/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! - `compute_fee_actual`: the base fee for this block, calculated as the median of the most recent
66
//! `fee_proposal` values across `window_size` blocks.
77
//! - `compute_fee_target`: the fee we'd *like* for this block, derived from the STRK/USD oracle
8-
//! quote and a fixed USD-cost target.
8+
//! quote and a configurable USD-cost target.
99
//! - `compute_fee_proposal`: the target, clamped within a fixed multiplicative margin of
1010
//! `fee_actual` (so a proposer cannot move the fee too far per round).
1111
//!
@@ -44,10 +44,6 @@ const FRI_DECIMALS_SCALE: u128 = 10u128.pow(18);
4444
/// Denominator for parts-per-thousand calculations in fee_proposal bounds.
4545
pub(crate) const PPT_DENOMINATOR: u128 = 1000;
4646

47-
/// Target USD cost per L2 gas unit in atto-USD ($3e-9 = 3_000_000_000 atto-USD).
48-
// TODO(AndrewL): consider moving this to a dynamic config.
49-
pub(crate) const TARGET_ATTO_USD_PER_L2_GAS: u128 = 3_000_000_000;
50-
5147
/// Compute fee_actual for `height` as the median of the `fee_proposal` values
5248
/// recorded for heights `[height - window_size, height - 1]`.
5349
///

crates/apollo_consensus_orchestrator/src/dynamic_gas_price/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::BTreeMap;
22

3+
use apollo_consensus_orchestrator_config::config::DEFAULT_SNIP35_TARGET_ATTO_USD_PER_L2_GAS;
34
use apollo_versioned_constants::VersionedConstants;
45
use rand::{Rng, SeedableRng};
56
use rand_chacha::ChaCha8Rng;
@@ -13,7 +14,6 @@ use crate::dynamic_gas_price::{
1314
compute_fee_target,
1415
FeeProposalInfo,
1516
PPT_DENOMINATOR,
16-
TARGET_ATTO_USD_PER_L2_GAS,
1717
};
1818

1919
const TEST_FEE_PROPOSAL_WINDOW_SIZE: u64 = 10;
@@ -228,7 +228,7 @@ fn test_honest_proposer_always_passes_validation_fuzzed() {
228228
let fee_actual_value = rng.gen_range(1u128..1_000_000_000_000_000_000);
229229
let strk_usd_rate = rng.gen_range(1u128..2 * 10u128.pow(18));
230230
let fee_actual = GasPrice(fee_actual_value);
231-
let target = compute_fee_target(TARGET_ATTO_USD_PER_L2_GAS, strk_usd_rate);
231+
let target = compute_fee_target(DEFAULT_SNIP35_TARGET_ATTO_USD_PER_L2_GAS, strk_usd_rate);
232232
let oracle_result = if rng.gen_bool(0.1) { None } else { target };
233233
let proposal = compute_fee_proposal(oracle_result, fee_actual, margin_ppt);
234234
assert!(

crates/apollo_consensus_orchestrator/src/sequencer_consensus_context.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ use crate::dynamic_gas_price::{
9090
compute_fee_target,
9191
proposal_commitment_from,
9292
FeeProposalInfo,
93-
TARGET_ATTO_USD_PER_L2_GAS,
9493
};
9594
use crate::fee_market::{
9695
calculate_next_l2_gas_price_for_fin,
@@ -445,6 +444,7 @@ impl SequencerConsensusContext {
445444
&self,
446445
fee_actual: Option<GasPrice>,
447446
timestamp: u64,
447+
target_atto_usd_per_l2_gas: u128,
448448
) -> GasPrice {
449449
let Some(fee_actual) = fee_actual else {
450450
warn!("fee_actual unavailable, freezing fee_proposal at l2_gas_price");
@@ -456,7 +456,7 @@ impl SequencerConsensusContext {
456456
let fee_target = match self.deps.l1_gas_price_provider.get_strk_to_usd_rate(timestamp).await
457457
{
458458
Ok(rate) => {
459-
let target = compute_fee_target(TARGET_ATTO_USD_PER_L2_GAS, rate);
459+
let target = compute_fee_target(target_atto_usd_per_l2_gas, rate);
460460
match target {
461461
Some(t) => SNIP35_FEE_TARGET.set_lossy(t.0),
462462
None => warn!("STRK/USD oracle returned zero rate, freezing fee_proposal"),
@@ -722,8 +722,13 @@ impl ConsensusContext for SequencerConsensusContext {
722722
build_param.height,
723723
VersionedConstants::latest_constants().fee_proposal_window_size,
724724
);
725-
let fee_proposal =
726-
self.compute_proposer_fee_proposal(fee_actual, self.deps.clock.unix_now()).await;
725+
let fee_proposal = self
726+
.compute_proposer_fee_proposal(
727+
fee_actual,
728+
self.deps.clock.unix_now(),
729+
self.config.dynamic_config.snip35_target_atto_usd_per_l2_gas,
730+
)
731+
.await;
727732
let round = build_param.round;
728733
let args = ProposalBuildArguments {
729734
deps: self.deps.clone(),

crates/apollo_consensus_orchestrator/src/sequencer_consensus_context_test.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ const HEIGHT_1: BlockNumber = BlockNumber(1);
107107
// Use heights < 10 to avoid triggering the height-10 block-hash mapping code path (not tested
108108
// here). Use non-zero height because height 0 always skips the write without querying the recorder.
109109
const HEIGHT_FOR_WRITE_TESTS: BlockNumber = BlockNumber(8);
110+
const TARGET_ATTO_USD_PER_L2_GAS: u128 = 3_000_000_000;
110111

111112
const ROUND_0: Round = 0;
112113
const ROUND_1: Round = 1;
@@ -1685,7 +1686,8 @@ async fn test_compute_proposer_fee_proposal(
16851686

16861687
let mut context = deps.build_context();
16871688
context.l2_gas_price = l2_gas_price;
1688-
let proposal = context.compute_proposer_fee_proposal(fee_actual, 0).await;
1689+
let proposal =
1690+
context.compute_proposer_fee_proposal(fee_actual, 0, TARGET_ATTO_USD_PER_L2_GAS).await;
16891691
assert_eq!(proposal, expected_fee_proposal);
16901692
}
16911693

@@ -1725,7 +1727,9 @@ async fn test_compute_proposer_fee_proposal_converges_to_oracle_target() {
17251727
let h = BlockNumber(height);
17261728
let fee_actual = compute_fee_actual(&context.fee_proposals_window, h, window_size)
17271729
.expect("window stays complete across the loop");
1728-
let proposal = context.compute_proposer_fee_proposal(Some(fee_actual), 0).await;
1730+
let proposal = context
1731+
.compute_proposer_fee_proposal(Some(fee_actual), 0, TARGET_ATTO_USD_PER_L2_GAS)
1732+
.await;
17291733
context.record_fee_proposal(h, Some(proposal));
17301734
height += 1;
17311735
}

crates/apollo_consensus_orchestrator_config/src/config.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ impl SerializeConfig for CendeConfig {
8282
const GWEI_FACTOR: u128 = u128::pow(10, 9);
8383
const ETH_FACTOR: u128 = u128::pow(10, 18);
8484

85+
// Default SNIP-35 target USD cost per L2 gas unit: $0.88 per 1e9 L2 gas = 880_000_000 atto-USD.
86+
pub const DEFAULT_SNIP35_TARGET_ATTO_USD_PER_L2_GAS: u128 = 880_000_000;
87+
8588
// This matches the min_gas_price in orchestrator_versioned_constants_0_14_1.json (0x1dcd65000).
8689
const MIN_ALLOWED_GAS_PRICE: u128 = 8_000_000_000;
8790

@@ -284,6 +287,9 @@ pub struct ContextDynamicConfig {
284287
pub l1_data_gas_price_multiplier_ppt: u128,
285288
/// This additional gas is added to the L1 gas price.
286289
pub l1_gas_tip_wei: u128,
290+
/// SNIP-35 target USD cost per L2 gas unit, in atto-USD ($0.88 per 1e9 L2 gas = 880_000_000
291+
/// atto-USD).
292+
pub snip35_target_atto_usd_per_l2_gas: u128,
287293
/// If given, will override the L2 gas price.
288294
pub override_l2_gas_price_fri: Option<u128>,
289295
/// If given, will override the L1 gas price in FRI.
@@ -350,6 +356,13 @@ impl SerializeConfig for ContextDynamicConfig {
350356
"This additional gas is added to the L1 gas price.",
351357
ParamPrivacyInput::Public,
352358
),
359+
ser_param(
360+
"snip35_target_atto_usd_per_l2_gas",
361+
&self.snip35_target_atto_usd_per_l2_gas,
362+
"SNIP-35 target USD cost per L2 gas unit, in atto-USD ($0.88 per 1e9 L2 gas = \
363+
880_000_000 atto-USD).",
364+
ParamPrivacyInput::Public,
365+
),
353366
ser_param(
354367
"compare_retrospective_block_hash",
355368
&self.compare_retrospective_block_hash,
@@ -413,6 +426,7 @@ impl Default for ContextDynamicConfig {
413426
max_l1_data_gas_price_wei: ETH_FACTOR,
414427
l1_data_gas_price_multiplier_ppt: 135,
415428
l1_gas_tip_wei: GWEI_FACTOR,
429+
snip35_target_atto_usd_per_l2_gas: DEFAULT_SNIP35_TARGET_ATTO_USD_PER_L2_GAS,
416430
override_l2_gas_price_fri: None,
417431
override_l1_gas_price_fri: None,
418432
override_l1_data_gas_price_fri: None,

crates/apollo_deployments/resources/app_configs/consensus_manager_config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"consensus_manager_config.context_config.dynamic_config.max_l1_gas_price_wei": 1000000000000,
4545
"consensus_manager_config.context_config.dynamic_config.min_l1_data_gas_price_wei": 1,
4646
"consensus_manager_config.context_config.dynamic_config.min_l1_gas_price_wei": 1000000000,
47+
"consensus_manager_config.context_config.dynamic_config.snip35_target_atto_usd_per_l2_gas": 880000000,
4748
"consensus_manager_config.context_config.static_config.proposal_buffer_size": 512,
4849
"consensus_manager_config.context_config.static_config.retrospective_block_hash_retry_interval_millis": 500,
4950
"consensus_manager_config.context_config.static_config.validate_proposal_margin_millis": 10000,

crates/apollo_deployments/resources/app_configs/replacer_consensus_manager_config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"consensus_manager_config.context_config.dynamic_config.override_l1_gas_price_fri.#is_none": "$$$_CONSENSUS_MANAGER_CONFIG-CONTEXT_CONFIG-DYNAMIC_CONFIG-OVERRIDE_L1_GAS_PRICE_FRI-IS_NONE_$$$",
5050
"consensus_manager_config.context_config.dynamic_config.override_l2_gas_price_fri": "$$$_CONSENSUS_MANAGER_CONFIG-CONTEXT_CONFIG-DYNAMIC_CONFIG-OVERRIDE_L2_GAS_PRICE_FRI_$$$",
5151
"consensus_manager_config.context_config.dynamic_config.override_l2_gas_price_fri.#is_none": "$$$_CONSENSUS_MANAGER_CONFIG-CONTEXT_CONFIG-DYNAMIC_CONFIG-OVERRIDE_L2_GAS_PRICE_FRI-IS_NONE_$$$",
52+
"consensus_manager_config.context_config.dynamic_config.snip35_target_atto_usd_per_l2_gas": 880000000,
5253
"consensus_manager_config.context_config.static_config.block_timestamp_window_seconds": 1,
5354
"consensus_manager_config.context_config.static_config.build_proposal_time_ratio_for_retrospective_block_hash": 0.7,
5455
"consensus_manager_config.context_config.static_config.builder_address": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8",

crates/apollo_node/resources/config_schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2729,6 +2729,11 @@
27292729
"privacy": "TemporaryValue",
27302730
"value": true
27312731
},
2732+
"consensus_manager_config.context_config.dynamic_config.snip35_target_atto_usd_per_l2_gas": {
2733+
"description": "SNIP-35 target USD cost per L2 gas unit, in atto-USD ($0.88 per 1e9 L2 gas = 880_000_000 atto-USD).",
2734+
"privacy": "Public",
2735+
"value": 880000000
2736+
},
27322737
"consensus_manager_config.context_config.static_config.behavior_mode": {
27332738
"description": "Behavior mode: 'starknet' for production, 'echonet' for test/replay mode.",
27342739
"pointer_target": "behavior_mode",

0 commit comments

Comments
 (0)