Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#3) Alloy Migration: migrate fork-adjacent files to alloy primitives #5771

Merged
merged 8 commits into from
Sep 15, 2023
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>,
>;
Evalir marked this conversation as resolved.
Show resolved Hide resolved

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