fix: Make state root zero on unwind as well

Make it consistent across codebases.
This commit is contained in:
sprites0
2025-07-12 18:15:18 +00:00
parent 87b66170d6
commit c740533904

View File

@ -168,10 +168,10 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
) -> ProviderResult<Box<dyn StateProvider + 'a>> {
let mut block_number =
self.block_number(block_hash)?.ok_or(ProviderError::BlockHashNotFound(block_hash))?;
if block_number == self.best_block_number().unwrap_or_default() &&
block_number == self.last_block_number().unwrap_or_default()
if block_number == self.best_block_number().unwrap_or_default()
&& block_number == self.last_block_number().unwrap_or_default()
{
return Ok(Box::new(LatestStateProviderRef::new(self)))
return Ok(Box::new(LatestStateProviderRef::new(self)));
}
// +1 as the changeset that we want is the one that was applied after this block.
@ -311,11 +311,13 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
storage_prefix_sets,
destroyed_accounts,
};
let (new_state_root, trie_updates) = StateRoot::from_tx(&self.tx)
let (_new_state_root, trie_updates) = StateRoot::from_tx(&self.tx)
.with_prefix_sets(prefix_sets)
.root_with_updates()
.map_err(reth_db_api::DatabaseError::from)?;
let new_state_root = B256::ZERO;
let parent_number = range.start().saturating_sub(1);
let parent_state_root = self
.header_by_number(parent_number)?
@ -332,7 +334,7 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
root: GotExpected { got: new_state_root, expected: parent_state_root },
block_number: parent_number,
block_hash: parent_hash,
})))
})));
}
self.write_trie_updates(&trie_updates)?;
@ -373,10 +375,10 @@ impl<TX: DbTx + 'static, N: NodeTypes> TryIntoHistoricalStateProvider for Databa
self,
mut block_number: BlockNumber,
) -> ProviderResult<StateProviderBox> {
if block_number == self.best_block_number().unwrap_or_default() &&
block_number == self.last_block_number().unwrap_or_default()
if block_number == self.best_block_number().unwrap_or_default()
&& block_number == self.last_block_number().unwrap_or_default()
{
return Ok(Box::new(LatestStateProvider::new(self)))
return Ok(Box::new(LatestStateProvider::new(self)));
}
// +1 as the changeset that we want is the one that was applied after this block.
@ -479,7 +481,7 @@ where
while let Some((sharded_key, list)) = item {
// If the shard does not belong to the key, break.
if !shard_belongs_to_key(&sharded_key) {
break
break;
}
cursor.delete_current()?;
@ -488,12 +490,12 @@ where
let first = list.iter().next().expect("List can't be empty");
if first >= block_number {
item = cursor.prev()?;
continue
continue;
} else if block_number <= sharded_key.as_ref().highest_block_number {
// Filter out all elements greater than block number.
return Ok(list.iter().take_while(|i| *i < block_number).collect::<Vec<_>>())
return Ok(list.iter().take_while(|i| *i < block_number).collect::<Vec<_>>());
}
return Ok(list.iter().collect::<Vec<_>>())
return Ok(list.iter().collect::<Vec<_>>());
}
Ok(Vec::new())
@ -612,7 +614,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
F: FnMut(H, BodyTy<N>, Range<TxNumber>) -> ProviderResult<R>,
{
if range.is_empty() {
return Ok(Vec::new())
return Ok(Vec::new());
}
let len = range.end().saturating_sub(*range.start()) as usize;
@ -807,7 +809,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
// delete old shard so new one can be inserted.
cursor.delete_current()?;
let list = list.iter().collect::<Vec<_>>();
return Ok(list)
return Ok(list);
}
Ok(Vec::new())
}
@ -967,7 +969,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> HeaderSyncGapProvider
}
Ordering::Less => {
// There's either missing or corrupted files.
return Err(ProviderError::HeaderNotFound(next_static_file_block_num.into()))
return Err(ProviderError::HeaderNotFound(next_static_file_block_num.into()));
}
Ordering::Equal => {}
}
@ -1014,7 +1016,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> HeaderProvider for DatabasePro
if let Some(td) = self.chain_spec.final_paris_total_difficulty(number) {
// if this block is higher than the final paris(merge) block, return the final paris
// difficulty
return Ok(Some(td))
return Ok(Some(td));
}
self.static_file_provider.get_with_static_file_or_database(
@ -1079,7 +1081,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> HeaderProvider for DatabasePro
.ok_or_else(|| ProviderError::HeaderNotFound(number.into()))?;
let sealed = SealedHeader::new(header, hash);
if !predicate(&sealed) {
break
break;
}
headers.push(sealed);
}
@ -1174,7 +1176,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvid
// If they exist but are not indexed, we don't have enough
// information to return the block anyways, so we return `None`.
let Some(transactions) = self.transactions_by_block(number.into())? else {
return Ok(None)
return Ok(None);
};
let body = self
@ -1184,7 +1186,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvid
.pop()
.ok_or(ProviderError::InvalidStorageOutput)?;
return Ok(Some(Self::Block::new(header, body)))
return Ok(Some(Self::Block::new(header, body)));
}
}
@ -1432,7 +1434,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> TransactionsProvider for Datab
timestamp: header.timestamp(),
};
return Ok(Some((transaction, meta)))
return Ok(Some((transaction, meta)));
}
}
}
@ -1460,7 +1462,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> TransactionsProvider for Datab
Ok(Some(Vec::new()))
} else {
Ok(Some(self.transactions_by_tx_range_with_cursor(tx_range, &mut tx_cursor)?))
}
};
}
}
Ok(None)
@ -1542,7 +1544,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> ReceiptProvider for DatabasePr
Ok(Some(Vec::new()))
} else {
self.receipts_by_tx_range(tx_range).map(Some)
}
};
}
}
Ok(None)
@ -1586,7 +1588,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Withdrawals
.unwrap_or_default();
Ok(Some(withdrawals))
},
)
);
}
}
Ok(None)
@ -1603,7 +1605,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> OmmersProvider for DatabasePro
// If the Paris (Merge) hardfork block is known and block is after it, return empty
// ommers.
if self.chain_spec.final_paris_total_difficulty(number).is_some() {
return Ok(Some(Vec::new()))
return Ok(Some(Vec::new()));
}
return self.static_file_provider.get_with_static_file_or_database(
@ -1611,7 +1613,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> OmmersProvider for DatabasePro
number,
|static_file| static_file.ommers(id),
|| Ok(self.tx.get::<tables::BlockOmmers<Self::Header>>(number)?.map(|o| o.ommers)),
)
);
}
Ok(None)
@ -1821,8 +1823,8 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
// Prepare receipts static writer if we are going to write receipts to static files
//
// We are writing to static files if requested and if there's no receipt pruning configured
let mut receipts_static_writer = (write_receipts_to.static_files() &&
!has_receipts_pruning)
let mut receipts_static_writer = (write_receipts_to.static_files()
&& !has_receipts_pruning)
.then(|| self.static_file_provider.get_writer(first_block, StaticFileSegment::Receipts))
.transpose()?;
@ -1851,12 +1853,13 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
}
// Skip writing receipts if pruning configuration requires us to.
if prunable_receipts &&
self.prune_modes
if prunable_receipts
&& self
.prune_modes
.receipts
.is_some_and(|mode| mode.should_prune(block_number, tip))
{
continue
continue;
}
// If there are new addresses to retain after this block number, track them
@ -1868,11 +1871,11 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
let receipt_idx = first_tx_index + idx as u64;
// Skip writing receipt if log filter is active and it does not have any logs to
// retain
if prunable_receipts &&
has_contract_log_filter &&
!receipt.logs().iter().any(|log| allowed_addresses.contains(&log.address))
if prunable_receipts
&& has_contract_log_filter
&& !receipt.logs().iter().any(|log| allowed_addresses.contains(&log.address))
{
continue
continue;
}
if let Some(writer) = &mut receipts_static_writer {
@ -2180,7 +2183,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
let range = block + 1..=self.last_block_number()?;
if range.is_empty() {
return Ok(ExecutionOutcome::default())
return Ok(ExecutionOutcome::default());
}
let start_block_number = *range.start();
@ -2298,7 +2301,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> TrieWriter for DatabaseProvider
/// Writes trie updates. Returns the number of entries modified.
fn write_trie_updates(&self, trie_updates: &TrieUpdates) -> ProviderResult<usize> {
if trie_updates.is_empty() {
return Ok(0)
return Ok(0);
}
// Track the number of inserted entries.
@ -2372,7 +2375,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> StorageTrieWriter for DatabaseP
updates: &StorageTrieUpdates,
) -> ProviderResult<usize> {
if updates.is_empty() {
return Ok(0)
return Ok(0);
}
let cursor = self.tx_ref().cursor_dup_write::<tables::StoragesTrie>()?;
@ -2594,7 +2597,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HashingWriter for DatabaseProvi
root: GotExpected { got: state_root, expected: expected_state_root },
block_number: *range.end(),
block_hash: end_block_hash,
})))
})));
}
self.write_trie_updates(&trie_updates)?;
}
@ -2680,8 +2683,8 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HistoryWriter for DatabaseProvi
StorageShardedKey::last(address, storage_key),
rem_index,
|storage_sharded_key| {
storage_sharded_key.address == address &&
storage_sharded_key.sharded_key.key == storage_key
storage_sharded_key.address == address
&& storage_sharded_key.sharded_key.key == storage_key
},
)?;
@ -2980,7 +2983,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
while let Some(Ok((number, hash))) = rev_headers.next() {
if number <= block {
break
break;
}
self.tx.delete::<tables::HeaderNumbers>(hash, None)?;
rev_headers.delete_current()?;
@ -3064,7 +3067,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
) -> ProviderResult<()> {
if blocks.is_empty() {
debug!(target: "providers::db", "Attempted to append empty block range");
return Ok(())
return Ok(());
}
let first_number = blocks.first().unwrap().number();