@@ -174,6 +174,9 @@ fn process_payload(payload: FlashblocksPayloadV1, cache: Arc<Cache>) {
174
174
return ;
175
175
}
176
176
177
+ // Track flashblock indices and record metrics
178
+ update_flashblocks_index ( payload. index , & cache, & metrics) ;
179
+
177
180
// Prevent updating to older blocks
178
181
let current_block = cache. get :: < OpBlock > ( "pending" ) ;
179
182
if current_block. is_some ( ) && current_block. unwrap ( ) . number > block_number {
@@ -302,6 +305,32 @@ fn process_payload(payload: FlashblocksPayloadV1, cache: Arc<Cache>) {
302
305
}
303
306
}
304
307
308
+ fn update_flashblocks_index ( index : u64 , cache : & Arc < Cache > , metrics : & Metrics ) {
309
+ if index == 0 {
310
+ // Get highest index from previous block
311
+ if let Some ( prev_highest_index) = cache. get :: < u64 > ( "highest_payload_index" ) {
312
+ // Record metric: total flash blocks = highest_index + 1 (since it's 0-indexed)
313
+ metrics
314
+ . flashblocks_in_block
315
+ . record ( ( prev_highest_index + 1 ) as f64 ) ;
316
+ println ! ( "Previous block had {} flash blocks" , prev_highest_index + 1 ) ;
317
+ }
318
+
319
+ // Reset highest index to 0 for new block
320
+ if let Err ( e) = cache. set ( "highest_payload_index" , & 0u64 , Some ( 10 ) ) {
321
+ error ! ( "Failed to reset highest flash index: {}" , e) ;
322
+ }
323
+ } else {
324
+ // Update highest index if current index is higher
325
+ let current_highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap_or ( 0 ) ;
326
+ if index > current_highest {
327
+ if let Err ( e) = cache. set ( "highest_payload_index" , & index, Some ( 10 ) ) {
328
+ error ! ( "Failed to update highest flash index: {}" , e) ;
329
+ }
330
+ }
331
+ }
332
+ }
333
+
305
334
fn get_and_set_transactions (
306
335
transactions : Vec < Bytes > ,
307
336
payload_index : u64 ,
@@ -506,6 +535,50 @@ mod tests {
506
535
}
507
536
}
508
537
538
+ // Create payload with specific index and block number
539
+ fn create_payload_with_index ( index : u64 , block_number : u64 ) -> FlashblocksPayloadV1 {
540
+ let base = if index == 0 {
541
+ Some ( ExecutionPayloadBaseV1 {
542
+ parent_hash : Default :: default ( ) ,
543
+ parent_beacon_block_root : Default :: default ( ) ,
544
+ fee_recipient : Address :: from_str ( "0x1234567890123456789012345678901234567890" )
545
+ . unwrap ( ) ,
546
+ block_number,
547
+ gas_limit : 1000000 ,
548
+ timestamp : 1234567890 ,
549
+ prev_randao : Default :: default ( ) ,
550
+ extra_data : Default :: default ( ) ,
551
+ base_fee_per_gas : U256 :: from ( 1000 ) ,
552
+ } )
553
+ } else {
554
+ None
555
+ } ;
556
+
557
+ let delta = ExecutionPayloadFlashblockDeltaV1 {
558
+ transactions : vec ! [ ] ,
559
+ withdrawals : vec ! [ ] ,
560
+ state_root : B256 :: repeat_byte ( index as u8 ) ,
561
+ receipts_root : B256 :: repeat_byte ( ( index + 1 ) as u8 ) ,
562
+ logs_bloom : Default :: default ( ) ,
563
+ gas_used : 21000 * index,
564
+ block_hash : B256 :: repeat_byte ( ( index + 2 ) as u8 ) ,
565
+ } ;
566
+
567
+ let metadata = Metadata {
568
+ block_number,
569
+ receipts : HashMap :: default ( ) ,
570
+ new_account_balances : HashMap :: default ( ) ,
571
+ } ;
572
+
573
+ FlashblocksPayloadV1 {
574
+ index,
575
+ payload_id : PayloadId :: new ( [ 0 ; 8 ] ) ,
576
+ base,
577
+ diff : delta,
578
+ metadata : serde_json:: to_value ( metadata) . unwrap ( ) ,
579
+ }
580
+ }
581
+
509
582
fn create_second_payload ( ) -> FlashblocksPayloadV1 {
510
583
// Create second payload (index 1) with transactions
511
584
// tx1 hash: 0x3cbbc9a6811ac5b2a2e5780bdb67baffc04246a59f39e398be048f1b2d05460c
@@ -688,4 +761,76 @@ mod tests {
688
761
// Verify no block was stored, since it skips the first payload
689
762
assert ! ( cache. get:: <OpBlock >( "pending" ) . is_none( ) ) ;
690
763
}
764
+
765
+ #[ test]
766
+ fn test_flash_block_tracking ( ) {
767
+ // Create cache
768
+ let cache = Arc :: new ( Cache :: default ( ) ) ;
769
+
770
+ // Process first block with 3 flash blocks
771
+ // Block 1, payload 0 (starts a new block)
772
+ let payload1_0 = create_payload_with_index ( 0 , 1 ) ;
773
+ process_payload ( payload1_0, cache. clone ( ) ) ;
774
+
775
+ // Check that highest_payload_index was set to 0
776
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
777
+ assert_eq ! ( highest, 0 ) ;
778
+
779
+ // Block 1, payload 1
780
+ let payload1_1 = create_payload_with_index ( 1 , 1 ) ;
781
+ process_payload ( payload1_1, cache. clone ( ) ) ;
782
+
783
+ // Check that highest_payload_index was updated
784
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
785
+ assert_eq ! ( highest, 1 ) ;
786
+
787
+ // Block 1, payload 2
788
+ let payload1_2 = create_payload_with_index ( 2 , 1 ) ;
789
+ process_payload ( payload1_2, cache. clone ( ) ) ;
790
+
791
+ // Check that highest_payload_index was updated
792
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
793
+ assert_eq ! ( highest, 2 ) ;
794
+
795
+ // Now start a new block (block 2, payload 0)
796
+ let payload2_0 = create_payload_with_index ( 0 , 2 ) ;
797
+ process_payload ( payload2_0, cache. clone ( ) ) ;
798
+
799
+ // Check that highest_payload_index was reset to 0
800
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
801
+ assert_eq ! ( highest, 0 ) ;
802
+
803
+ // Block 2, payload 1 (out of order with payload 3)
804
+ let payload2_1 = create_payload_with_index ( 1 , 2 ) ;
805
+ process_payload ( payload2_1, cache. clone ( ) ) ;
806
+
807
+ // Check that highest_payload_index was updated
808
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
809
+ assert_eq ! ( highest, 1 ) ;
810
+
811
+ // Block 2, payload 3 (skipping 2)
812
+ let payload2_3 = create_payload_with_index ( 3 , 2 ) ;
813
+ process_payload ( payload2_3, cache. clone ( ) ) ;
814
+
815
+ // Check that highest_payload_index was updated
816
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
817
+ assert_eq ! ( highest, 3 ) ;
818
+
819
+ // Block 2, payload 2 (out of order, should not change highest)
820
+ let payload2_2 = create_payload_with_index ( 2 , 2 ) ;
821
+ process_payload ( payload2_2, cache. clone ( ) ) ;
822
+
823
+ // Check that highest_payload_index is still 3
824
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
825
+ assert_eq ! ( highest, 3 ) ;
826
+
827
+ // Start block 3, payload 0
828
+ let payload3_0 = create_payload_with_index ( 0 , 3 ) ;
829
+ process_payload ( payload3_0, cache. clone ( ) ) ;
830
+
831
+ // Check that highest_payload_index was reset to 0
832
+ // Also verify metric would have been recorded (though we can't directly check the metric's value)
833
+ let highest = cache. get :: < u64 > ( "highest_payload_index" ) . unwrap ( ) ;
834
+ assert_eq ! ( highest, 0 ) ;
835
+ }
691
836
}
0 commit comments