From a8ed1c672f3fdbc7a30e88458e866d54240c2b34 Mon Sep 17 00:00:00 2001 From: Kenil shah Date: Wed, 25 Mar 2026 00:26:25 +0530 Subject: [PATCH] perf: stack-allocate PlainKey encoding in hot EVM state read path --- crates/stateless-core/src/data_types.rs | 13 +++++++++++++ crates/stateless-core/src/database.rs | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/crates/stateless-core/src/data_types.rs b/crates/stateless-core/src/data_types.rs index b7b6ba31..f24d90af 100644 --- a/crates/stateless-core/src/data_types.rs +++ b/crates/stateless-core/src/data_types.rs @@ -71,6 +71,19 @@ impl PlainKey { } } + /// Encodes an account address into a stack-allocated 20-byte array. + pub fn encode_account(addr: Address) -> [u8; ACCOUNT_ADDRESS_LEN] { + addr.into_array() + } + + /// Encodes an address + storage slot into a stack-allocated 52-byte array. + pub fn encode_storage(addr: Address, slot: B256) -> [u8; STORAGE_SLOT_KEY_LEN] { + let mut buf = [0u8; STORAGE_SLOT_KEY_LEN]; + buf[..ACCOUNT_ADDRESS_LEN].copy_from_slice(addr.as_slice()); + buf[ACCOUNT_ADDRESS_LEN..].copy_from_slice(slot.as_slice()); + buf + } + /// Decodes a byte slice into a PlainKey. /// /// Returns `PlainKey::Unknown` if the buffer length is neither 20 (account) diff --git a/crates/stateless-core/src/database.rs b/crates/stateless-core/src/database.rs index 9596113e..b3849fe7 100644 --- a/crates/stateless-core/src/database.rs +++ b/crates/stateless-core/src/database.rs @@ -94,7 +94,7 @@ where fn basic_ref(&self, address: Address) -> Result, Self::Error> { trace!(?address, "basic_ref"); - let raw_value = self.plain_value(&PlainKey::Account(address).encode())?; + let raw_value = self.plain_value(&PlainKey::encode_account(address))?; match raw_value.and_then(|v| match PlainValue::decode(&v) { PlainValue::Account(acc) => Some(acc), @@ -130,7 +130,7 @@ where fn storage_ref(&self, address: Address, index: U256) -> Result { trace!(?address, index = %format_args!("{:#x}", index), "storage_ref"); - let raw_value = self.plain_value(&PlainKey::Storage(address, index.into()).encode())?; + let raw_value = self.plain_value(&PlainKey::encode_storage(address, index.into()))?; Ok(raw_value .and_then(|v| match PlainValue::decode(&v) { @@ -292,11 +292,11 @@ impl SaltEnv for WitnessExternalEnv { } fn bucket_id_for_account(account: Address) -> BucketId { - hasher::bucket_id(&PlainKey::Account(account).encode()) + hasher::bucket_id(&PlainKey::encode_account(account)) } fn bucket_id_for_slot(address: Address, key: U256) -> BucketId { - hasher::bucket_id(&PlainKey::Storage(address, key.into()).encode()) + hasher::bucket_id(&PlainKey::encode_storage(address, key.into())) } }