Skip to content

Commit 5f2e85c

Browse files
committed
Remove pre execution block from DA checker if execution failed to allow re-processing.
1 parent f2d5e92 commit 5f2e85c

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3377,7 +3377,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
33773377
.set_time_consensus_verified(block_root, block_slot, timestamp)
33783378
}
33793379

3380-
let executed_block = chain.into_executed_block(execution_pending).await?;
3380+
let executed_block = chain
3381+
.into_executed_block(execution_pending)
3382+
.await
3383+
.inspect_err(|_| {
3384+
// If the block fails execution for whatever reason (e.g. engine offline),
3385+
// and we keep it in the cache, then the node will NOT perform lookup and
3386+
// reprocess this block until the block is evicted from DA checker, causing the
3387+
// chain to get stuck temporarily if the block is canonical. Therefore we remove
3388+
// it from the cache if execution fails.
3389+
self.data_availability_checker
3390+
.remove_block_on_execution_error(&block_root);
3391+
})?;
33813392

33823393
// Record the *additional* time it took to wait for execution layer verification.
33833394
if let Some(timestamp) = self.slot_clock.now_duration() {

beacon_node/beacon_chain/src/data_availability_checker.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,13 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
356356
.put_pre_execution_block(block_root, block)
357357
}
358358

359+
/// Removes a pre-execution block from the cache.
360+
/// This does NOT remove an existing executed block.
361+
pub fn remove_block_on_execution_error(&self, block_root: &Hash256) {
362+
self.availability_cache
363+
.remove_pre_execution_block(block_root);
364+
}
365+
359366
/// Verifies kzg commitments for an RpcBlock, returns a `MaybeAvailableBlock` that may
360367
/// include the fully available block.
361368
///

beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,15 @@ impl<T: BeaconChainTypes> DataAvailabilityCheckerInner<T> {
704704
Ok(())
705705
}
706706

707+
/// Removes a pre-execution block from the cache.
708+
/// This does NOT remove an existing executed block.
709+
pub fn remove_pre_execution_block(&self, block_root: &Hash256) {
710+
// The read lock is immediately dropped so we can safely remove the block from the cache.
711+
if let Some(BlockProcessStatus::NotValidated(_)) = self.get_cached_block(block_root) {
712+
self.critical.write().pop(block_root);
713+
}
714+
}
715+
707716
/// Check if we have all the blobs for a block. If we do, return the Availability variant that
708717
/// triggers import of the block.
709718
pub fn put_executed_block(
@@ -1429,4 +1438,34 @@ mod pending_components_tests {
14291438

14301439
assert_cache_consistent(cache, max_len);
14311440
}
1441+
1442+
#[test]
1443+
fn should_not_insert_pre_execution_block_if_executed_block_exists() {
1444+
let (pre_execution_block, blobs, random_blobs, max_len) = pre_setup();
1445+
let (executed_block, blobs, random_blobs) =
1446+
setup_pending_components(pre_execution_block.clone(), blobs, random_blobs);
1447+
1448+
let block_root = pre_execution_block.canonical_root();
1449+
let max_blobs_per_block = 6; // doesn't matter here
1450+
let mut pending_component = <PendingComponents<E>>::empty(block_root, max_blobs_per_block);
1451+
1452+
let pre_execution_block = Arc::new(pre_execution_block);
1453+
pending_component.insert_pre_execution_block(pre_execution_block.clone());
1454+
assert!(
1455+
matches!(pending_component.block, Some(CachedBlock::PreExecution(_))),
1456+
"pre execution block inserted"
1457+
);
1458+
1459+
pending_component.insert_executed_block(executed_block);
1460+
assert!(
1461+
matches!(pending_component.block, Some(CachedBlock::Executed(_))),
1462+
"executed block inserted"
1463+
);
1464+
1465+
pending_component.insert_pre_execution_block(pre_execution_block);
1466+
assert!(
1467+
matches!(pending_component.block, Some(CachedBlock::Executed(_))),
1468+
"executed block should remain"
1469+
);
1470+
}
14321471
}

beacon_node/network/src/sync/tests/lookups.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,11 @@ impl TestRig {
11231123
}
11241124

11251125
fn simulate_block_gossip_processing_becomes_invalid(&mut self, block_root: Hash256) {
1126+
self.harness
1127+
.chain
1128+
.data_availability_checker
1129+
.remove_block_on_execution_error(&block_root);
1130+
11261131
self.send_sync_message(SyncMessage::GossipBlockProcessResult {
11271132
block_root,
11281133
imported: false,

0 commit comments

Comments
 (0)