11use std:: collections:: BTreeMap ;
22use std:: future:: ready;
3- use std:: sync:: Arc ;
3+ use std:: sync:: { Arc , LazyLock } ;
44use std:: time:: Duration ;
55
66use apollo_batcher_types:: batcher_types:: {
@@ -72,6 +72,7 @@ use crate::sequencer_consensus_context::{
7272 SequencerConsensusContext ,
7373 SequencerConsensusContextDeps ,
7474} ;
75+ use crate :: snip35:: proposal_commitment_from;
7576use crate :: test_utils:: {
7677 create_test_and_network_deps,
7778 proposal_init,
@@ -96,7 +97,14 @@ fn expected_l2_gas_info_for_build_proposal_defaults() -> L2GasInfo {
9697use crate :: snip35:: { compute_fee_actual, FEE_PROPOSAL_WINDOW_SIZE } ;
9798use crate :: utils:: { apply_fee_transformations, make_gas_price_params} ;
9899
99- const TEST_PROPOSAL_COMMITMENT : ProposalCommitment = ProposalCommitment ( PARTIAL_BLOCK_HASH . 0 ) ;
100+ static TEST_PROPOSAL_COMMITMENT : LazyLock < ProposalCommitment > = LazyLock :: new ( || {
101+ // Default test setup: empty fee_proposals_window → `compute_fee_actual` returns `None` →
102+ // `compute_snip35_fee_proposal` falls back to `self.l2_gas_price` (default
103+ // `min_gas_price` = 8 gwei = 8_000_000_000 FRI). The orchestrator chains this value into
104+ // the proposal commitment via `proposal_commitment_from`. The `proposal_init` test helper
105+ // produces an init with `fee_proposal_fri = Some(8 gwei)` to match what the proposer emits.
106+ proposal_commitment_from ( PARTIAL_BLOCK_HASH , Some ( GasPrice ( 8_000_000_000 ) ) )
107+ } ) ;
100108const HEIGHT_0 : BlockNumber = BlockNumber ( 0 ) ;
101109const HEIGHT_1 : BlockNumber = BlockNumber ( 1 ) ;
102110
@@ -136,7 +144,7 @@ async fn validate_proposal_success() {
136144 let fin_receiver = context
137145 . validate_proposal ( proposal_init ( HEIGHT_0 , ROUND_0 ) , TIMEOUT , content_receiver)
138146 . await ;
139- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
147+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
140148}
141149
142150#[ rstest]
@@ -182,7 +190,7 @@ async fn validate_then_repropose(#[case] execute_all_txs: bool) {
182190 ProposalPart :: Transactions ( TransactionBatch { transactions : TX_BATCH . to_vec ( ) } ) ;
183191 content_sender. send ( transactions. clone ( ) ) . await . unwrap ( ) ;
184192 let fin = ProposalPart :: Fin ( ProposalFin {
185- proposal_commitment : TEST_PROPOSAL_COMMITMENT ,
193+ proposal_commitment : * TEST_PROPOSAL_COMMITMENT ,
186194 executed_transaction_count : n_executed_txs_count. try_into ( ) . unwrap ( ) ,
187195 fin_payload : Some ( ProposalFinPayload {
188196 commitment_parts : CommitmentParts :: default ( ) ,
@@ -192,11 +200,11 @@ async fn validate_then_repropose(#[case] execute_all_txs: bool) {
192200 content_sender. send ( fin. clone ( ) ) . await . unwrap ( ) ;
193201 let fin_receiver = context. validate_proposal ( init. clone ( ) , TIMEOUT , content_receiver) . await ;
194202 content_sender. close_channel ( ) ;
195- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
203+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
196204
197205 let build_param =
198206 BuildParam { round : ROUND_1 , valid_round : Some ( ROUND_0 ) , ..Default :: default ( ) } ;
199- context. repropose ( TEST_PROPOSAL_COMMITMENT , build_param) . await ;
207+ context. repropose ( * TEST_PROPOSAL_COMMITMENT , build_param) . await ;
200208 let ( _, mut receiver) = network. outbound_proposal_receiver . next ( ) . await . unwrap ( ) ;
201209 // Reproposal sends init with updated round, proposer, valid_round.
202210 let mut expected_init = init;
@@ -212,7 +220,7 @@ async fn validate_then_repropose(#[case] execute_all_txs: bool) {
212220 assert ! ( receiver. next( ) . await . is_none( ) ) ;
213221
214222 // Verify decision_reached uses the updated init (from reproposal round) for finalize.
215- context. decision_reached ( HEIGHT_0 , ROUND_1 , TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
223+ context. decision_reached ( HEIGHT_0 , ROUND_1 , * TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
216224}
217225
218226#[ tokio:: test]
@@ -260,14 +268,14 @@ async fn validate_then_build_then_decision_reached_round_0_uses_round_0_init() {
260268 ProposalPart :: Transactions ( TransactionBatch { transactions : TX_BATCH . to_vec ( ) } ) ;
261269 content_sender. send ( transactions. clone ( ) ) . await . unwrap ( ) ;
262270 let fin = ProposalPart :: Fin ( ProposalFin {
263- proposal_commitment : TEST_PROPOSAL_COMMITMENT ,
271+ proposal_commitment : * TEST_PROPOSAL_COMMITMENT ,
264272 executed_transaction_count : TX_BATCH . len ( ) . try_into ( ) . unwrap ( ) ,
265273 fin_payload : None ,
266274 } ) ;
267275 content_sender. send ( fin. clone ( ) ) . await . unwrap ( ) ;
268276 let fin_receiver = context. validate_proposal ( init, TIMEOUT , content_receiver) . await ;
269277 content_sender. close_channel ( ) ;
270- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
278+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
271279
272280 // Round 1: build - clock returns TIMESTAMP_ROUND_1 (different from TIMESTAMP_ROUND_0)
273281 let build_param = BuildParam { round : ROUND_1 , ..Default :: default ( ) } ;
@@ -282,10 +290,10 @@ async fn validate_then_build_then_decision_reached_round_0_uses_round_0_init() {
282290 assert_eq ! ( build_init. timestamp, TIMESTAMP_ROUND_1 ) ;
283291 let _txs = receiver. next ( ) . await . unwrap ( ) ;
284292 let _fin = receiver. next ( ) . await . unwrap ( ) ;
285- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
293+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
286294
287295 // Decision reached for round 0 - state_sync should receive TIMESTAMP_ROUND_0
288- context. decision_reached ( HEIGHT_0 , ROUND_0 , TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
296+ context. decision_reached ( HEIGHT_0 , ROUND_0 , * TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
289297}
290298
291299#[ tokio:: test]
@@ -301,7 +309,7 @@ async fn proposals_from_different_rounds() {
301309 let prop_part_txs =
302310 ProposalPart :: Transactions ( TransactionBatch { transactions : TX_BATCH . to_vec ( ) } ) ;
303311 let prop_part_fin = ProposalPart :: Fin ( ProposalFin {
304- proposal_commitment : TEST_PROPOSAL_COMMITMENT ,
312+ proposal_commitment : * TEST_PROPOSAL_COMMITMENT ,
305313 executed_transaction_count : INTERNAL_TX_BATCH . len ( ) . try_into ( ) . unwrap ( ) ,
306314 fin_payload : Some ( ProposalFinPayload :: default ( ) ) ,
307315 } ) ;
@@ -325,7 +333,7 @@ async fn proposals_from_different_rounds() {
325333 let fin_receiver_curr_round = context
326334 . validate_proposal ( proposal_init ( HEIGHT_0 , ROUND_1 ) , TIMEOUT , content_receiver)
327335 . await ;
328- assert_eq ! ( fin_receiver_curr_round. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
336+ assert_eq ! ( fin_receiver_curr_round. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
329337
330338 // The proposal from the future round should not be processed.
331339 let ( mut content_sender, content_receiver) =
@@ -394,7 +402,7 @@ async fn interrupt_active_proposal() {
394402
395403 // Interrupt active proposal.
396404 assert ! ( fin_receiver_0. await . is_err( ) ) ;
397- assert_eq ! ( fin_receiver_1. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
405+ assert_eq ! ( fin_receiver_1. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
398406}
399407
400408#[ tokio:: test]
@@ -414,14 +422,16 @@ async fn build_proposal() {
414422 panic ! ( "Expected ProposalPart::Init" ) ;
415423 } ;
416424 assert ! ( info. timestamp >= before && info. timestamp <= after) ;
425+ let expected_proposal_commitment =
426+ proposal_commitment_from ( PARTIAL_BLOCK_HASH , info. fee_proposal_fri ) ;
417427 assert_eq ! (
418428 receiver. next( ) . await . unwrap( ) ,
419429 ProposalPart :: Transactions ( TransactionBatch { transactions: TX_BATCH . to_vec( ) } )
420430 ) ;
421431 assert_eq ! (
422432 receiver. next( ) . await . unwrap( ) ,
423433 ProposalPart :: Fin ( ProposalFin {
424- proposal_commitment: TEST_PROPOSAL_COMMITMENT ,
434+ proposal_commitment: expected_proposal_commitment ,
425435 executed_transaction_count: INTERNAL_TX_BATCH . len( ) . try_into( ) . unwrap( ) ,
426436 fin_payload: Some ( ProposalFinPayload {
427437 commitment_parts: CommitmentParts :: default ( ) ,
@@ -430,7 +440,7 @@ async fn build_proposal() {
430440 } )
431441 ) ;
432442 assert ! ( receiver. next( ) . await . is_none( ) ) ;
433- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
443+ assert_eq ! ( fin_receiver. await . unwrap( ) , expected_proposal_commitment ) ;
434444}
435445
436446#[ tokio:: test]
@@ -564,12 +574,12 @@ async fn propose_then_repropose(#[case] execute_all_txs: bool) {
564574 } ;
565575 let _txs = receiver. next ( ) . await . unwrap ( ) ;
566576 let fin = receiver. next ( ) . await . unwrap ( ) ;
567- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
577+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
568578
569579 // Re-propose.
570580 let build_param =
571581 BuildParam { round : ROUND_1 , valid_round : Some ( ROUND_0 ) , ..Default :: default ( ) } ;
572- context. repropose ( TEST_PROPOSAL_COMMITMENT , build_param) . await ;
582+ context. repropose ( * TEST_PROPOSAL_COMMITMENT , build_param) . await ;
573583 // Re-propose sends the same proposal content but with updated init (round, proposer,
574584 // valid_round).
575585 let ( _, mut receiver) = network. outbound_proposal_receiver . next ( ) . await . unwrap ( ) ;
@@ -586,7 +596,7 @@ async fn propose_then_repropose(#[case] execute_all_txs: bool) {
586596 assert ! ( receiver. next( ) . await . is_none( ) ) ;
587597
588598 // Verify decision_reached uses the updated init (from reproposal round) for finalize.
589- context. decision_reached ( HEIGHT_0 , ROUND_1 , TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
599+ context. decision_reached ( HEIGHT_0 , ROUND_1 , * TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
590600}
591601
592602#[ tokio:: test]
@@ -685,7 +695,7 @@ async fn gas_price_limits(#[case] maximum: bool) {
685695 // Even though we used the minimum/maximum gas price, not the values we gave the provider,
686696 // the proposal should be still be valid due to the clamping of limit prices.
687697 let fin_receiver = context. validate_proposal ( init, TIMEOUT , content_receiver) . await ;
688- assert_eq ! ( fin_receiver. await , Ok ( TEST_PROPOSAL_COMMITMENT ) ) ;
698+ assert_eq ! ( fin_receiver. await , Ok ( * TEST_PROPOSAL_COMMITMENT ) ) ;
689699}
690700
691701#[ tokio:: test]
@@ -731,7 +741,7 @@ async fn decision_reached_sends_correct_values() {
731741 let _fin = context. build_proposal ( BuildParam :: default ( ) , TIMEOUT ) . await . unwrap ( ) . await ;
732742 // At this point we should have a valid proposal in the context which contains the timestamp.
733743
734- context. decision_reached ( HEIGHT_0 , ROUND_0 , TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
744+ context. decision_reached ( HEIGHT_0 , ROUND_0 , * TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
735745
736746 let metrics = recorder. handle ( ) . render ( ) ;
737747 CONSENSUS_L2_GAS_PRICE
@@ -891,7 +901,7 @@ async fn oracle_fails_on_startup(#[case] l1_oracle_failure: bool) {
891901 assert_eq ! (
892902 receiver. next( ) . await . unwrap( ) ,
893903 ProposalPart :: Fin ( ProposalFin {
894- proposal_commitment: TEST_PROPOSAL_COMMITMENT ,
904+ proposal_commitment: * TEST_PROPOSAL_COMMITMENT ,
895905 executed_transaction_count: INTERNAL_TX_BATCH . len( ) . try_into( ) . unwrap( ) ,
896906 fin_payload: Some ( ProposalFinPayload {
897907 commitment_parts: CommitmentParts :: default ( ) ,
@@ -900,7 +910,7 @@ async fn oracle_fails_on_startup(#[case] l1_oracle_failure: bool) {
900910 } )
901911 ) ;
902912 assert ! ( receiver. next( ) . await . is_none( ) ) ;
903- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
913+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
904914}
905915
906916#[ rstest]
@@ -973,7 +983,7 @@ async fn oracle_fails_on_second_block(#[case] l1_oracle_failure: bool) {
973983 . validate_proposal ( proposal_init ( HEIGHT_0 , ROUND_0 ) , TIMEOUT , content_receiver)
974984 . await ;
975985 let proposal_commitment = fin_receiver. await . unwrap ( ) ;
976- assert_eq ! ( proposal_commitment, TEST_PROPOSAL_COMMITMENT ) ;
986+ assert_eq ! ( proposal_commitment, * TEST_PROPOSAL_COMMITMENT ) ;
977987
978988 // Decision reached
979989
@@ -1006,7 +1016,7 @@ async fn oracle_fails_on_second_block(#[case] l1_oracle_failure: bool) {
10061016 assert_eq ! (
10071017 receiver. next( ) . await . unwrap( ) ,
10081018 ProposalPart :: Fin ( ProposalFin {
1009- proposal_commitment: TEST_PROPOSAL_COMMITMENT ,
1019+ proposal_commitment: * TEST_PROPOSAL_COMMITMENT ,
10101020 executed_transaction_count: INTERNAL_TX_BATCH . len( ) . try_into( ) . unwrap( ) ,
10111021 fin_payload: Some ( ProposalFinPayload {
10121022 commitment_parts: CommitmentParts :: default ( ) ,
@@ -1015,7 +1025,7 @@ async fn oracle_fails_on_second_block(#[case] l1_oracle_failure: bool) {
10151025 } )
10161026 ) ;
10171027 assert ! ( receiver. next( ) . await . is_none( ) ) ;
1018- assert_eq ! ( fin_receiver. await . unwrap( ) , TEST_PROPOSAL_COMMITMENT ) ;
1028+ assert_eq ! ( fin_receiver. await . unwrap( ) , * TEST_PROPOSAL_COMMITMENT ) ;
10191029}
10201030
10211031// L2 gas is a bit above the minimum gas price.
@@ -1142,7 +1152,7 @@ async fn override_prices_behavior(
11421152 return ;
11431153 }
11441154
1145- context. decision_reached ( HEIGHT_0 , ROUND_0 , TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
1155+ context. decision_reached ( HEIGHT_0 , ROUND_0 , * TEST_PROPOSAL_COMMITMENT , false ) . await . unwrap ( ) ;
11461156
11471157 let actual_l2_gas_price = context. l2_gas_price . 0 ;
11481158
@@ -1268,7 +1278,7 @@ async fn change_gas_price_overrides() {
12681278 . await ;
12691279
12701280 let proposal_commitment = fin_receiver. await . unwrap ( ) ;
1271- assert_eq ! ( proposal_commitment, TEST_PROPOSAL_COMMITMENT ) ;
1281+ assert_eq ! ( proposal_commitment, * TEST_PROPOSAL_COMMITMENT ) ;
12721282
12731283 context. decision_reached ( HEIGHT_0 , ROUND_0 , proposal_commitment, false ) . await . unwrap ( ) ;
12741284
@@ -1297,7 +1307,7 @@ async fn change_gas_price_overrides() {
12971307 let content_receiver = send_proposal_to_validator_context ( & mut context) . await ;
12981308 let fin_receiver = context. validate_proposal ( modified_init, TIMEOUT , content_receiver) . await ;
12991309 let proposal_commitment = fin_receiver. await . unwrap ( ) ;
1300- assert_eq ! ( proposal_commitment, TEST_PROPOSAL_COMMITMENT ) ;
1310+ assert_eq ! ( proposal_commitment, * TEST_PROPOSAL_COMMITMENT ) ;
13011311
13021312 // Validate block number 1, round 1.
13031313 let new_dynamic_config = ContextDynamicConfig {
@@ -1328,7 +1338,7 @@ async fn change_gas_price_overrides() {
13281338 let content_receiver = send_proposal_to_validator_context ( & mut context) . await ;
13291339 let fin_receiver = context. validate_proposal ( modified_init, TIMEOUT , content_receiver) . await ;
13301340 let proposal_commitment = fin_receiver. await . unwrap ( ) ;
1331- assert_eq ! ( proposal_commitment, TEST_PROPOSAL_COMMITMENT ) ;
1341+ assert_eq ! ( proposal_commitment, * TEST_PROPOSAL_COMMITMENT ) ;
13321342
13331343 context. decision_reached ( HEIGHT_1 , ROUND_1 , proposal_commitment, false ) . await . unwrap ( ) ;
13341344
@@ -1347,7 +1357,7 @@ async fn change_gas_price_overrides() {
13471357 . await
13481358 . unwrap ( ) ;
13491359
1350- assert_eq ! ( fin_receiver, TEST_PROPOSAL_COMMITMENT ) ;
1360+ assert_eq ! ( fin_receiver, * TEST_PROPOSAL_COMMITMENT ) ;
13511361 let ( _, mut receiver) = network. outbound_proposal_receiver . next ( ) . await . unwrap ( ) ;
13521362
13531363 let part = receiver. next ( ) . await . unwrap ( ) ;
0 commit comments