diff --git a/Cargo.lock b/Cargo.lock index a51c4e0d343f..818dfe29b649 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,7 +90,7 @@ dependencies = [ [[package]] name = "alloy-consensus" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-eips", "alloy-network", @@ -122,7 +122,7 @@ dependencies = [ [[package]] name = "alloy-eips" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -133,7 +133,7 @@ dependencies = [ [[package]] name = "alloy-genesis" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "alloy-json-rpc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-primitives", "serde", @@ -166,7 +166,7 @@ dependencies = [ [[package]] name = "alloy-network" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -205,7 +205,7 @@ dependencies = [ [[package]] name = "alloy-providers" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-network", "alloy-primitives", @@ -224,7 +224,7 @@ dependencies = [ [[package]] name = "alloy-pubsub" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -262,7 +262,7 @@ dependencies = [ [[package]] name = "alloy-rpc-client" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -279,7 +279,7 @@ dependencies = [ [[package]] name = "alloy-rpc-trace-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -290,7 +290,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -303,7 +303,7 @@ dependencies = [ [[package]] name = "alloy-signer" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-network", "alloy-primitives", @@ -364,7 +364,7 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-json-rpc", "base64 0.21.7", @@ -380,7 +380,7 @@ dependencies = [ [[package]] name = "alloy-transport-http" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -393,7 +393,7 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -411,7 +411,7 @@ dependencies = [ [[package]] name = "alloy-transport-ws" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy#53ef6c2dc9867f03320131ff0f25577502259138" +source = "git+https://github.com/alloy-rs/alloy#11b80310b1dd717e5e799942534f1f8b9fb2ee46" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -513,6 +513,7 @@ dependencies = [ "alloy-chains", "alloy-consensus", "alloy-dyn-abi", + "alloy-genesis", "alloy-network", "alloy-primitives", "alloy-providers", diff --git a/crates/anvil/Cargo.toml b/crates/anvil/Cargo.toml index 21633df0c09a..f6d4f518561b 100644 --- a/crates/anvil/Cargo.toml +++ b/crates/anvil/Cargo.toml @@ -46,6 +46,7 @@ alloy-rpc-trace-types.workspace = true alloy-providers.workspace = true alloy-transport.workspace = true alloy-chains.workspace = true +alloy-genesis.workspace = true # axum related axum.workspace = true diff --git a/crates/anvil/core/src/eth/transaction/optimism.rs b/crates/anvil/core/src/eth/transaction/optimism.rs index 614ba15b81d6..86edc810a537 100644 --- a/crates/anvil/core/src/eth/transaction/optimism.rs +++ b/crates/anvil/core/src/eth/transaction/optimism.rs @@ -229,6 +229,14 @@ impl Transaction for DepositTransactionRequest { fn value(&self) -> U256 { self.value } + + fn encode_for_signing(&self, out: &mut dyn alloy_rlp::BufMut) { + self.encode_for_signing(out) + } + + fn payload_len_for_signature(&self) -> usize { + self.payload_len_for_signature() + } } impl From for DepositTransactionRequest { diff --git a/crates/anvil/src/cmd.rs b/crates/anvil/src/cmd.rs index 9ddd53434f6c..b87da35572ff 100644 --- a/crates/anvil/src/cmd.rs +++ b/crates/anvil/src/cmd.rs @@ -1,9 +1,9 @@ use crate::{ config::DEFAULT_MNEMONIC, eth::{backend::db::SerializableState, pool::transactions::TransactionOrder, EthApi}, - genesis::Genesis, AccountGenerator, Hardfork, NodeConfig, CHAIN_ID, }; +use alloy_genesis::Genesis; use alloy_primitives::{utils::Unit, U256}; use alloy_signer::coins_bip39::{English, Mnemonic}; use anvil_server::ServerConfig; @@ -110,7 +110,7 @@ pub struct NodeArgs { pub order: TransactionOrder, /// Initialize the genesis block with the given `genesis.json` file. - #[clap(long, value_name = "PATH", value_parser = Genesis::parse)] + #[clap(long, value_name = "PATH", value_parser= read_genesis_file)] pub init: Option, /// This is an alias for both --load-state and --dump-state. @@ -672,6 +672,11 @@ impl FromStr for ForkUrl { } } +/// Clap's value parser for genesis. Loads a genesis.json file. +fn read_genesis_file(path: &str) -> Result { + foundry_common::fs::read_json_file(path.as_ref()).map_err(|err| err.to_string()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/anvil/src/config.rs b/crates/anvil/src/config.rs index 3e370b576847..e7bec82bfcbf 100644 --- a/crates/anvil/src/config.rs +++ b/crates/anvil/src/config.rs @@ -11,11 +11,11 @@ use crate::{ fees::{INITIAL_BASE_FEE, INITIAL_GAS_PRICE}, pool::transactions::TransactionOrder, }, - genesis::Genesis, mem, mem::in_memory_db::MemDb, FeeManager, Hardfork, }; +use alloy_genesis::Genesis; use alloy_primitives::{hex, utils::Unit, U256}; use alloy_providers::provider::TempProvider; use alloy_rpc_types::BlockNumberOrTag; @@ -412,7 +412,7 @@ impl NodeConfig { /// Returns the base fee to use pub fn get_base_fee(&self) -> U256 { self.base_fee - .or_else(|| self.genesis.as_ref().and_then(|g| g.base_fee_per_gas)) + .or_else(|| self.genesis.as_ref().and_then(|g| g.base_fee_per_gas.map(U256::from))) .unwrap_or_else(|| U256::from(INITIAL_BASE_FEE)) } @@ -457,7 +457,7 @@ impl NodeConfig { /// Returns the chain ID to use pub fn get_chain_id(&self) -> u64 { self.chain_id - .or_else(|| self.genesis.as_ref().and_then(|g| g.chain_id())) + .or_else(|| self.genesis.as_ref().map(|g| g.config.chain_id)) .unwrap_or(CHAIN_ID) } @@ -532,7 +532,7 @@ impl NodeConfig { /// Returns the genesis timestamp to use pub fn get_genesis_timestamp(&self) -> u64 { self.genesis_timestamp - .or_else(|| self.genesis.as_ref().and_then(|g| g.timestamp)) + .or_else(|| self.genesis.as_ref().map(|g| g.timestamp)) .unwrap_or_else(|| duration_since_unix_epoch().as_secs()) } @@ -834,7 +834,15 @@ impl NodeConfig { // if provided use all settings of `genesis.json` if let Some(ref genesis) = self.genesis { - genesis.apply(&mut env); + env.cfg.chain_id = genesis.config.chain_id; + env.block.timestamp = U256::from(genesis.timestamp); + if let Some(base_fee) = genesis.base_fee_per_gas { + env.block.basefee = U256::from(base_fee); + } + if let Some(number) = genesis.number { + env.block.number = U256::from(number); + } + env.block.coinbase = genesis.coinbase; } let genesis = GenesisConfig { diff --git a/crates/anvil/src/eth/backend/genesis.rs b/crates/anvil/src/eth/backend/genesis.rs index 523208ba83b4..c6e75bb4440f 100644 --- a/crates/anvil/src/eth/backend/genesis.rs +++ b/crates/anvil/src/eth/backend/genesis.rs @@ -1,9 +1,7 @@ //! Genesis settings -use crate::{ - eth::backend::db::{Db, MaybeHashDatabase}, - genesis::Genesis, -}; +use crate::eth::backend::db::{Db, MaybeHashDatabase}; +use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{Address, B256, U256}; use foundry_evm::{ backend::{DatabaseError, DatabaseResult, StateSnapshot}, @@ -57,12 +55,12 @@ impl GenesisConfig { mut db: RwLockWriteGuard<'_, Box>, ) -> DatabaseResult<()> { if let Some(ref genesis) = self.genesis_init { - for (addr, mut acc) in genesis.alloc.accounts.clone() { + for (addr, mut acc) in genesis.alloc.clone() { let storage = std::mem::take(&mut acc.storage); // insert all accounts - db.insert_account(addr, acc.into()); + db.insert_account(addr, self.genesis_to_account_info(&acc)); // insert all storage values - for (k, v) in storage.iter() { + for (k, v) in storage.unwrap_or_default().iter() { db.set_storage_at(addr, U256::from_be_bytes(k.0), U256::from_be_bytes(v.0))?; } } @@ -70,6 +68,18 @@ impl GenesisConfig { Ok(()) } + /// Converts a [`GenesisAccount`] to an [`AccountInfo`] + fn genesis_to_account_info(&self, acc: &GenesisAccount) -> AccountInfo { + let GenesisAccount { code, balance, nonce, .. } = acc.clone(); + let code = code.map(|code| Bytecode::new_raw(code.to_vec().into())); + AccountInfo { + balance, + nonce: nonce.unwrap_or_default(), + code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY), + code, + } + } + /// Returns a database wrapper that points to the genesis and is aware of all provided /// [AccountInfo] pub(crate) fn state_db_at_genesis<'a>( @@ -113,11 +123,12 @@ impl<'a> DatabaseRef for AtGenesisStateDb<'a> { } fn storage_ref(&self, address: Address, index: U256) -> DatabaseResult { - if let Some(acc) = - self.genesis.as_ref().and_then(|genesis| genesis.alloc.accounts.get(&(address))) - { - let value = acc.storage.get(&B256::from(index)).copied().unwrap_or_default(); - return Ok(U256::from_be_bytes(value.0)) + if let Some(acc) = self.genesis.as_ref().and_then(|genesis| genesis.alloc.get(&(address))) { + if let Some(storage) = acc.storage.as_ref() { + return Ok(U256::from_be_bytes( + storage.get(&B256::from(index)).copied().unwrap_or_default().0, + )) + } } self.db.storage_ref(address, index) } diff --git a/crates/anvil/src/genesis.rs b/crates/anvil/src/genesis.rs deleted file mode 100644 index 3525838a7756..000000000000 --- a/crates/anvil/src/genesis.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! Bindings for geth's `genesis.json` format -use crate::revm::primitives::AccountInfo; -use alloy_primitives::{Address, Bytes, B256, U256}; -use alloy_signer::LocalWallet; -use foundry_common::errors::FsPathError; -use foundry_evm::revm::primitives::{Bytecode, Env, KECCAK_EMPTY, U256 as rU256}; -use serde::{Deserialize, Serialize}; -use std::{ - collections::{BTreeMap, HashMap}, - path::Path, -}; - -/// Genesis specifies the header fields, state of a genesis block. It also defines hard fork -/// switch-over blocks through the chain configuration See also: -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Genesis { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub config: Option, - #[serde( - default, - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64_opt", - skip_serializing_if = "Option::is_none" - )] - pub nonce: Option, - #[serde( - default, - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64_opt", - skip_serializing_if = "Option::is_none" - )] - pub timestamp: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub extra_data: Option, - #[serde( - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64" - )] - pub gas_limit: u64, - #[serde( - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64" - )] - pub difficulty: u64, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub mix_hash: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub coinbase: Option
, - #[serde(default)] - pub alloc: Alloc, - #[serde( - default, - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64_opt", - skip_serializing_if = "Option::is_none" - )] - pub number: Option, - #[serde( - default, - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64_opt", - skip_serializing_if = "Option::is_none" - )] - pub gas_used: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub parent_hash: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub base_fee_per_gas: Option, -} - -impl Genesis { - /// Loads the `Genesis` object from the given json file path - pub fn load(path: impl AsRef) -> Result { - foundry_common::fs::read_json_file(path.as_ref()) - } - - /// The clap `value_parser` function - pub(crate) fn parse(path: &str) -> Result { - Self::load(path).map_err(|err| err.to_string()) - } - - pub fn chain_id(&self) -> Option { - self.config.as_ref().and_then(|c| c.chain_id) - } - - /// Applies all settings to the given `env` - pub fn apply(&self, env: &mut Env) { - if let Some(chain_id) = self.chain_id() { - env.cfg.chain_id = chain_id; - } - if let Some(timestamp) = self.timestamp { - env.block.timestamp = U256::from(timestamp); - } - if let Some(base_fee) = self.base_fee_per_gas { - env.block.basefee = base_fee; - } - if let Some(number) = self.number { - env.block.number = rU256::from(number); - } - if let Some(coinbase) = self.coinbase { - env.block.coinbase = coinbase; - } - env.block.difficulty = U256::from(self.difficulty); - env.block.gas_limit = U256::from(self.gas_limit); - } - - /// Returns all private keys from the genesis accounts, if they exist - pub fn private_keys(&self) -> Vec { - self.alloc.accounts.values().filter_map(|acc| acc.private_key.clone()).collect() - } -} - -#[derive(Clone, Debug, Default, Serialize, Deserialize)] -#[serde(transparent)] -pub struct Alloc { - pub accounts: BTreeMap, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct GenesisAccount { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub code: Option, - #[serde(default, skip_serializing_if = "HashMap::is_empty")] - pub storage: HashMap, - pub balance: U256, - #[serde( - default, - deserialize_with = "anvil_core::eth::serde_helpers::numeric::deserialize_stringified_u64_opt", - skip_serializing_if = "Option::is_none" - )] - pub nonce: Option, - #[serde( - rename = "secretKey", - default, - skip_serializing_if = "Option::is_none", - with = "secret_key" - )] - pub private_key: Option, -} - -impl From for AccountInfo { - fn from(acc: GenesisAccount) -> Self { - let GenesisAccount { code, balance, nonce, .. } = acc; - let code = code.map(|code| Bytecode::new_raw(code.to_vec().into())); - AccountInfo { - balance, - nonce: nonce.unwrap_or_default(), - code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY), - code, - } - } -} - -/// ChainConfig is the core config which determines the blockchain settings. -/// -/// ChainConfig is stored in the database on a per block basis. This means -/// that any network, identified by its genesis block, can have its own -/// set of configuration options. -/// <(https://github.com/ethereum/go-ethereum/blob/0ce494b60cd00d70f1f9f2dd0b9bfbd76204168a/params/config.go#L342-L387> -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Config { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub chain_id: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub homestead_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub dao_fork_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub dao_fork_support: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub eip150_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub eip150_hash: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub eip155_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub eip158_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub byzantium_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub constantinople_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub petersburg_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub istanbul_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub muir_glacier_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub berlin_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub london_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub arrow_glacier_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub gray_glacier_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub merge_netsplit_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub shanghai_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub cancun_block: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub terminal_total_difficulty: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub terminal_total_difficulty_passed: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub ethash: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub clique: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct EthashConfig {} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct CliqueConfig { - pub period: u64, - pub epoch: u64, -} - -/// serde support for `secretKey` in genesis - -pub mod secret_key { - use alloy_primitives::Bytes; - use alloy_signer::LocalWallet; - use k256::{ecdsa::SigningKey, SecretKey}; - use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - - pub fn serialize(value: &Option, serializer: S) -> Result - where - S: Serializer, - { - if let Some(wallet) = value { - let signer: SigningKey = wallet.signer().clone(); - let signer_bytes = signer.to_bytes(); - let signer_bytes2: [u8; 32] = *signer_bytes.as_ref(); - Bytes::from(signer_bytes2).serialize(serializer) - } else { - serializer.serialize_none() - } - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - if let Some(s) = Option::::deserialize(deserializer)? { - if s.is_empty() { - return Ok(None) - } - SecretKey::from_bytes(s.as_ref().into()) - .map_err(de::Error::custom) - .map(Into::into) - .map(Some) - } else { - Ok(None) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn can_parse_genesis_json() { - let s = r#"{ - "config": { - "chainId": 19763, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "ethash": {} - }, - "nonce": "0xdeadbeefdeadbeef", - "timestamp": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x80000000", - "difficulty": "0x20000", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "71562b71999873db5b286df957af199ec94617f7": { - "balance": "0xffffffffffffffffffffffffff", - "secretkey": "0x305b526d493844b63466be6d48a424ab83f5216011eef860acc6db4c1821adc9" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} -"#; - - let gen: Genesis = serde_json::from_str(s).unwrap(); - assert_eq!(gen.nonce, Some(16045690984833335023)); - assert_eq!(gen.gas_limit, 2147483648); - assert_eq!(gen.difficulty, 131072); - assert_eq!(gen.alloc.accounts.len(), 1); - let config = gen.config.unwrap(); - assert_eq!(config.chain_id, Some(19763)); - } -} diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index 322b14aad60f..d2503410f0e6 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -52,8 +52,6 @@ pub use hardfork::Hardfork; pub mod eth; /// support for polling filters pub mod filter; -/// support for handling `genesis.json` files -pub mod genesis; /// commandline output pub mod logging; /// types for subscriptions @@ -128,11 +126,14 @@ pub async fn spawn(mut config: NodeConfig) -> (EthApi, NodeHandle) { let dev_signer: Box = Box::new(DevSigner::new(signer_accounts)); let mut signers = vec![dev_signer]; if let Some(genesis) = genesis { - // include all signers from genesis.json if any - let genesis_signers = genesis.private_keys(); + let genesis_signers = genesis + .alloc + .values() + .filter_map(|acc| acc.private_key) + .flat_map(|k| LocalWallet::from_bytes(&k)) + .collect::>(); if !genesis_signers.is_empty() { - let genesis_signers: Box = Box::new(DevSigner::new(genesis_signers)); - signers.push(genesis_signers); + signers.push(Box::new(DevSigner::new(genesis_signers))); } } diff --git a/crates/anvil/tests/it/genesis.rs b/crates/anvil/tests/it/genesis.rs index 2a0c2e8eed24..9b822aff7207 100644 --- a/crates/anvil/tests/it/genesis.rs +++ b/crates/anvil/tests/it/genesis.rs @@ -2,9 +2,10 @@ use std::str::FromStr; +use alloy_genesis::Genesis; use alloy_primitives::{Address, U256, U64}; use alloy_providers::provider::TempProvider; -use anvil::{genesis::Genesis, spawn, NodeConfig}; +use anvil::{spawn, NodeConfig}; #[tokio::test(flavor = "multi_thread")] async fn can_apply_genesis() { diff --git a/crates/cheatcodes/src/evm.rs b/crates/cheatcodes/src/evm.rs index 5bd7750cfe29..5185ebbc541b 100644 --- a/crates/cheatcodes/src/evm.rs +++ b/crates/cheatcodes/src/evm.rs @@ -126,6 +126,7 @@ impl Cheatcode for dumpStateCall { .map(|(k, v)| (B256::from(*k), B256::from(v.present_value()))) .collect(), ), + private_key: None, }, ) })