Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/anvil/src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
AccountGenerator, CHAIN_ID, NodeConfig,
config::{DEFAULT_MNEMONIC, ForkChoice},
config::{DEFAULT_MNEMONIC, DEFAULT_SLOTS_IN_AN_EPOCH, ForkChoice},
eth::{EthApi, backend::db::SerializableState, pool::transactions::TransactionOrder},
};
use alloy_genesis::Genesis;
Expand Down Expand Up @@ -92,7 +92,7 @@ pub struct NodeArgs {
pub block_time: Option<Duration>,

/// Slots in an epoch
#[arg(long, value_name = "SLOTS_IN_AN_EPOCH", default_value_t = 32)]
#[arg(long, value_name = "SLOTS_IN_AN_EPOCH", default_value_t = DEFAULT_SLOTS_IN_AN_EPOCH)]
pub slots_in_an_epoch: u64,

/// Writes output of `anvil` as json to user-specified file.
Expand Down
4 changes: 3 additions & 1 deletion crates/anvil/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ pub const NODE_PORT: u16 = 8545;
pub const CHAIN_ID: u64 = 31337;
/// The default gas limit for all transactions
pub const DEFAULT_GAS_LIMIT: u64 = 30_000_000;
/// The default number of slots in an epoch used for safe/finalized block tags.
pub const DEFAULT_SLOTS_IN_AN_EPOCH: u64 = 32;
/// Default mnemonic for dev accounts
pub const DEFAULT_MNEMONIC: &str = "test test test test test test test test test test test junk";

Expand Down Expand Up @@ -507,7 +509,7 @@ impl Default for NodeConfig {
transaction_block_keeper: None,
disable_default_create2_deployer: false,
disable_pool_balance_checks: false,
slots_in_an_epoch: 32,
slots_in_an_epoch: DEFAULT_SLOTS_IN_AN_EPOCH,
memory_limit: None,
precompile_factory: None,
networks: Default::default(),
Expand Down
11 changes: 1 addition & 10 deletions crates/anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,16 +1102,7 @@ impl<N: Network> EthApi<N> {
node_info!("eth_feeHistory");
// max number of blocks in the requested range

let current = self.backend.best_number();
let slots_in_an_epoch = 32u64;

let number = match newest_block {
BlockNumber::Latest | BlockNumber::Pending => current,
BlockNumber::Earliest => 0,
BlockNumber::Number(n) => n,
BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
};
let number = self.backend.convert_block_number(Some(newest_block));

// check if the number predates the fork, if in fork mode
if let Some(fork) = self.get_fork() {
Expand Down
29 changes: 2 additions & 27 deletions crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,33 +765,8 @@ impl<N: Network> Backend<N> {

/// Returns the block and its hash for the given id
fn get_block_with_hash(&self, id: impl Into<BlockId>) -> Option<(Block, B256)> {
let hash = match id.into() {
BlockId::Hash(hash) => hash.block_hash,
BlockId::Number(number) => {
let storage = self.blockchain.storage.read();
let slots_in_an_epoch = self.slots_in_an_epoch;
match number {
BlockNumber::Latest => storage.best_hash,
BlockNumber::Earliest => storage.genesis_hash,
BlockNumber::Pending => return None,
BlockNumber::Number(num) => *storage.hashes.get(&num)?,
BlockNumber::Safe => {
if storage.best_number > (slots_in_an_epoch) {
*storage.hashes.get(&(storage.best_number - (slots_in_an_epoch)))?
} else {
storage.genesis_hash // treat the genesis block as safe "by definition"
}
}
BlockNumber::Finalized => {
if storage.best_number > (slots_in_an_epoch * 2) {
*storage.hashes.get(&(storage.best_number - (slots_in_an_epoch * 2)))?
} else {
storage.genesis_hash
}
}
}
}
};
let hash =
self.blockchain.hash_with_slots_in_an_epoch(id.into(), self.slots_in_an_epoch)?;
let block = self.get_block_by_hash(hash)?;
Some((block, hash))
}
Expand Down
36 changes: 27 additions & 9 deletions crates/anvil/src/eth/backend/mem/storage.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
//! In-memory blockchain storage
use crate::eth::{
backend::{
db::{
MaybeFullDatabase, SerializableBlock, SerializableHistoricalStates,
SerializableTransaction, StateDb,
use crate::{
config::DEFAULT_SLOTS_IN_AN_EPOCH,
eth::{
backend::{
db::{
MaybeFullDatabase, SerializableBlock, SerializableHistoricalStates,
SerializableTransaction, StateDb,
},
mem::cache::DiskStateCache,
},
mem::cache::DiskStateCache,
pool::transactions::PoolTransaction,
},
pool::transactions::PoolTransaction,
};
use alloy_consensus::{BlockHeader, Header, constants::EMPTY_WITHDRAWALS};
use alloy_eips::eip7685::EMPTY_REQUESTS_HASH;
Expand Down Expand Up @@ -435,7 +438,15 @@ impl<N: Network> BlockchainStorage<N> {

/// Returns the hash for [BlockNumberOrTag]
pub fn hash(&self, number: BlockNumberOrTag) -> Option<B256> {
let slots_in_an_epoch = 32;
self.hash_with_slots_in_an_epoch(number, DEFAULT_SLOTS_IN_AN_EPOCH)
}

/// Returns the hash for [BlockNumberOrTag] using the configured slots in an epoch.
pub fn hash_with_slots_in_an_epoch(
&self,
number: BlockNumberOrTag,
slots_in_an_epoch: u64,
) -> Option<B256> {
match number {
BlockNumberOrTag::Latest => Some(self.best_hash),
BlockNumberOrTag::Earliest => Some(self.genesis_hash),
Expand Down Expand Up @@ -510,9 +521,16 @@ impl<N: Network> Blockchain<N> {

/// returns the header hash of given block
pub fn hash(&self, id: BlockId) -> Option<B256> {
self.hash_with_slots_in_an_epoch(id, DEFAULT_SLOTS_IN_AN_EPOCH)
}

/// returns the header hash of given block using the configured slots in an epoch.
pub fn hash_with_slots_in_an_epoch(&self, id: BlockId, slots_in_an_epoch: u64) -> Option<B256> {
match id {
BlockId::Hash(h) => Some(h.block_hash),
BlockId::Number(num) => self.storage.read().hash(num),
BlockId::Number(num) => {
self.storage.read().hash_with_slots_in_an_epoch(num, slots_in_an_epoch)
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions crates/anvil/tests/it/anvil_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,28 @@ async fn test_mine_first_block_with_interval() {
assert_eq!(second_block.header.timestamp, init_timestamp + 120);
}

#[tokio::test(flavor = "multi_thread")]
async fn test_safe_and_finalized_use_configured_slots_in_epoch() {
let (api, _) = spawn(NodeConfig::test().with_slots_in_an_epoch(2)).await;

api.anvil_mine(Some(U256::from(5)), None).await.unwrap();
tokio::time::sleep(Duration::from_millis(100)).await;

let safe_block = api.block_by_number(BlockNumberOrTag::Safe).await.unwrap().unwrap();
assert_eq!(safe_block.header.number, 3);

let finalized_block = api.block_by_number(BlockNumberOrTag::Finalized).await.unwrap().unwrap();
assert_eq!(finalized_block.header.number, 1);

let safe_history =
api.fee_history(U256::from(1), BlockNumberOrTag::Safe, vec![]).await.unwrap();
assert_eq!(safe_history.oldest_block, 3);

let finalized_history =
api.fee_history(U256::from(1), BlockNumberOrTag::Finalized, vec![]).await.unwrap();
assert_eq!(finalized_history.oldest_block, 1);
}

#[tokio::test(flavor = "multi_thread")]
async fn test_anvil_reset_non_fork() {
let (api, handle) = spawn(NodeConfig::test()).await;
Expand Down
Loading