perf(storage): skip plain state conversion in write_state for storage v2 (#22294)

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com>
This commit is contained in:
Georgios Konstantopoulos
2026-02-17 16:48:06 -08:00
committed by GitHub
parent 5045e6ef8b
commit a195b777eb

View File

@@ -843,6 +843,18 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
Ok(())
}
/// Writes bytecodes to MDBX.
fn write_bytecodes(
&self,
bytecodes: impl IntoIterator<Item = (B256, Bytecode)>,
) -> ProviderResult<()> {
let mut bytecodes_cursor = self.tx_ref().cursor_write::<tables::Bytecodes>()?;
for (hash, bytecode) in bytecodes {
bytecodes_cursor.upsert(hash, &bytecode)?;
}
Ok(())
}
}
impl<TX: DbTx + 'static, N: NodeTypes> TryIntoHistoricalStateProvider for DatabaseProvider<TX, N> {
@@ -2366,8 +2378,22 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
config: StateWriteConfig,
) -> ProviderResult<()> {
let execution_outcome = execution_outcome.into();
let first_block = execution_outcome.first_block();
if self.cached_storage_settings().use_hashed_state() &&
!config.write_receipts &&
!config.write_account_changesets &&
!config.write_storage_changesets
{
// In storage v2 with all outputs directed to static files, plain state and changesets
// are written elsewhere. Only bytecodes need MDBX writes, so skip the expensive
// to_plain_state_and_reverts conversion that iterates all accounts and storage.
self.write_bytecodes(
execution_outcome.state().contracts.iter().map(|(h, b)| (*h, Bytecode(b.clone()))),
)?;
return Ok(());
}
let first_block = execution_outcome.first_block();
let (plain_state, reverts) =
execution_outcome.state().to_plain_state_and_reverts(is_value_known);
@@ -2624,10 +2650,9 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
// Write bytecode
tracing::trace!(len = changes.contracts.len(), "Writing bytecodes");
let mut bytecodes_cursor = self.tx_ref().cursor_write::<tables::Bytecodes>()?;
for (hash, bytecode) in changes.contracts {
bytecodes_cursor.upsert(hash, &Bytecode(bytecode))?;
}
self.write_bytecodes(
changes.contracts.into_iter().map(|(hash, bytecode)| (hash, Bytecode(bytecode))),
)?;
Ok(())
}