Skip to content

Commit 390292e

Browse files
committed
Fix some tests
1 parent bc9912e commit 390292e

File tree

4 files changed

+253
-60
lines changed

4 files changed

+253
-60
lines changed

crates/op-rbuilder/src/block_stm/db_adapter.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,11 +342,35 @@ where
342342
}
343343
};
344344

345+
// Get bytecode - check MVHashMap first for newly deployed contracts
346+
let code = if code_hash != revm::primitives::KECCAK_EMPTY {
347+
// Contract exists - try to get bytecode
348+
if let Some(base_code) = &base_info.code {
349+
if base_code.len() > 0 {
350+
// Base has the code
351+
Some(base_code.clone())
352+
} else {
353+
// Base code is empty, check MVHashMap for newly deployed contracts
354+
self.mv_hashmap
355+
.get_bytecode(code_hash, self.txn_idx)
356+
.map(Bytecode::new_raw)
357+
}
358+
} else {
359+
// No code in base, check MVHashMap for newly deployed contracts
360+
self.mv_hashmap
361+
.get_bytecode(code_hash, self.txn_idx)
362+
.map(Bytecode::new_raw)
363+
}
364+
} else {
365+
// No contract (KECCAK_EMPTY means no code)
366+
None
367+
};
368+
345369
let account_info = AccountInfo {
346370
balance,
347371
nonce,
348372
code_hash,
349-
code: base_info.code.clone(),
373+
code,
350374
};
351375

352376
// Cache the result
@@ -404,7 +428,12 @@ where
404428

405429
/// Read contract code by hash.
406430
fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, VersionedDbError> {
407-
// Code is usually immutable, read directly from base
431+
// First check MVHashMap for bytecode deployed by earlier transactions in this block
432+
if let Some(bytecode_bytes) = self.mv_hashmap.get_bytecode(code_hash, self.txn_idx) {
433+
return Ok(Bytecode::new_raw(bytecode_bytes));
434+
}
435+
436+
// Fall back to base database for pre-existing contracts
408437
self.base_db
409438
.code_by_hash_ref(code_hash)
410439
.map_err(|e| VersionedDbError::BaseDbError(e.to_string()))

crates/op-rbuilder/src/block_stm/mv_hashmap.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use crate::block_stm::types::{
1414
EvmStateKey, EvmStateValue, Incarnation, ReadResult, ResolvedBalance, TxnIndex, Version,
1515
};
16-
use alloy_primitives::{Address, U256};
16+
use alloy_primitives::{Address, B256, Bytes, U256};
1717
use parking_lot::RwLock;
1818
use std::{
1919
collections::{BTreeMap, HashMap, HashSet},
@@ -254,6 +254,10 @@ pub struct MVHashMap {
254254
/// Balance deltas indexed by address.
255255
/// These are commutative increments that don't conflict with each other.
256256
balance_deltas: RwLock<HashMap<Address, RwLock<VersionedDeltas>>>,
257+
/// Bytecode cache for newly deployed contracts.
258+
/// Maps code_hash → (bytecode, txn_idx that deployed it).
259+
/// This allows parallel transactions to access code deployed in the same block.
260+
bytecode_cache: RwLock<HashMap<B256, (Bytes, TxnIndex)>>,
257261
/// Number of transactions in the block (reserved for future use).
258262
#[allow(dead_code)]
259263
num_txns: usize,
@@ -265,10 +269,35 @@ impl MVHashMap {
265269
Self {
266270
data: RwLock::new(HashMap::new()),
267271
balance_deltas: RwLock::new(HashMap::new()),
272+
bytecode_cache: RwLock::new(HashMap::new()),
268273
num_txns,
269274
}
270275
}
271276

277+
/// Store bytecode for a newly deployed contract.
278+
/// This makes the bytecode available to parallel transactions.
279+
pub fn store_bytecode(&self, code_hash: B256, bytecode: Bytes, txn_idx: TxnIndex) {
280+
// Don't store empty bytecode or the KECCAK_EMPTY hash
281+
if bytecode.is_empty() || code_hash == revm::primitives::KECCAK_EMPTY {
282+
return;
283+
}
284+
let mut cache = self.bytecode_cache.write();
285+
cache.insert(code_hash, (bytecode, txn_idx));
286+
}
287+
288+
/// Retrieve bytecode by hash, if it was deployed by a transaction before reader_txn_idx.
289+
pub fn get_bytecode(&self, code_hash: B256, reader_txn_idx: TxnIndex) -> Option<Bytes> {
290+
let cache = self.bytecode_cache.read();
291+
cache.get(&code_hash).and_then(|(bytecode, writer_txn_idx)| {
292+
// Only return bytecode if it was written by an earlier transaction
293+
if *writer_txn_idx < reader_txn_idx {
294+
Some(bytecode.clone())
295+
} else {
296+
None
297+
}
298+
})
299+
}
300+
272301
/// Write a value at the given version.
273302
#[instrument(level = "trace", skip(self, value), fields(txn_idx, incarnation, key = %key))]
274303
pub fn write(

crates/op-rbuilder/src/builders/builder_tx.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,21 @@ pub trait BuilderTransactions<
275275
) -> State<StateProviderDatabase<impl StateProvider>> {
276276
let state = StateProviderDatabase::new(state_provider);
277277

278+
// Debug: log accounts with code in the cache
279+
for (addr, cached) in db.cache.accounts.iter() {
280+
if let Some(ref account) = cached.account {
281+
let code_len = account.info.code.as_ref().map(|c| c.len()).unwrap_or(0);
282+
if code_len > 0 {
283+
tracing::debug!(
284+
target: "builder_tx",
285+
address = ?addr,
286+
code_len = code_len,
287+
"Cache contains account with code"
288+
);
289+
}
290+
}
291+
}
292+
278293
State::builder()
279294
.with_database(state)
280295
.with_cached_prestate(db.cache.clone())

0 commit comments

Comments
 (0)