Skip to content

Commit 58d1055

Browse files
committed
Merge branch 'master' into dani/inline-config-generic
2 parents de5a0c9 + 6bcfb82 commit 58d1055

File tree

15 files changed

+507
-31
lines changed

15 files changed

+507
-31
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ resolver = "2"
3232
version = "1.3.5"
3333
edition = "2024"
3434
# Remember to update clippy.toml as well
35-
rust-version = "1.88"
35+
rust-version = "1.89"
3636
authors = ["Foundry Contributors"]
3737
license = "MIT OR Apache-2.0"
3838
homepage = "https://getfoundry.sh"

clippy.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
msrv = "1.88"
1+
msrv = "1.89"
22

33
# `bytes::Bytes` is included by default and `alloy_primitives::Bytes` is a wrapper around it,
44
# so it is safe to ignore it as well.

crates/anvil/core/src/eth/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ pub enum EthRequest {
264264
#[serde(rename = "eth_syncing", with = "empty_params")]
265265
EthSyncing(()),
266266

267+
#[serde(rename = "eth_config", with = "empty_params")]
268+
EthConfig(()),
269+
267270
/// geth's `debug_getRawTransaction` endpoint
268271
#[serde(rename = "debug_getRawTransaction", with = "sequence")]
269272
DebugGetRawTransaction(TxHash),

crates/anvil/src/eth/api.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ use alloy_consensus::{
3434
transaction::{Recovered, eip4844::TxEip4844Variant},
3535
};
3636
use alloy_dyn_abi::TypedData;
37-
use alloy_eips::eip2718::Encodable2718;
37+
use alloy_eips::{
38+
eip2718::Encodable2718,
39+
eip7910::{EthConfig, EthForkConfig},
40+
};
3841
use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
3942
use alloy_network::{
4043
AnyRpcBlock, AnyRpcTransaction, BlockResponse, Ethereum, NetworkWallet, TransactionBuilder,
@@ -313,6 +316,7 @@ impl EthApi {
313316
EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
314317
EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
315318
EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
319+
EthRequest::EthConfig(_) => self.config().to_rpc_result(),
316320
EthRequest::EthSubmitWork(nonce, pow, digest) => {
317321
self.submit_work(nonce, pow, digest).to_rpc_result()
318322
}
@@ -762,12 +766,31 @@ impl EthApi {
762766
}
763767

764768
/// Returns the account information including balance, nonce, code and storage
769+
///
770+
/// Note: This isn't support by all providers
765771
pub async fn get_account_info(
766772
&self,
767773
address: Address,
768774
block_number: Option<BlockId>,
769775
) -> Result<alloy_rpc_types::eth::AccountInfo> {
770776
node_info!("eth_getAccountInfo");
777+
778+
if let Some(fork) = self.get_fork() {
779+
// check if the number predates the fork, if in fork mode
780+
if let BlockRequest::Number(number) = self.block_request(block_number).await?
781+
&& fork.predates_fork(number)
782+
{
783+
// if this predates the fork we need to fetch balance, nonce, code individually
784+
// because the provider might not support this endpoint
785+
let balance = self.balance(address, Some(number.into()));
786+
let code = self.get_code(address, Some(number.into()));
787+
let nonce = self.get_transaction_count(address, Some(number.into()));
788+
let (balance, code, nonce) = try_join!(balance, code, nonce)?;
789+
790+
return Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code });
791+
}
792+
}
793+
771794
let account = self.get_account(address, block_number);
772795
let code = self.get_code(address, block_number);
773796
let (account, code) = try_join!(account, code)?;
@@ -1472,6 +1495,32 @@ impl EthApi {
14721495
Ok(false)
14731496
}
14741497

1498+
/// Returns the current configuration of the chain.
1499+
/// This is useful for finding out what precompiles and system contracts are available.
1500+
///
1501+
/// Note: the activation timestamp is always 0 as the configuration is set at genesis.
1502+
/// Note: the `fork_id` is always `0x00000000` as this node does not participate in any forking
1503+
/// on the network.
1504+
/// Note: the `next` and `last` fields are always `null` as this node does not participate in
1505+
/// any forking on the network.
1506+
///
1507+
/// Handler for ETH RPC call: `eth_config`
1508+
pub fn config(&self) -> Result<EthConfig> {
1509+
node_info!("eth_config");
1510+
Ok(EthConfig {
1511+
current: EthForkConfig {
1512+
activation_time: 0,
1513+
blob_schedule: self.backend.blob_params(),
1514+
chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1515+
fork_id: Bytes::from_static(&[0; 4]),
1516+
precompiles: self.backend.precompiles(),
1517+
system_contracts: self.backend.system_contracts(),
1518+
},
1519+
next: None,
1520+
last: None,
1521+
})
1522+
}
1523+
14751524
/// Used for submitting a proof-of-work solution.
14761525
///
14771526
/// Handler for ETH RPC call: `eth_submitWork`

crates/anvil/src/eth/backend/mem/mod.rs

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
pool::transactions::PoolTransaction,
2828
sign::build_typed_transaction,
2929
},
30-
evm::celo_precompile,
30+
evm::celo_precompile::{self, CELO_TRANSFER_ADDRESS},
3131
inject_precompiles,
3232
mem::{
3333
inspector::AnvilInspector,
@@ -41,7 +41,10 @@ use alloy_consensus::{
4141
proofs::{calculate_receipt_root, calculate_transaction_root},
4242
transaction::Recovered,
4343
};
44-
use alloy_eips::{eip1559::BaseFeeParams, eip4844::kzg_to_versioned_hash, eip7840::BlobParams};
44+
use alloy_eips::{
45+
eip1559::BaseFeeParams, eip4844::kzg_to_versioned_hash, eip7840::BlobParams,
46+
eip7910::SystemContract,
47+
};
4548
use alloy_evm::{
4649
Database, Evm,
4750
eth::EthEvmContext,
@@ -115,7 +118,11 @@ use revm::{
115118
},
116119
database::{CacheDB, WrapDatabaseRef},
117120
interpreter::InstructionResult,
118-
precompile::secp256r1::{P256VERIFY, P256VERIFY_BASE_GAS_FEE},
121+
precompile::{
122+
PrecompileId, PrecompileSpecId, Precompiles,
123+
secp256r1::{P256VERIFY, P256VERIFY_ADDRESS, P256VERIFY_BASE_GAS_FEE},
124+
u64_to_address,
125+
},
119126
primitives::{KECCAK_EMPTY, hardfork::SpecId},
120127
state::AccountInfo,
121128
};
@@ -843,6 +850,56 @@ impl Backend {
843850
self.env.read().is_celo
844851
}
845852

853+
/// Returns the precompiles for the current spec.
854+
pub fn precompiles(&self) -> BTreeMap<String, Address> {
855+
let spec_id = self.env.read().evm_env.cfg_env.spec;
856+
let precompiles = Precompiles::new(PrecompileSpecId::from_spec_id(spec_id));
857+
858+
let mut precompiles_map = BTreeMap::<String, Address>::default();
859+
for (address, precompile) in precompiles.inner() {
860+
precompiles_map.insert(precompile.id().name().to_string(), *address);
861+
}
862+
863+
if self.odyssey {
864+
precompiles_map.insert(
865+
PrecompileId::P256Verify.name().to_string(),
866+
u64_to_address(P256VERIFY_ADDRESS),
867+
);
868+
}
869+
870+
if self.is_celo() {
871+
precompiles_map.insert(
872+
celo_precompile::PRECOMPILE_ID_CELO_TRANSFER.clone().name().to_string(),
873+
CELO_TRANSFER_ADDRESS,
874+
);
875+
}
876+
877+
if let Some(factory) = &self.precompile_factory {
878+
for (precompile, _) in &factory.precompiles() {
879+
precompiles_map.insert(precompile.id().name().to_string(), *precompile.address());
880+
}
881+
}
882+
883+
precompiles_map
884+
}
885+
886+
/// Returns the system contracts for the current spec.
887+
pub fn system_contracts(&self) -> BTreeMap<SystemContract, Address> {
888+
let mut system_contracts = BTreeMap::<SystemContract, Address>::default();
889+
890+
let spec_id = self.env.read().evm_env.cfg_env.spec;
891+
892+
if spec_id >= SpecId::CANCUN {
893+
system_contracts.extend(SystemContract::cancun());
894+
}
895+
896+
if spec_id >= SpecId::PRAGUE {
897+
system_contracts.extend(SystemContract::prague(None));
898+
}
899+
900+
system_contracts
901+
}
902+
846903
/// Returns [`BlobParams`] corresponding to the current spec.
847904
pub fn blob_params(&self) -> BlobParams {
848905
let spec_id = self.env.read().evm_env.cfg_env.spec;

crates/anvil/src/evm/celo_precompile.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,25 @@
1111
//! - to address (32 bytes, left-padded)
1212
//! - value (32 bytes, big-endian U256)
1313
14+
use std::borrow::Cow;
15+
1416
use alloy_evm::precompiles::{DynPrecompile, PrecompileInput};
1517
use alloy_primitives::{Address, U256, address};
1618
use revm::precompile::{PrecompileError, PrecompileId, PrecompileOutput, PrecompileResult};
1719

20+
/// Address of the Celo transfer precompile.
1821
pub const CELO_TRANSFER_ADDRESS: Address = address!("0x00000000000000000000000000000000000000fd");
1922

20-
/// Gas cost for Celo transfer precompile
23+
/// ID for the [Celo transfer precompile](CELO_TRANSFER_ADDRESS).
24+
pub static PRECOMPILE_ID_CELO_TRANSFER: PrecompileId =
25+
PrecompileId::Custom(Cow::Borrowed("celo transfer"));
26+
27+
/// Gas cost for Celo transfer precompile.
2128
const CELO_TRANSFER_GAS_COST: u64 = 9000;
2229

23-
/// Returns the celo native transfer
30+
/// Returns the Celo native transfer.
2431
pub fn precompile() -> DynPrecompile {
25-
DynPrecompile::new_stateful(PrecompileId::custom("celo transfer"), celo_transfer_precompile)
32+
DynPrecompile::new_stateful(PRECOMPILE_ID_CELO_TRANSFER.clone(), celo_transfer_precompile)
2633
}
2734

2835
/// Celo transfer precompile implementation.

0 commit comments

Comments
 (0)