Skip to content

Commit

Permalink
(#3) Alloy Migration: migrate fork-adjacent files to alloy primitives (
Browse files Browse the repository at this point in the history
  • Loading branch information
Evalir authored Sep 15, 2023
1 parent 9cd47f3 commit d48d589
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 77 deletions.
4 changes: 2 additions & 2 deletions crates/evm/src/executor/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ impl Backend {
transaction: B256,
) -> eyre::Result<(U64, Block<Transaction>)> {
let fork = self.inner.get_fork_by_id(id)?;
let tx = fork.db.db.get_transaction(b256_to_h256(transaction))?;
let tx = fork.db.db.get_transaction(transaction)?;

// get the block number we need to fork
if let Some(tx_block) = tx.block_number {
Expand Down Expand Up @@ -1171,7 +1171,7 @@ impl DatabaseExt for Backend {
};

let fork = self.inner.get_fork_by_id_mut(id)?;
let tx = fork.db.db.get_transaction(b256_to_h256(transaction))?;
let tx = fork.db.db.get_transaction(transaction)?;

commit_transaction(tx, env, journaled_state, fork, &fork_id, cheatcodes_inspector)?;

Expand Down
128 changes: 62 additions & 66 deletions crates/evm/src/executor/fork/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use crate::{
backend::error::{DatabaseError, DatabaseResult},
fork::{cache::FlushJsonBlockCacheDB, BlockchainDb},
},
utils::{b160_to_h160, b256_to_h256, h160_to_b160, h256_to_b256, ru256_to_u256, u256_to_ru256},
utils::{b160_to_h160, b256_to_h256, h256_to_b256, u256_to_ru256},
};
use ethers::{
core::abi::ethereum_types::BigEndianHash,
providers::Middleware,
types::{Address, Block, BlockId, Bytes, Transaction, H256, U256},
types::{Block, BlockId, NameOrAddress, Transaction},
utils::keccak256,
};
use foundry_common::NON_ARCHIVE_NODE_WARNING;
Expand All @@ -21,7 +21,7 @@ use futures::{
};
use revm::{
db::DatabaseRef,
primitives::{AccountInfo, Address as aB160, Bytecode, B256, KECCAK_EMPTY, U256 as rU256},
primitives::{AccountInfo, Address, Bytecode, Bytes, B256, KECCAK_EMPTY, U256},
};
use std::{
collections::{hash_map::Entry, HashMap, VecDeque},
Expand All @@ -37,20 +37,20 @@ use std::{
type AccountFuture<Err> =
Pin<Box<dyn Future<Output = (Result<(U256, U256, Bytes), Err>, Address)> + Send>>;
type StorageFuture<Err> = Pin<Box<dyn Future<Output = (Result<U256, Err>, Address, U256)> + Send>>;
type BlockHashFuture<Err> = Pin<Box<dyn Future<Output = (Result<H256, Err>, u64)> + Send>>;
type BlockHashFuture<Err> = Pin<Box<dyn Future<Output = (Result<B256, Err>, u64)> + Send>>;
type FullBlockFuture<Err> = Pin<
Box<
dyn Future<Output = (FullBlockSender, Result<Option<Block<Transaction>>, Err>, BlockId)>
+ Send,
>,
>;
type TransactionFuture<Err> = Pin<
Box<dyn Future<Output = (TransactionSender, Result<Option<Transaction>, Err>, H256)> + Send>,
Box<dyn Future<Output = (TransactionSender, Result<Option<Transaction>, Err>, B256)> + Send>,
>;

type AccountInfoSender = OneshotSender<DatabaseResult<AccountInfo>>;
type StorageSender = OneshotSender<DatabaseResult<U256>>;
type BlockHashSender = OneshotSender<DatabaseResult<H256>>;
type BlockHashSender = OneshotSender<DatabaseResult<B256>>;
type FullBlockSender = OneshotSender<DatabaseResult<Block<Transaction>>>;
type TransactionSender = OneshotSender<DatabaseResult<Transaction>>;

Expand All @@ -75,7 +75,7 @@ enum BackendRequest {
/// Fetch an entire block with transactions
FullBlock(BlockId, FullBlockSender),
/// Fetch a transaction
Transaction(H256, TransactionSender),
Transaction(B256, TransactionSender),
/// Sets the pinned block to fetch data from
SetPinnedBlock(BlockId),
}
Expand Down Expand Up @@ -139,17 +139,17 @@ where
match req {
BackendRequest::Basic(addr, sender) => {
trace!(target: "backendhandler", "received request basic address={:?}", addr);
let acc = self.db.accounts().read().get(&h160_to_b160(addr)).cloned();
let acc = self.db.accounts().read().get(&addr).cloned();
if let Some(basic) = acc {
let _ = sender.send(Ok(basic));
} else {
self.request_account(addr, sender);
}
}
BackendRequest::BlockHash(number, sender) => {
let hash = self.db.block_hashes().read().get(&rU256::from(number)).cloned();
let hash = self.db.block_hashes().read().get(&U256::from(number)).cloned();
if let Some(hash) = hash {
let _ = sender.send(Ok(b256_to_h256(hash)));
let _ = sender.send(Ok(hash));
} else {
self.request_hash(number, sender);
}
Expand All @@ -162,14 +162,10 @@ where
}
BackendRequest::Storage(addr, idx, sender) => {
// account is already stored in the cache
let value = self
.db
.storage()
.read()
.get(&h160_to_b160(addr))
.and_then(|acc| acc.get(&u256_to_ru256(idx)).copied());
let value =
self.db.storage().read().get(&addr).and_then(|acc| acc.get(&idx).copied());
if let Some(value) = value {
let _ = sender.send(Ok(ru256_to_u256(value)));
let _ = sender.send(Ok(value));
} else {
// account present but not storage -> fetch storage
self.request_account_storage(addr, idx, sender);
Expand All @@ -194,9 +190,15 @@ where
let block_id = self.block_id;
let fut = Box::pin(async move {
// serialize & deserialize back to U256
let idx_req = H256::from_uint(&idx);
let storage = provider.get_storage_at(address, idx_req, block_id).await;
let storage = storage.map(|storage| storage.into_uint());
let idx_req = B256::from(idx);
let storage = provider
.get_storage_at(
NameOrAddress::Address(b160_to_h160(address)),
b256_to_h256(idx_req),
block_id,
)
.await;
let storage = storage.map(|storage| storage.into_uint()).map(u256_to_ru256);
(storage, address, idx)
});
self.pending_requests.push(ProviderRequest::Storage(fut));
Expand All @@ -210,10 +212,14 @@ where
let provider = self.provider.clone();
let block_id = self.block_id;
let fut = Box::pin(async move {
let balance = provider.get_balance(address, block_id);
let nonce = provider.get_transaction_count(address, block_id);
let code = provider.get_code(address, block_id);
let resp = tokio::try_join!(balance, nonce, code);
let balance =
provider.get_balance(NameOrAddress::Address(b160_to_h160(address)), block_id);
let nonce = provider
.get_transaction_count(NameOrAddress::Address(b160_to_h160(address)), block_id);
let code = provider.get_code(NameOrAddress::Address(b160_to_h160(address)), block_id);
let resp = tokio::try_join!(balance, nonce, code).map(|(balance, nonce, code)| {
(u256_to_ru256(balance), u256_to_ru256(nonce), Bytes::from(code.0))
});
(resp, address)
});
ProviderRequest::Account(fut)
Expand Down Expand Up @@ -244,10 +250,10 @@ where
}

/// process a request for a transactions
fn request_transaction(&mut self, tx: H256, sender: TransactionSender) {
fn request_transaction(&mut self, tx: B256, sender: TransactionSender) {
let provider = self.provider.clone();
let fut = Box::pin(async move {
let block = provider.get_transaction(tx).await;
let block = provider.get_transaction(b256_to_h256(tx)).await;
(sender, block, tx)
});

Expand Down Expand Up @@ -282,7 +288,7 @@ where
Err(err)
}
};
(block_hash, number)
(block_hash.map(h256_to_b256), number)
});
self.pending_requests.push(ProviderRequest::BlockHash(fut));
}
Expand Down Expand Up @@ -332,7 +338,7 @@ where
if let Some(listeners) = pin.account_requests.remove(&addr) {
listeners.into_iter().for_each(|l| {
let _ = l.send(Err(DatabaseError::GetAccount(
h160_to_b160(addr),
addr,
Arc::clone(&err),
)));
})
Expand All @@ -350,14 +356,14 @@ where

// update the cache
let acc = AccountInfo {
nonce: nonce.as_u64(),
balance: u256_to_ru256(balance),
nonce: nonce.to(),
balance,
code: code.map(|bytes| {
Bytecode::new_raw(alloy_primitives::Bytes(bytes)).to_checked()
}),
code_hash,
};
pin.db.accounts().write().insert(h160_to_b160(addr), acc.clone());
pin.db.accounts().write().insert(addr, acc.clone());

// notify all listeners
if let Some(listeners) = pin.account_requests.remove(&addr) {
Expand All @@ -380,8 +386,8 @@ where
{
listeners.into_iter().for_each(|l| {
let _ = l.send(Err(DatabaseError::GetStorage(
h160_to_b160(addr),
u256_to_ru256(idx),
addr,
idx,
Arc::clone(&err),
)));
})
Expand All @@ -391,12 +397,7 @@ where
};

// update the cache
pin.db
.storage()
.write()
.entry(h160_to_b160(addr))
.or_default()
.insert(u256_to_ru256(idx), u256_to_ru256(value));
pin.db.storage().write().entry(addr).or_default().insert(idx, value);

// notify all listeners
if let Some(listeners) = pin.storage_requests.remove(&(addr, idx)) {
Expand Down Expand Up @@ -427,10 +428,7 @@ where
};

// update the cache
pin.db
.block_hashes()
.write()
.insert(rU256::from(number), h256_to_b256(value));
pin.db.block_hashes().write().insert(U256::from(number), value);

// notify all listeners
if let Some(listeners) = pin.block_requests.remove(&number) {
Expand Down Expand Up @@ -459,12 +457,10 @@ where
if let Poll::Ready((sender, tx, tx_hash)) = fut.poll_unpin(cx) {
let msg = match tx {
Ok(Some(tx)) => Ok(tx),
Ok(None) => {
Err(DatabaseError::TransactionNotFound(h256_to_b256(tx_hash)))
}
Ok(None) => Err(DatabaseError::TransactionNotFound(tx_hash)),
Err(err) => {
let err = Arc::new(eyre::Error::new(err));
Err(DatabaseError::GetTransaction(h256_to_b256(tx_hash), err))
Err(DatabaseError::GetTransaction(tx_hash, err))
}
};
let _ = sender.send(msg);
Expand Down Expand Up @@ -605,7 +601,7 @@ impl SharedBackend {
}

/// Returns the transaction for the hash
pub fn get_transaction(&self, tx: H256) -> DatabaseResult<Transaction> {
pub fn get_transaction(&self, tx: B256) -> DatabaseResult<Transaction> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::Transaction(tx, sender);
Expand All @@ -632,7 +628,7 @@ impl SharedBackend {
})
}

fn do_get_block_hash(&self, number: u64) -> DatabaseResult<H256> {
fn do_get_block_hash(&self, number: u64) -> DatabaseResult<B256> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::BlockHash(number, sender);
Expand All @@ -650,9 +646,9 @@ impl SharedBackend {
impl DatabaseRef for SharedBackend {
type Error = DatabaseError;

fn basic(&self, address: aB160) -> Result<Option<AccountInfo>, Self::Error> {
fn basic(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
trace!( target: "sharedbackend", "request basic {:?}", address);
self.do_get_basic(b160_to_h160(address)).map_err(|err| {
self.do_get_basic(address).map_err(|err| {
error!(target: "sharedbackend", ?err, ?address, "Failed to send/recv `basic`");
if err.is_possibly_non_archive_node_error() {
error!(target: "sharedbackend", "{NON_ARCHIVE_NODE_WARNING}");
Expand All @@ -665,26 +661,26 @@ impl DatabaseRef for SharedBackend {
Err(DatabaseError::MissingCode(hash))
}

fn storage(&self, address: aB160, index: rU256) -> Result<rU256, Self::Error> {
fn storage(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
trace!( target: "sharedbackend", "request storage {:?} at {:?}", address, index);
match self.do_get_storage(b160_to_h160(address), ru256_to_u256(index)).map_err(|err| {
match self.do_get_storage(address, index).map_err(|err| {
error!( target: "sharedbackend", ?err, ?address, ?index, "Failed to send/recv `storage`");
if err.is_possibly_non_archive_node_error() {
error!(target: "sharedbackend", "{NON_ARCHIVE_NODE_WARNING}");
}
err
}) {
Ok(val) => Ok(u256_to_ru256(val)),
Ok(val) => Ok(val),
Err(err) => Err(err),
}
}

fn block_hash(&self, number: rU256) -> Result<B256, Self::Error> {
if number > rU256::from(u64::MAX) {
fn block_hash(&self, number: U256) -> Result<B256, Self::Error> {
if number > U256::from(u64::MAX) {
return Ok(KECCAK_EMPTY)
}
let number: U256 = ru256_to_u256(number);
let number = number.as_u64();
let number: U256 = number;
let number = number.to();
trace!( target: "sharedbackend", "request block hash for number {:?}", number);
match self.do_get_block_hash(number).map_err(|err| {
error!(target: "sharedbackend",?err, ?number, "Failed to send/recv `block_hash`");
Expand All @@ -693,7 +689,7 @@ impl DatabaseRef for SharedBackend {
}
err
}) {
Ok(val) => Ok(h256_to_b256(val)),
Ok(val) => Ok(val),
Err(err) => Err(err),
}
}
Expand Down Expand Up @@ -726,9 +722,9 @@ mod tests {
let backend = SharedBackend::spawn_backend(Arc::new(provider), db.clone(), None).await;

// some rng contract from etherscan
let address: aB160 = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap();
let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap();

let idx = rU256::from(0u64);
let idx = U256::from(0u64);
let value = backend.storage(address, idx).unwrap();
let account = backend.basic(address).unwrap().unwrap();

Expand All @@ -739,15 +735,15 @@ mod tests {
assert_eq!(slots.len(), 1);
assert_eq!(slots.get(&idx).copied().unwrap(), value);

let num = rU256::from(10u64);
let num = U256::from(10u64);
let hash = backend.block_hash(num).unwrap();
let mem_hash = *db.block_hashes().read().get(&num).unwrap();
assert_eq!(hash, mem_hash);

let max_slots = 5;
let handle = std::thread::spawn(move || {
for i in 1..max_slots {
let idx = rU256::from(i);
let idx = U256::from(i);
let _ = backend.storage(address, idx);
}
});
Expand Down Expand Up @@ -785,16 +781,16 @@ mod tests {
let backend = Backend::spawn(Some(fork)).await;

// some rng contract from etherscan
let address: aB160 = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap();
let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap();

let idx = rU256::from(0u64);
let idx = U256::from(0u64);
let _value = backend.storage(address, idx);
let _account = backend.basic(address);

// fill some slots
let num_slots = 10u64;
for idx in 1..num_slots {
let _ = backend.storage(address, rU256::from(idx));
let _ = backend.storage(address, U256::from(idx));
}
drop(backend);

Expand Down
7 changes: 4 additions & 3 deletions crates/evm/src/executor/fork/init.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::utils::{
apply_chain_and_block_specific_env_changes, h160_to_b160, h256_to_b256, u256_to_ru256,
};
use alloy_primitives::{Address, U256};
use ethers::{
providers::Middleware,
types::{Address, Block, TxHash, U256},
types::{Block, TxHash},
};
use eyre::WrapErr;
use foundry_common::NON_ARCHIVE_NODE_WARNING;
Expand Down Expand Up @@ -79,8 +80,8 @@ where
gas_limit: u256_to_ru256(block.gas_limit),
},
tx: TxEnv {
caller: h160_to_b160(origin),
gas_price: u256_to_ru256(gas_price.map(U256::from).unwrap_or(fork_gas_price)),
caller: origin,
gas_price: gas_price.map(U256::from).unwrap_or(u256_to_ru256(fork_gas_price)),
chain_id: Some(override_chain_id.unwrap_or(rpc_chain_id.as_u64())),
gas_limit: block.gas_limit.as_u64(),
..Default::default()
Expand Down
Loading

0 comments on commit d48d589

Please sign in to comment.