66mod sequencer_consensus_context_test;
77
88use std:: cmp:: max;
9- use std:: collections:: { BTreeMap , HashMap , VecDeque } ;
9+ use std:: collections:: { BTreeMap , HashMap } ;
1010use std:: sync:: { Arc , Mutex } ;
1111use std:: time:: Duration ;
1212
@@ -235,9 +235,8 @@ pub struct SequencerConsensusContext {
235235 l2_gas_price : GasPrice ,
236236 l1_da_mode : L1DataAvailabilityMode ,
237237 previous_proposal_init : Option < PreviousProposalInitInfo > ,
238- /// SNIP-35: sliding window of recent fee_proposal values (size from
239- /// `FEE_PROPOSAL_WINDOW_SIZE`).
240- fee_proposals_window : VecDeque < GasPrice > ,
238+ /// SNIP-35 fee_proposals window. `None` = pre-V0_14_3.
239+ fee_proposals_window : BTreeMap < BlockNumber , Option < GasPrice > > ,
241240}
242241
243242#[ derive( Clone ) ]
@@ -288,16 +287,19 @@ impl SequencerConsensusContext {
288287 l2_gas_price : VersionedConstants :: latest_constants ( ) . min_gas_price ,
289288 l1_da_mode,
290289 previous_proposal_init : None ,
291- fee_proposals_window : VecDeque :: with_capacity ( FEE_PROPOSAL_WINDOW_SIZE ) ,
290+ fee_proposals_window : BTreeMap :: new ( ) ,
292291 }
293292 }
294293
295- /// FIFO append into the SNIP-35 sliding window.
296- fn push_fee_proposal ( & mut self , fee_proposal : GasPrice ) {
297- if self . fee_proposals_window . len ( ) >= FEE_PROPOSAL_WINDOW_SIZE {
298- self . fee_proposals_window . pop_front ( ) ;
299- }
300- self . fee_proposals_window . push_back ( fee_proposal) ;
294+ fn record_fee_proposal ( & mut self , height : BlockNumber , fee_proposal_fri : Option < GasPrice > ) {
295+ self . fee_proposals_window . insert ( height, fee_proposal_fri) ;
296+ }
297+
298+ fn prune_fee_proposals_window ( & mut self , current_height : BlockNumber ) {
299+ let window_size =
300+ u64:: try_from ( FEE_PROPOSAL_WINDOW_SIZE ) . expect ( "FEE_PROPOSAL_WINDOW_SIZE fits in u64" ) ;
301+ let cutoff = BlockNumber ( current_height. 0 . saturating_sub ( window_size) ) ;
302+ self . fee_proposals_window = self . fee_proposals_window . split_off ( & cutoff) ;
301303 }
302304
303305 /// SNIP-35: bootstrap the fee_proposals window from state_sync on startup so `fee_actual` is
@@ -315,10 +317,11 @@ impl SequencerConsensusContext {
315317 u64:: try_from ( FEE_PROPOSAL_WINDOW_SIZE ) . expect ( "FEE_PROPOSAL_WINDOW_SIZE fits in u64" ) ;
316318 let start = height. 0 . saturating_sub ( window_size) ;
317319 for h in start..height. 0 {
318- match self . deps . state_sync_client . get_block ( BlockNumber ( h) ) . await {
320+ let block_number = BlockNumber ( h) ;
321+ match self . deps . state_sync_client . get_block ( block_number) . await {
319322 Ok ( block) => {
320323 if let Some ( fee_proposal) = block. block_header_without_hash . fee_proposal_fri {
321- self . push_fee_proposal ( fee_proposal) ;
324+ self . record_fee_proposal ( block_number , Some ( fee_proposal) ) ;
322325 }
323326 }
324327 Err ( e) => {
@@ -436,9 +439,7 @@ impl SequencerConsensusContext {
436439 let DecisionReachedResponse { state_diff, central_objects } = decision_reached_response;
437440
438441 self . update_l2_gas_price ( height, l2_gas_used) ;
439- if let Some ( fee_proposal) = init. fee_proposal_fri {
440- self . push_fee_proposal ( fee_proposal) ;
441- }
442+ self . record_fee_proposal ( height, init. fee_proposal_fri ) ;
442443
443444 // A hash map of (possibly failed) transactions, where the key is the transaction hash
444445 // and the value is the transaction itself.
@@ -891,9 +892,10 @@ impl ConsensusContext for SequencerConsensusContext {
891892 sync_block. block_header_without_hash . next_l2_gas_price ,
892893 VersionedConstants :: latest_constants ( ) . min_gas_price ,
893894 ) ;
894- if let Some ( fee_proposal) = sync_block. block_header_without_hash . fee_proposal_fri {
895- self . push_fee_proposal ( fee_proposal) ;
896- }
895+ self . record_fee_proposal (
896+ sync_block. block_header_without_hash . block_number ,
897+ sync_block. block_header_without_hash . fee_proposal_fri ,
898+ ) ;
897899
898900 // TODO(Asmaa): validate starknet_version and parent_hash when they are stored.
899901 let block_number = sync_block. block_header_without_hash . block_number ;
@@ -958,6 +960,7 @@ impl ConsensusContext for SequencerConsensusContext {
958960 }
959961 self . current_height = Some ( height) ;
960962 self . current_round = round;
963+ self . prune_fee_proposals_window ( height) ;
961964 self . queued_proposals . clear ( ) ;
962965 // The Batcher must be told when we begin to work on a new height. The implicit model is
963966 // that consensus works on a given height until it is done (either a decision is reached
0 commit comments