Skip to content

Commit d71ccfb

Browse files
apollo_consensus_orchestrator: wire SNIP-35 fee_proposal into cende blob
1 parent b8bc905 commit d71ccfb

8 files changed

Lines changed: 68 additions & 1 deletion

File tree

crates/apollo_consensus_orchestrator/resources/central_blob.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
"l2_gas_consumed": 150000,
9494
"next_l2_gas_price": "0x186a0"
9595
},
96+
"snip35_info": {
97+
"fee_proposal_fri": "0x186a0"
98+
},
9699
"transactions": [
97100
{
98101
"tx": {

crates/apollo_consensus_orchestrator/resources/central_blob_empty_or_none_fields.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
"l2_gas_consumed": 150000,
5555
"next_l2_gas_price": "0x186a0"
5656
},
57+
"snip35_info": {
58+
"fee_proposal_fri": "0x186a0"
59+
},
5760
"transactions": [],
5861
"execution_infos": [],
5962
"contract_classes": [],

crates/apollo_consensus_orchestrator/src/cende/central_objects.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use starknet_types_core::felt::Felt;
5050

5151
use super::{CendeAmbassadorError, CendeAmbassadorResult};
5252
use crate::fee_market::FeeMarketInfo;
53+
use crate::snip35::Snip35Info;
5354

5455
/// Central objects are required in order to continue processing the block by the centralized
5556
/// Python pipline. These objects are written to the Aerospike database and are used by python
@@ -86,6 +87,7 @@ impl From<BouncerWeights> for CentralBouncerWeights {
8687
}
8788
}
8889
pub(crate) type CentralFeeMarketInfo = FeeMarketInfo;
90+
pub(crate) type CentralSnip35Info = Snip35Info;
8991
pub(crate) type CentralCompressedStateDiff = CentralStateDiff;
9092
pub(crate) type CentralSierraContractClassEntry = (ClassHash, CentralSierraContractClass);
9193
pub(crate) type CentralCasmContractClassEntry = (CompiledClassHash, CentralCasmContractClass);

crates/apollo_consensus_orchestrator/src/cende/central_objects_test.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ use super::{
141141
CentralFeeMarketInfo,
142142
CentralInvokeTransaction,
143143
CentralSierraContractClass,
144+
CentralSnip35Info,
144145
CentralStateDiff,
145146
CentralTransaction,
146147
CentralTransactionWritten,
@@ -417,6 +418,10 @@ fn central_fee_market_info() -> CentralFeeMarketInfo {
417418
CentralFeeMarketInfo { l2_gas_consumed: GasAmount(150000), next_l2_gas_price: GasPrice(100000) }
418419
}
419420

421+
fn central_snip35_info() -> CentralSnip35Info {
422+
CentralSnip35Info { fee_proposal_fri: Some(GasPrice(100000)) }
423+
}
424+
420425
fn entry_point(idx: usize, selector: u8) -> EntryPoint {
421426
EntryPoint { function_idx: FunctionIndex(idx), selector: EntryPointSelector(felt!(selector)) }
422427
}
@@ -746,6 +751,7 @@ fn central_blob() -> AerospikeBlob {
746751
transactions_with_execution_infos,
747752
bouncer_weights: test_bouncer_weights(),
748753
fee_market_info: central_fee_market_info(),
754+
snip35_info: central_snip35_info(),
749755
casm_hash_computation_data_sierra_gas: central_casm_hash_computation_data(),
750756
casm_hash_computation_data_proving_gas: central_casm_hash_computation_data(),
751757
compiled_class_hashes_for_migration: central_compiled_class_hashes_for_migration(),
@@ -777,6 +783,7 @@ fn central_blob_with_empty_or_none_fields() -> AerospikeBlob {
777783
transactions_with_execution_infos: vec![],
778784
bouncer_weights: test_bouncer_weights(),
779785
fee_market_info: central_fee_market_info(),
786+
snip35_info: central_snip35_info(),
780787
casm_hash_computation_data_sierra_gas: central_casm_hash_computation_data(),
781788
casm_hash_computation_data_proving_gas: central_casm_hash_computation_data(),
782789
compiled_class_hashes_for_migration: vec![],

crates/apollo_consensus_orchestrator/src/cende/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use central_objects::{
2424
CentralCompressedStateDiff,
2525
CentralFeeMarketInfo,
2626
CentralSierraContractClassEntry,
27+
CentralSnip35Info,
2728
CentralStateDiff,
2829
CentralTransactionWritten,
2930
};
@@ -53,6 +54,7 @@ use crate::metrics::{
5354
CENDE_WRITE_BLOB_SUCCESS,
5455
CENDE_WRITE_PREV_HEIGHT_BLOB_LATENCY,
5556
};
57+
use crate::snip35::Snip35Info;
5658

5759
#[derive(thiserror::Error, Debug)]
5860
pub enum CendeAmbassadorError {
@@ -80,6 +82,7 @@ pub struct AerospikeBlob {
8082
compressed_state_diff: Option<CentralCompressedStateDiff>,
8183
bouncer_weights: CentralBouncerWeights,
8284
fee_market_info: CentralFeeMarketInfo,
85+
snip35_info: CentralSnip35Info,
8386
transactions: Vec<CentralTransactionWritten>,
8487
execution_infos: Vec<CentralTransactionExecutionInfo>,
8588
contract_classes: Vec<CentralSierraContractClassEntry>,
@@ -362,6 +365,7 @@ pub struct BlobParameters {
362365
pub compressed_state_diff: Option<CommitmentStateDiff>,
363366
pub bouncer_weights: BouncerWeights,
364367
pub fee_market_info: FeeMarketInfo,
368+
pub snip35_info: Snip35Info,
365369
pub transactions_with_execution_infos: Vec<InternalTransactionWithReceipt>,
366370
pub casm_hash_computation_data_sierra_gas: CasmHashComputationData,
367371
pub casm_hash_computation_data_proving_gas: CasmHashComputationData,
@@ -412,6 +416,7 @@ impl AerospikeBlob {
412416
compressed_state_diff,
413417
bouncer_weights: blob_parameters.bouncer_weights.into(),
414418
fee_market_info: blob_parameters.fee_market_info,
419+
snip35_info: blob_parameters.snip35_info,
415420
transactions: central_transactions,
416421
execution_infos,
417422
contract_classes,

crates/apollo_consensus_orchestrator/src/sequencer_consensus_context.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ use crate::snip35::{
9999
compute_fee_actual,
100100
compute_fee_proposal,
101101
compute_fee_target,
102+
Snip35Info,
102103
FEE_PROPOSAL_MARGIN_PPT,
103104
FEE_PROPOSAL_WINDOW_SIZE,
104105
ORACLE_L2_GAS_FLOOR_MAX_FRI,
@@ -546,6 +547,11 @@ impl SequencerConsensusContext {
546547
l2_gas_consumed: l2_gas_used,
547548
next_l2_gas_price: self.l2_gas_price,
548549
},
550+
// SNIP-35: forward the proposer's stated fee_proposal_fri (from ProposalInit)
551+
// to the centralized cende pipeline. The centralized side persists this in
552+
// its own storage namespace, separate from FeeMarketInfo. Pre-V0_14_3 blocks
553+
// have `init.fee_proposal_fri == None`.
554+
snip35_info: Snip35Info { fee_proposal_fri: init.fee_proposal_fri },
549555
compiled_class_hashes_for_migration: central_objects
550556
.compiled_class_hashes_for_migration,
551557
proposal_commitment: commitment,

crates/apollo_consensus_orchestrator/src/snip35/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,24 @@
1313
//! `fee_actual` as a floor.
1414
1515
use ethnum::U256;
16+
use serde::Serialize;
1617
use starknet_api::block::GasPrice;
1718

1819
#[cfg(test)]
1920
mod test;
2021

22+
/// SNIP-35 proposer-stated fee value for a block, as it travels in the cende blob to the
23+
/// centralized recorder. Mirrors the `Snip35Info` Marshmallow dataclass on the centralized
24+
/// (Python) side; the wire JSON shape must agree across the language boundary.
25+
#[cfg_attr(any(feature = "testing", test), derive(serde::Deserialize, PartialEq))]
26+
#[derive(Debug, Default, Serialize)]
27+
pub struct Snip35Info {
28+
/// `None` for pre-V0_14_3 blocks (no value stated by the proposer); `Some(...)` for SNIP-35
29+
/// era blocks. The centralized side persists this independently of `FeeMarketInfo` so
30+
/// existing fee market storage blobs are untouched.
31+
pub fee_proposal_fri: Option<GasPrice>,
32+
}
33+
2134
/// Scale factor for 18-decimal fixed-point conversion (1 STRK = 10^18 FRI).
2235
const FRI_DECIMALS_SCALE: u128 = 10u128.pow(18);
2336

crates/apollo_consensus_orchestrator/src/snip35/test.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,35 @@
11
use rstest::rstest;
22
use starknet_api::block::GasPrice;
33

4-
use crate::snip35::{compute_fee_actual, compute_fee_proposal, compute_fee_target};
4+
use crate::snip35::{compute_fee_actual, compute_fee_proposal, compute_fee_target, Snip35Info};
5+
6+
#[test]
7+
fn snip35_info_serializes_field_by_name() {
8+
// The cende blob's wire shape must agree with the Python `Snip35Info` Marshmallow
9+
// dataclass — same field name (`fee_proposal_fri`), same JSON shape. If a refactor here
10+
// accidentally renames or restructures the field, the centralized recorder would silently
11+
// fail to load the Marshmallow schema on the new blob shape.
12+
let info = Snip35Info { fee_proposal_fri: Some(GasPrice(0x1dcd65000)) };
13+
let json = serde_json::to_value(&info).unwrap();
14+
assert_eq!(json["fee_proposal_fri"], serde_json::Value::String("0x1dcd65000".to_string()));
15+
16+
let info_none = Snip35Info { fee_proposal_fri: None };
17+
let json_none = serde_json::to_value(&info_none).unwrap();
18+
assert_eq!(json_none["fee_proposal_fri"], serde_json::Value::Null);
19+
}
20+
21+
#[test]
22+
fn snip35_info_round_trips_through_serde_json() {
23+
let original = Snip35Info { fee_proposal_fri: Some(GasPrice(0xDEAD_BEEF)) };
24+
let bytes = serde_json::to_vec(&original).unwrap();
25+
let reparsed: Snip35Info = serde_json::from_slice(&bytes).unwrap();
26+
assert_eq!(reparsed, original);
27+
28+
let original_none = Snip35Info { fee_proposal_fri: None };
29+
let bytes_none = serde_json::to_vec(&original_none).unwrap();
30+
let reparsed_none: Snip35Info = serde_json::from_slice(&bytes_none).unwrap();
31+
assert_eq!(reparsed_none, original_none);
32+
}
533

634
const FRI_DECIMALS_SCALE: u128 = 10u128.pow(18);
735
const FLOOR_MIN_FRI: u128 = 100;

0 commit comments

Comments
 (0)