Skip to content

Commit b544fab

Browse files
committed
Implement flash block tracking and metrics recording in process_payload function
1 parent 3f3d846 commit b544fab

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

crates/flashblocks-rpc/src/flashblocks.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,31 @@ fn process_payload(payload: FlashblocksPayloadV1, cache: Arc<Cache>) {
174174
return;
175175
}
176176

177+
// When index is 0, we're starting a new block - emit metric for previous block
178+
let index = payload.index;
179+
if index == 0 {
180+
// Get highest index from previous block
181+
if let Some(prev_highest_index) = cache.get::<u64>("highest_payload_index") {
182+
// Record metric: total flash blocks = highest_index + 1 (since it's 0-indexed)
183+
metrics.flashblocks_in_block.record((prev_highest_index + 1) as f64);
184+
println!("Previous block had {} flash blocks", prev_highest_index + 1);
185+
}
186+
187+
// Reset highest index to 0 for new block
188+
if let Err(e) = cache.set("highest_payload_index", &0u64, Some(10)) {
189+
error!("Failed to reset highest flash index: {}", e);
190+
}
191+
} else {
192+
// Update highest index if current index is higher
193+
let current_highest = cache.get::<u64>("highest_payload_index").unwrap_or(0);
194+
if index > current_highest {
195+
if let Err(e) = cache.set("highest_payload_index", &index, Some(10)) {
196+
error!("Failed to update highest flash index: {}", e);
197+
}
198+
}
199+
}
200+
201+
177202
// Prevent updating to older blocks
178203
let current_block = cache.get::<OpBlock>("pending");
179204
if current_block.is_some() && current_block.unwrap().number > block_number {
@@ -505,6 +530,49 @@ mod tests {
505530
metadata: serde_json::to_value(metadata).unwrap(),
506531
}
507532
}
533+
534+
// Create payload with specific index and block number
535+
fn create_payload_with_index(index: u64, block_number: u64) -> FlashblocksPayloadV1 {
536+
let base = if index == 0 {
537+
Some(ExecutionPayloadBaseV1 {
538+
parent_hash: Default::default(),
539+
parent_beacon_block_root: Default::default(),
540+
fee_recipient: Address::from_str("0x1234567890123456789012345678901234567890").unwrap(),
541+
block_number,
542+
gas_limit: 1000000,
543+
timestamp: 1234567890,
544+
prev_randao: Default::default(),
545+
extra_data: Default::default(),
546+
base_fee_per_gas: U256::from(1000),
547+
})
548+
} else {
549+
None
550+
};
551+
552+
let delta = ExecutionPayloadFlashblockDeltaV1 {
553+
transactions: vec![],
554+
withdrawals: vec![],
555+
state_root: B256::repeat_byte(index as u8),
556+
receipts_root: B256::repeat_byte((index + 1) as u8),
557+
logs_bloom: Default::default(),
558+
gas_used: 21000 * index,
559+
block_hash: B256::repeat_byte((index + 2) as u8),
560+
};
561+
562+
let metadata = Metadata {
563+
block_number,
564+
receipts: HashMap::default(),
565+
new_account_balances: HashMap::default(),
566+
};
567+
568+
FlashblocksPayloadV1 {
569+
index,
570+
payload_id: PayloadId::new([0; 8]),
571+
base,
572+
diff: delta,
573+
metadata: serde_json::to_value(metadata).unwrap(),
574+
}
575+
}
508576

509577
fn create_second_payload() -> FlashblocksPayloadV1 {
510578
// Create second payload (index 1) with transactions
@@ -688,4 +756,76 @@ mod tests {
688756
// Verify no block was stored, since it skips the first payload
689757
assert!(cache.get::<OpBlock>("pending").is_none());
690758
}
759+
760+
#[test]
761+
fn test_flash_block_tracking() {
762+
// Create cache
763+
let cache = Arc::new(Cache::default());
764+
765+
// Process first block with 3 flash blocks
766+
// Block 1, payload 0 (starts a new block)
767+
let payload1_0 = create_payload_with_index(0, 1);
768+
process_payload(payload1_0, cache.clone());
769+
770+
// Check that highest_payload_index was set to 0
771+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
772+
assert_eq!(highest, 0);
773+
774+
// Block 1, payload 1
775+
let payload1_1 = create_payload_with_index(1, 1);
776+
process_payload(payload1_1, cache.clone());
777+
778+
// Check that highest_payload_index was updated
779+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
780+
assert_eq!(highest, 1);
781+
782+
// Block 1, payload 2
783+
let payload1_2 = create_payload_with_index(2, 1);
784+
process_payload(payload1_2, cache.clone());
785+
786+
// Check that highest_payload_index was updated
787+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
788+
assert_eq!(highest, 2);
789+
790+
// Now start a new block (block 2, payload 0)
791+
let payload2_0 = create_payload_with_index(0, 2);
792+
process_payload(payload2_0, cache.clone());
793+
794+
// Check that highest_payload_index was reset to 0
795+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
796+
assert_eq!(highest, 0);
797+
798+
// Block 2, payload 1 (out of order with payload 3)
799+
let payload2_1 = create_payload_with_index(1, 2);
800+
process_payload(payload2_1, cache.clone());
801+
802+
// Check that highest_payload_index was updated
803+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
804+
assert_eq!(highest, 1);
805+
806+
// Block 2, payload 3 (skipping 2)
807+
let payload2_3 = create_payload_with_index(3, 2);
808+
process_payload(payload2_3, cache.clone());
809+
810+
// Check that highest_payload_index was updated
811+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
812+
assert_eq!(highest, 3);
813+
814+
// Block 2, payload 2 (out of order, should not change highest)
815+
let payload2_2 = create_payload_with_index(2, 2);
816+
process_payload(payload2_2, cache.clone());
817+
818+
// Check that highest_payload_index is still 3
819+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
820+
assert_eq!(highest, 3);
821+
822+
// Start block 3, payload 0
823+
let payload3_0 = create_payload_with_index(0, 3);
824+
process_payload(payload3_0, cache.clone());
825+
826+
// Check that highest_payload_index was reset to 0
827+
// Also verify metric would have been recorded (though we can't directly check the metric's value)
828+
let highest = cache.get::<u64>("highest_payload_index").unwrap();
829+
assert_eq!(highest, 0);
830+
}
691831
}

crates/flashblocks-rpc/src/metrics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ pub struct Metrics {
2626

2727
#[metric(describe = "Count of times flashblocks get_block_by_number is called")]
2828
pub get_block_by_number: Counter,
29+
30+
#[metric(describe = "Number of flashblocks in a block")]
31+
pub flashblocks_in_block: Histogram,
2932
}

0 commit comments

Comments
 (0)