Skip to content

Commit

Permalink
add anvil_{get,set}Automine/anvil_setIntervalMining
Browse files Browse the repository at this point in the history
  • Loading branch information
itegulov committed Nov 28, 2024
1 parent bf55eb9 commit 6f13900
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 26 deletions.
21 changes: 13 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ use crate::namespaces::{
EthTestNodeNamespaceT, EvmNamespaceT, HardhatNamespaceT, NetNamespaceT, Web3NamespaceT,
ZksNamespaceT,
};
use crate::node::{BlockProducer, BlockSealer, ImpersonationManager, TimestampManager, TxPool};
use crate::node::{
BlockProducer, BlockSealer, BlockSealerMode, ImpersonationManager, TimestampManager, TxPool,
};
use crate::system_contracts::SystemContracts;

#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -260,13 +262,23 @@ async fn main() -> anyhow::Result<()> {
let time = TimestampManager::default();
let impersonation = ImpersonationManager::default();
let pool = TxPool::new(impersonation.clone());
let sealing_mode = if config.no_mining {
BlockSealerMode::noop()
} else if let Some(block_time) = config.block_time {
BlockSealerMode::fixed_time(config.max_transactions, block_time)
} else {
BlockSealerMode::immediate(config.max_transactions)
};
let block_sealer = BlockSealer::new(sealing_mode);

let node: InMemoryNode<HttpForkSource> = InMemoryNode::new(
fork_details,
Some(observability),
&config,
time.clone(),
impersonation,
pool.clone(),
block_sealer.clone(),
);

if let Some(ref bytecodes_dir) = config.override_bytecodes_dir {
Expand Down Expand Up @@ -307,13 +319,6 @@ async fn main() -> anyhow::Result<()> {
}))
.await;

