From d03c0d8f6a7a08a53b355364085bbb8f9f2df4c4 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 29 Apr 2026 12:15:28 +0000 Subject: [PATCH] fix(re-execute): properly handle selfdestructed storage slots --- crates/cli/commands/src/re_execute.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/cli/commands/src/re_execute.rs b/crates/cli/commands/src/re_execute.rs index cb65502be43..5923fde9f3c 100644 --- a/crates/cli/commands/src/re_execute.rs +++ b/crates/cli/commands/src/re_execute.rs @@ -20,7 +20,10 @@ use reth_provider::{ }; use reth_revm::{ database::StateProviderDatabase, - db::{states::reverts::AccountInfoRevert, BundleState}, + db::{ + states::reverts::{AccountInfoRevert, RevertToSlot}, + BundleState, + }, }; use reth_stages::stages::calculate_gas_used_from_headers; use reth_storage_api::{ChangeSetReader, DBProvider, StorageChangeSetReader}; @@ -425,14 +428,19 @@ where let mut cs_slots = cs_storage.get_mut(addr); for (slot_key, revert_slot) in &revert.storage { let b256_key = B256::from(*slot_key); - match cs_slots.as_mut().and_then(|s| s.remove(&b256_key)) { - Some(cs_value) => eyre::ensure!( - revert_slot.to_previous_value() == cs_value, + let cs_value = cs_slots.as_mut().and_then(|s| s.remove(&b256_key)); + match (revert_slot, cs_value) { + // When a contract is selfdestructed and re-created at the same address + // within the same block, revm marks slots touched by the new contract + // as `Destroyed` and never reads the original DB value, so + // `to_previous_value()` would resolve to zero, which might be wrong. + (RevertToSlot::Destroyed, _) => {} + (RevertToSlot::Some(prev), Some(cs_value)) => eyre::ensure!( + *prev == cs_value, "Block {block_number}: {addr} slot {b256_key} mismatch: \ - revert={} cs={cs_value}", - revert_slot.to_previous_value(), + revert={prev} cs={cs_value}", ), - None => eyre::ensure!( + (RevertToSlot::Some(_), None) => eyre::ensure!( revert.wipe_storage, "Block {block_number}: {addr} slot {b256_key} in reverts but not in changeset", ),