Skip to content

Commit 0bad861

Browse files
apollo_consensus_orchestrator: add SNIP-35 e2e test
1 parent aee5c5f commit 0bad861

1 file changed

Lines changed: 68 additions & 1 deletion

File tree

crates/apollo_consensus_orchestrator/src/sequencer_consensus_context_test.rs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ use apollo_l1_gas_price_types::errors::{
2626
L1GasPriceClientError,
2727
L1GasPriceProviderError,
2828
};
29-
use apollo_l1_gas_price_types::{MockL1GasPriceProviderClient, PriceInfo};
29+
use apollo_l1_gas_price_types::{
30+
MockExchangeRateOracleClientTrait,
31+
MockL1GasPriceProviderClient,
32+
PriceInfo,
33+
};
3034
use apollo_protobuf::consensus::{
3135
BuildParam,
3236
CommitmentParts,
@@ -89,6 +93,15 @@ fn expected_l2_gas_info_for_build_proposal_defaults() -> L2GasInfo {
8993
l2_gas_used: GasAmount(0),
9094
}
9195
}
96+
97+
use crate::snip35::{
98+
compute_fee_proposal,
99+
compute_fee_target,
100+
FEE_PROPOSAL_MARGIN_PPT,
101+
ORACLE_L2_GAS_FLOOR_MAX_FRI,
102+
ORACLE_L2_GAS_FLOOR_MIN_FRI,
103+
TARGET_ATTO_USD_PER_L2_GAS,
104+
};
92105
use crate::utils::{apply_fee_transformations, make_gas_price_params};
93106

94107
static TEST_PROPOSAL_COMMITMENT: LazyLock<ProposalCommitment> = LazyLock::new(|| {
@@ -1544,3 +1557,57 @@ async fn test_first_height_keeps_sync_provided_l2_gas_price() {
15441557
expected_price, context.l2_gas_price.0
15451558
);
15461559
}
1560+
1561+
/// E2E test: SNIP-35 oracle → fee_proposal → ProposalInit → validate → decision_reached.
1562+
/// Verifies the full flow from STRK/USD oracle price to a fee_proposal that appears in the
1563+
/// built proposal and passes validation.
1564+
#[tokio::test]
1565+
async fn snip35_fee_proposal_e2e_flow() {
1566+
// STRK/USD rate: $0.50 with 18 decimals.
1567+
const STRK_USD_RATE: u128 = 500_000_000_000_000_000;
1568+
1569+
let (mut deps, mut network) = create_test_and_network_deps();
1570+
deps.setup_deps_for_build(SetupDepsArgs::default());
1571+
1572+
// Create a mock oracle that returns the known STRK/USD rate.
1573+
let mut mock_oracle = MockExchangeRateOracleClientTrait::new();
1574+
mock_oracle.expect_eth_to_fri_rate().returning(|_| Ok(STRK_USD_RATE));
1575+
deps.strk_exchange_rate_oracle = Some(Arc::new(mock_oracle));
1576+
1577+
// Build context (SNIP-35 is always enabled with hardcoded constants).
1578+
let mut context = deps.build_context();
1579+
1580+
// Build a proposal.
1581+
context.set_height_and_round(BlockNumber(0), 0).await.unwrap();
1582+
let _fin_receiver = context.build_proposal(BuildParam::default(), TIMEOUT).await.unwrap();
1583+
1584+
// Extract ProposalInit from the network.
1585+
let (_, mut receiver) = network.outbound_proposal_receiver.next().await.unwrap();
1586+
let ProposalPart::Init(init) = receiver.next().await.unwrap() else {
1587+
panic!("Expected ProposalPart::Init");
1588+
};
1589+
1590+
// Compute the expected fee_proposal.
1591+
// During initiation (< 10 blocks), fee_actual falls back to l2_gas_price (min_gas_price).
1592+
let min_gas_price = VersionedConstants::latest_constants().min_gas_price;
1593+
let fee_target = compute_fee_target(
1594+
TARGET_ATTO_USD_PER_L2_GAS,
1595+
STRK_USD_RATE,
1596+
ORACLE_L2_GAS_FLOOR_MIN_FRI,
1597+
ORACLE_L2_GAS_FLOOR_MAX_FRI,
1598+
);
1599+
let expected_fee_proposal =
1600+
compute_fee_proposal(Some(fee_target), min_gas_price, FEE_PROPOSAL_MARGIN_PPT);
1601+
1602+
assert_eq!(
1603+
init.fee_proposal_fri,
1604+
Some(expected_fee_proposal),
1605+
"fee_proposal in ProposalInit should match: fee_target={fee_target:?}, \
1606+
min_gas_price={min_gas_price:?}, expected={expected_fee_proposal:?}"
1607+
);
1608+
// Sanity: fee_proposal should be nonzero.
1609+
assert!(
1610+
init.fee_proposal_fri.expect("fee_proposal must be Some at V0_14_3+").0 > 0,
1611+
"fee_proposal should be nonzero when oracle is active"
1612+
);
1613+
}

0 commit comments

Comments
 (0)