let block_sealer = if config.no_mining {
BlockSealer::noop()
} else if let Some(block_time) = config.block_time {
BlockSealer::fixed_time(config.max_transactions, block_time)
} else {
BlockSealer::immediate(config.max_transactions)
};
let system_contracts =
SystemContracts::from_options(&config.system_contracts_options, config.use_evm_emulator);
let block_producer_handle = tokio::task::spawn(BlockProducer::new(
Expand Down
26 changes: 25 additions & 1 deletion src/namespaces/anvil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,37 @@ use crate::utils::Numeric;

#[rpc]
pub trait AnvilNamespaceT {
/// Gets node's auto mining status.
///
/// # Returns
/// `true` if auto mining is enabled, `false` otherwise
#[rpc(name = "anvil_getAutomine")]
fn get_auto_mine(&self) -> RpcResult<bool>;

/// Enables or disables, based on the single boolean argument, the automatic mining of new
/// blocks with each new transaction submitted to the network.
///
/// # Arguments
///
/// * `enable` - if `true` automatic mining will be enabled, disabled otherwise
#[rpc(name = "anvil_setAutomine")]
fn set_auto_mine(&self, enable: bool) -> RpcResult<()>;

/// Sets the mining behavior to interval with the given interval (seconds).
///
/// # Arguments
///
/// * `seconds` - Frequency of automatic block production (in seconds)
#[rpc(name = "anvil_setIntervalMining")]
fn set_interval_mining(&self, seconds: u64) -> RpcResult<()>;

/// Sets the block timestamp interval. All future blocks' timestamps will
/// have the provided amount of seconds in-between of them. Does not affect
/// the block production interval.
///
/// # Arguments
///
/// * `seconds` - The minimum gas price to be set
/// * `seconds` - The interval between two consecutive blocks (in seconds)
#[rpc(name = "anvil_setBlockTimestampInterval")]
fn set_block_timestamp_interval(&self, seconds: u64) -> RpcResult<()>;

Expand Down
27 changes: 27 additions & 0 deletions src/node/anvil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,33 @@ use crate::{
impl<S: ForkSource + std::fmt::Debug + Clone + Send + Sync + 'static> AnvilNamespaceT
for InMemoryNode<S>
{
fn get_auto_mine(&self) -> RpcResult<bool> {
self.get_immediate_sealing()
.map_err(|err| {
tracing::error!("failed getting immediate sealing: {:?}", err);
into_jsrpc_error(Web3Error::InternalError(err))
})
.into_boxed_future()
}

fn set_auto_mine(&self, enable: bool) -> RpcResult<()> {
self.set_immediate_sealing(enable)
.map_err(|err| {
tracing::error!("failed setting immediate sealing: {:?}", err);
into_jsrpc_error(Web3Error::InternalError(err))
})
.into_boxed_future()
}

fn set_interval_mining(&self, seconds: u64) -> RpcResult<()> {
self.set_interval_sealing(seconds)
.map_err(|err| {
tracing::error!("failed setting interval sealing: {:?}", err);
into_jsrpc_error(Web3Error::InternalError(err))
})
.into_boxed_future()
}

fn set_block_timestamp_interval(&self, seconds: u64) -> RpcResult<()> {
self.time.set_block_timestamp_interval(seconds);
Ok(()).into_boxed_future()
Expand Down
9 changes: 8 additions & 1 deletion src/node/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use zksync_web3_decl::error::Web3Error;

use crate::node::impersonate::{ImpersonationManager, ImpersonationState};
use crate::node::time::{AdvanceTime, ReadTime, TimestampManager};
use crate::node::TxPool;
use crate::node::{BlockSealer, TxPool};
use crate::{
bootloader_debug::{BootloaderDebug, BootloaderDebugTracer},
config::{
Expand Down Expand Up @@ -971,6 +971,7 @@ pub struct InMemoryNode<S: Clone> {
/// An optional handle to the observability stack
pub(crate) observability: Option<Observability>,
pub(crate) pool: TxPool,
pub(crate) sealer: BlockSealer,
}

fn contract_address_from_tx_result(execution_result: &VmExecutionResultAndLogs) -> Option<H160> {
Expand All @@ -992,6 +993,7 @@ impl<S: ForkSource + std::fmt::Debug + Clone> Default for InMemoryNode<S> {
TimestampManager::default(),
impersonation.clone(),
TxPool::new(impersonation),
BlockSealer::default(),
)
}
}
Expand All @@ -1004,6 +1006,7 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
time: TimestampManager,
impersonation: ImpersonationManager,
pool: TxPool,
sealer: BlockSealer,
) -> Self {
let system_contracts_options = config.system_contracts_options;
let inner = InMemoryNodeInner::new(fork, config, &time, impersonation.clone());
Expand All @@ -1015,6 +1018,7 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
impersonation,
observability,
pool,
sealer,
}
}

Expand All @@ -1029,6 +1033,7 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
TimestampManager::default(),
impersonation.clone(),
TxPool::new(impersonation),
BlockSealer::default(),
)
}

Expand Down Expand Up @@ -2070,6 +2075,7 @@ mod tests {
TimestampManager::default(),
impersonation.clone(),
TxPool::new(impersonation),
BlockSealer::default(),
);

let tx = testing::TransactionBuilder::new().build();
Expand All @@ -2094,6 +2100,7 @@ mod tests {
TimestampManager::default(),
impersonation.clone(),
TxPool::new(impersonation),
BlockSealer::default(),
);

let private_key = K256PrivateKey::from_bytes(H256::repeat_byte(0xef)).unwrap();
Expand Down
43 changes: 42 additions & 1 deletion src/node/in_memory_ext.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::node::sealer::BlockSealerMode;
use crate::utils::Numeric;
use crate::{
fork::{ForkDetails, ForkSource},
Expand All @@ -7,6 +8,7 @@ use crate::{
};
use anyhow::{anyhow, Context};
use std::convert::TryInto;
use std::time::Duration;
use zksync_types::{
get_code_key, get_nonce_key,
utils::{nonces_to_full_nonce, storage_key_for_eth_balance},
Expand Down Expand Up @@ -360,6 +362,44 @@ impl<S: ForkSource + std::fmt::Debug + Clone + Send + Sync + 'static> InMemoryNo
observability.disable_logging()
}
}

pub fn get_immediate_sealing(&self) -> Result<bool> {
Ok(self.sealer.is_immediate())
}

pub fn set_immediate_sealing(&self, enable: bool) -> Result<()> {
if enable {
self.sealer.set_mode(BlockSealerMode::immediate(
self.inner
.read()
.map_err(|err| anyhow!("failed acquiring lock: {:?}", err))?
.config
.max_transactions,
))
} else {
self.sealer.set_mode(BlockSealerMode::Noop)
}
Ok(())
}

pub fn set_interval_sealing(&self, seconds: u64) -> Result<()> {
let sealing_mode = if seconds == 0 {
BlockSealerMode::noop()
} else {
let block_time = Duration::from_secs(seconds);

BlockSealerMode::fixed_time(
self.inner
.read()
.map_err(|err| anyhow!("failed acquiring lock: {:?}", err))?
.config
.max_transactions,
block_time,
)
};
self.sealer.set_mode(sealing_mode);
Ok(())
}
}

#[cfg(test)]
Expand All @@ -368,7 +408,7 @@ mod tests {
use crate::fork::ForkStorage;
use crate::namespaces::EthNamespaceT;
use crate::node::time::{ReadTime, TimestampManager};
use crate::node::{ImpersonationManager, InMemoryNodeInner, Snapshot, TxPool};
use crate::node::{BlockSealer, ImpersonationManager, InMemoryNodeInner, Snapshot, TxPool};
use crate::{http_fork_source::HttpForkSource, node::InMemoryNode};
use std::str::FromStr;
use std::sync::{Arc, RwLock};
Expand Down Expand Up @@ -507,6 +547,7 @@ mod tests {
impersonation,
observability: None,
pool,
sealer: BlockSealer::default(),
};

let address = Address::from_str("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049").unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ mod zks;

pub use self::{
block_producer::BlockProducer, impersonate::ImpersonationManager, pool::TxPool,
sealer::BlockSealer, time::TimestampManager,
sealer::BlockSealer, sealer::BlockSealerMode, time::TimestampManager,
};
pub use in_memory::*;
Loading

0 comments on commit 6f13900

Please sign in to comment.