Skip to content

Commit

Permalink
feat: alloy migration (bluealloy#535)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes authored Aug 16, 2023
1 parent 49a6470 commit f95b7a4
Show file tree
Hide file tree
Showing 72 changed files with 968 additions and 1,259 deletions.
516 changes: 401 additions & 115 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions bins/revme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,20 @@ version = "0.2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bytes = "1.4"
hash-db = "0.15"
hashbrown = "0.14"
hex = "0.4"
indicatif = "0.17"
plain_hasher = "0.2"
primitive-types = { version = "0.12", features = ["rlp", "serde"] }
revm = { path = "../../crates/revm", version = "3.3.0", default-features = false, features = [
"ethersdb",
"std",
"serde",
] }
rlp = { version = "0.5", default-features = false }
ruint = { version = "1.8.0", features = ["rlp", "serde"] }
alloy-rlp = { version = "0.3", default-features = false, features = ["arrayvec"] }
ruint = { version = "1.9.0", features = ["rlp", "serde"] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = { version = "1.0", features = ["preserve_order"] }
sha3 = { version = "0.10", default-features = false }
structopt = "0.3"
thiserror = "1.0"
triehash = "0.8"
Expand Down
29 changes: 9 additions & 20 deletions bins/revme/src/cli_env.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use std::str::FromStr;

use bytes::Bytes;
use revm::primitives::{Env, TransactTo, B160, U256};
use revm::primitives::{Address, Bytes, Env, TransactTo, U256};
use structopt::StructOpt;

#[derive(StructOpt, Clone, Debug)]
Expand Down Expand Up @@ -63,8 +60,8 @@ pub struct CliEnvBlock {
pub number: Option<u64>,
/// Coinbase or miner or address that created and signed the block.
/// Address where we are going to send gas spend
#[structopt(long = "env.block.coinbase", parse(try_from_str = parse_b160))]
pub coinbase: Option<B160>,
#[structopt(long = "env.block.coinbase")]
pub coinbase: Option<Address>,
#[structopt(long = "env.block.timestamp")]
pub timestamp: Option<u64>,
#[structopt(long = "env.block.difficulty")]
Expand All @@ -77,32 +74,24 @@ pub struct CliEnvBlock {
#[derive(StructOpt, Clone, Debug)]
pub struct CliEnvTx {
/// Caller or Author or tx signer
#[structopt(long = "env.tx.caller", parse(try_from_str = parse_b160))]
pub caller: Option<B160>,
#[structopt(long = "env.tx.caller")]
pub caller: Option<Address>,
#[structopt(long = "env.tx.gas_limit")]
pub tx_gas_limit: Option<u64>,
#[structopt(long = "env.tx.gas_price")]
pub gas_price: Option<u64>,
#[structopt(long = "env.tx.gas_priority_fee")]
pub gas_priority_fee: Option<u64>,
#[structopt(long = "env.tx.to", parse(try_from_str = parse_b160))]
pub transact_to: Option<B160>,
#[structopt(long = "env.tx.to")]
pub transact_to: Option<Address>,
#[structopt(long = "env.tx.value")]
pub value: Option<u64>,
#[structopt(long = "env.tx.data", parse(try_from_str = parse_hex))]
#[structopt(long = "env.tx.data")]
pub data: Option<Bytes>,
#[structopt(long = "env.tx.chain_id")]
pub chain_id: Option<u64>,
#[structopt(long = "env.tx.nonce")]
pub nonce: Option<u64>,
//#[structopt(long = "env.")]
//TODO pub access_list: Vec<(B160, Vec<U256>)>,
}

fn parse_hex(src: &str) -> Result<Bytes, hex::FromHexError> {
Ok(Bytes::from(hex::decode(src)?))
}

pub fn parse_b160(input: &str) -> Result<B160, <B160 as FromStr>::Err> {
B160::from_str(input)
//TODO pub access_list: Vec<(Address, Vec<U256>)>,
}
97 changes: 46 additions & 51 deletions bins/revme/src/statetest/merkle_trie.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,74 @@
use bytes::Bytes;
use alloy_rlp::{RlpEncodable, RlpMaxEncodedLen};
use hash_db::Hasher;
use plain_hasher::PlainHasher;
use primitive_types::{H160, H256};
use revm::{
db::PlainAccount,
primitives::{keccak256, Log, B160, B256, U256},
primitives::{keccak256, Address, Log, B256, U256},
};
use rlp::RlpStream;
use sha3::{Digest, Keccak256};
use triehash::sec_trie_root;

pub fn log_rlp_hash(logs: Vec<Log>) -> B256 {
//https://github.com/ethereum/go-ethereum/blob/356bbe343a30789e77bb38f25983c8f2f2bfbb47/cmd/evm/internal/t8ntool/execution.go#L255
let mut stream = RlpStream::new();
stream.begin_unbounded_list();
for log in logs {
stream.begin_list(3);
stream.append(&log.address.0.as_ref());
stream.begin_unbounded_list();
for topic in log.topics {
stream.append(&topic.0.as_ref());
}
stream.finalize_unbounded_list();
stream.append(&log.data);
}
stream.finalize_unbounded_list();
let out = stream.out().freeze();

pub fn log_rlp_hash(logs: &[Log]) -> B256 {
let mut out = Vec::with_capacity(alloy_rlp::list_length(logs));
alloy_rlp::encode_list(logs, &mut out);
keccak256(&out)
}

pub fn state_merkle_trie_root<'a>(
accounts: impl IntoIterator<Item = (B160, &'a PlainAccount)>,
accounts: impl IntoIterator<Item = (Address, &'a PlainAccount)>,
) -> B256 {
let vec = accounts
.into_iter()
.map(|(address, info)| {
let acc_root = trie_account_rlp(info);
(H160::from(address.0), acc_root)
})
.collect();
trie_root(accounts.into_iter().map(|(address, acc)| {
(
address,
alloy_rlp::encode_fixed_size(&TrieAccount::new(acc)),
)
}))
}

trie_root(vec)
#[derive(RlpEncodable, RlpMaxEncodedLen)]
struct TrieAccount {
nonce: u64,
balance: U256,
root_hash: B256,
code_hash: B256,
}

/// Returns the RLP for this account.
pub fn trie_account_rlp(acc: &PlainAccount) -> Bytes {
let mut stream = RlpStream::new_list(4);
stream.append(&acc.info.nonce);
stream.append(&acc.info.balance);
stream.append(&{
sec_trie_root::<KeccakHasher, _, _, _>(
acc.storage
.iter()
.filter(|(_k, &v)| v != U256::ZERO)
.map(|(&k, v)| (H256::from(k.to_be_bytes()), rlp::encode(v))),
)
});
stream.append(&acc.info.code_hash.0.as_ref());
stream.out().freeze()
impl TrieAccount {
#[inline(always)]
fn new(acc: &PlainAccount) -> Self {
Self {
nonce: acc.info.nonce,
balance: acc.info.balance,
root_hash: sec_trie_root::<KeccakHasher, _, _, _>(
acc.storage
.iter()
.filter(|(_k, &v)| v != U256::ZERO)
.map(|(k, v)| (k.to_be_bytes::<32>(), alloy_rlp::encode_fixed_size(v))),
),
code_hash: acc.info.code_hash,
}
}
}

pub fn trie_root(acc_data: Vec<(H160, Bytes)>) -> B256 {
B256(sec_trie_root::<KeccakHasher, _, _, _>(acc_data).0)
#[inline]
pub fn trie_root<I, A, B>(input: I) -> B256
where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]>,
B: AsRef<[u8]>,
{
sec_trie_root::<KeccakHasher, _, _, _>(input)
}

#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct KeccakHasher;

impl Hasher for KeccakHasher {
type Out = H256;
type Out = B256;
type StdHasher = PlainHasher;
const LENGTH: usize = 32;

#[inline]
fn hash(x: &[u8]) -> Self::Out {
let out = Keccak256::digest(x);
H256::from_slice(out.as_slice())
keccak256(x)
}
}
77 changes: 11 additions & 66 deletions bins/revme/src/statetest/models/deserializer.rs
Original file line number Diff line number Diff line change
@@ -1,83 +1,28 @@
use std::str::FromStr;

use bytes::Bytes;
use revm::primitives::{B160, U256};
use serde::{
de::{self, Error},
Deserialize,
};
use revm::primitives::Address;
use serde::{de, Deserialize};

pub fn deserialize_str_as_u64<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: de::Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;

let output = if let Some(stripped) = string.strip_prefix("0x") {
u64::from_str_radix(stripped, 16).unwrap()
if let Some(stripped) = string.strip_prefix("0x") {
u64::from_str_radix(stripped, 16)
} else {
string.parse().unwrap()
};

Ok(output)
}

pub fn deserialize_str_as_u256<'de, D>(deserializer: D) -> Result<U256, D::Error>
where
D: de::Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
let output = string.parse().unwrap();

Ok(output)
}

pub fn deserialize_vec_as_vec_bytes<'de, D>(deserializer: D) -> Result<Vec<Bytes>, D::Error>
where
D: de::Deserializer<'de>,
{
let strings: Vec<String> = Vec::<String>::deserialize(deserializer)?;

let mut out = Vec::new();
for string in strings {
out.push(
hex::decode(string.strip_prefix("0x").unwrap_or(&string))
.map_err(D::Error::custom)?
.into(),
)
string.parse()
}
Ok(out)
.map_err(serde::de::Error::custom)
}

pub fn deserialize_maybe_empty<'de, D>(deserializer: D) -> Result<Option<B160>, D::Error>
pub fn deserialize_maybe_empty<'de, D>(deserializer: D) -> Result<Option<Address>, D::Error>
where
D: de::Deserializer<'de>,
{
let string: String = String::deserialize(deserializer)?;
let string = String::deserialize(deserializer)?;
if string.is_empty() {
return Ok(None);
Ok(None)
} else {
string.parse().map_err(de::Error::custom).map(Some)
}
Ok(Some(B160::from_str(&string).map_err(D::Error::custom)?))
}

pub fn deserialize_str_as_bytes<'de, D>(deserializer: D) -> Result<Bytes, D::Error>
where
D: de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;

Ok(hex::decode(s.strip_prefix("0x").unwrap_or(&s))
.map_err(D::Error::custom)?
.into())
}

pub fn deserialize_opt_str_as_bytes<'de, D>(deserializer: D) -> Result<Option<Bytes>, D::Error>
where
D: de::Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
struct WrappedValue(#[serde(deserialize_with = "deserialize_str_as_bytes")] Bytes);

Option::<WrappedValue>::deserialize(deserializer)
.map(|opt_wrapped: Option<WrappedValue>| opt_wrapped.map(|wrapped: WrappedValue| wrapped.0))
}
Loading

0 comments on commit f95b7a4

Please sign in to comment.