Skip to content

Commit

Permalink
feat: adds fork-transaction-hash and rename network to fork-url (
Browse files Browse the repository at this point in the history
…#431)

* feat: refactor network cli param for fork_url

* chore: clean up

* feat: add fork-from-transaction-hash

* refactor: add helper methods to config impl for fork config updates
  • Loading branch information
dutterbutter authored Nov 26, 2024
1 parent 45b9fd4 commit 4a99b85
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 49 deletions.
21 changes: 17 additions & 4 deletions src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,10 @@ pub struct ForkArgs {
/// - http://XXX:YY
#[arg(
long,
help = "Network to fork from (e.g., mainnet, sepolia-testnet, etc.)."
alias = "network",
help = "Network to fork from (e.g., http://XXX:YY, mainnet, sepolia-testnet)."
)]
pub network: String,
pub fork_url: String,
// Fork at a given L2 miniblock height.
// If not set - will use the current finalized block from the network.
#[arg(
Expand All @@ -239,6 +240,17 @@ pub struct ForkArgs {
alias = "fork-at"
)]
pub fork_block_number: Option<u64>,

/// Fetch state from a specific transaction hash over a remote endpoint.
///
/// See --fork-url.
#[arg(
long,
requires = "fork_url",
value_name = "TRANSACTION",
conflicts_with = "fork_block_number"
)]
pub fork_transaction_hash: Option<H256>,
}

#[derive(Debug, Parser, Clone)]
Expand All @@ -252,9 +264,10 @@ pub struct ReplayArgs {
/// - http://XXX:YY
#[arg(
long,
help = "Network to fork from (e.g., mainnet, sepolia-testnet, etc.)."
alias = "network",
help = "Network to fork from (e.g., http://XXX:YY, mainnet, sepolia-testnet)."
)]
pub network: String,
pub fork_url: String,
/// Transaction hash to replay.
#[arg(help = "Transaction hash to replay.")]
pub tx: H256,
Expand Down
63 changes: 61 additions & 2 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::net::{IpAddr, Ipv4Addr};

use crate::fork::ForkDetails;
use crate::{observability, system_contracts};
use anyhow::anyhow;
use std::net::{IpAddr, Ipv4Addr};

use crate::config::{
cache::{CacheConfig, CacheType},
Expand Down Expand Up @@ -404,6 +405,12 @@ impl TestNodeConfig {
self.chain_id.unwrap_or(TEST_NODE_NETWORK_ID)
}

/// Update the chain ID
pub fn update_chain_id(&mut self, chain_id: Option<u32>) -> &mut Self {
self.chain_id = chain_id;
self
}

/// Set the system contracts configuration option
#[must_use]
pub fn with_system_contracts(mut self, option: Option<system_contracts::Options>) -> Self {
Expand Down Expand Up @@ -460,6 +467,12 @@ impl TestNodeConfig {
self.l1_gas_price.unwrap_or(DEFAULT_L1_GAS_PRICE)
}

/// Update the L1 gas price
pub fn update_l1_gas_price(&mut self, price: Option<u64>) -> &mut Self {
self.l1_gas_price = price;
self
}

/// Set the L2 gas price
#[must_use]
pub fn with_l2_gas_price(mut self, price: Option<u64>) -> Self {
Expand All @@ -474,6 +487,12 @@ impl TestNodeConfig {
self.l2_gas_price.unwrap_or(DEFAULT_L2_GAS_PRICE)
}

/// Update the L2 gas price
pub fn update_l2_gas_price(&mut self, price: Option<u64>) -> &mut Self {
self.l2_gas_price = price;
self
}

/// Set the L1 pubdata price
#[must_use]
pub fn with_l1_pubdata_price(mut self, price: Option<u64>) -> Self {
Expand All @@ -486,6 +505,12 @@ impl TestNodeConfig {
self.l1_pubdata_price.unwrap_or(DEFAULT_FAIR_PUBDATA_PRICE)
}

/// Update the L1 pubdata price
pub fn update_l1_pubdata_price(&mut self, price: Option<u64>) -> &mut Self {
self.l1_pubdata_price = price;
self
}

/// Set the log level
#[must_use]
pub fn with_log_level(mut self, level: Option<LogLevel>) -> Self {
Expand Down Expand Up @@ -571,6 +596,12 @@ impl TestNodeConfig {
.unwrap_or(DEFAULT_ESTIMATE_GAS_SCALE_FACTOR)
}

/// Update the gas limit scale factor
pub fn update_gas_limit_scale(&mut self, scale: Option<f32>) -> &mut Self {
self.limit_scale_factor = scale;
self
}

/// Set the price scale factor
#[must_use]
pub fn with_price_scale(mut self, scale: Option<f64>) -> Self {
Expand All @@ -586,6 +617,12 @@ impl TestNodeConfig {
.unwrap_or(DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR)
}

/// Updates the price scale factor
pub fn update_price_scale(&mut self, scale: Option<f64>) -> &mut Self {
self.price_scale_factor = scale;
self
}

/// Set the detail level of VM execution logs
#[must_use]
pub fn with_vm_log_detail(mut self, detail: Option<ShowVMDetails>) -> Self {
Expand Down Expand Up @@ -675,6 +712,28 @@ impl TestNodeConfig {
pub fn is_health_check_endpoint_endpoint_enabled(&self) -> bool {
self.health_check_endpoint
}

/// Updates the configuration from fork details.
pub async fn update_with_fork_details(
&mut self,
fork_details_result: Result<ForkDetails, eyre::Report>,
) -> Result<Option<ForkDetails>, anyhow::Error> {
match fork_details_result {
Ok(fd) => {
self.update_l1_gas_price(Some(fd.l1_gas_price))
.update_l2_gas_price(Some(fd.l2_fair_gas_price))
.update_l1_pubdata_price(Some(fd.fair_pubdata_price))
.update_price_scale(Some(fd.estimate_gas_price_scale_factor))
.update_gas_limit_scale(Some(fd.estimate_gas_scale_factor))
.update_chain_id(Some(fd.chain_id.as_u64() as u32));
Ok(Some(fd))
}
Err(error) => {
tracing::error!("Error while attempting to fork: {:?}", error);
Err(anyhow!(error))
}
}
}
}

/// Account Generator
Expand Down
62 changes: 19 additions & 43 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,54 +154,30 @@ async fn main() -> anyhow::Result<()> {
}
}
Command::Fork(fork) => {
match ForkDetails::from_network(
&fork.network,
fork.fork_block_number,
&config.cache_config,
)
.await
{
Ok(fd) => {
// Update the config here
config = config
.with_l1_gas_price(Some(fd.l1_gas_price))
.with_l2_gas_price(Some(fd.l2_fair_gas_price))
.with_l1_pubdata_price(Some(fd.fair_pubdata_price))
.with_price_scale(Some(fd.estimate_gas_price_scale_factor))
.with_gas_limit_scale(Some(fd.estimate_gas_scale_factor))
.with_chain_id(Some(fd.chain_id.as_u64() as u32));
Some(fd)
}
Err(error) => {
tracing::error!("cannot fork: {:?}", error);
return Err(anyhow!(error));
}
}
let fork_details_result = if let Some(tx_hash) = fork.fork_transaction_hash {
// If fork_transaction_hash is provided, use from_network_tx
ForkDetails::from_network_tx(&fork.fork_url, tx_hash, &config.cache_config).await
} else {
// Otherwise, use from_network
ForkDetails::from_network(
&fork.fork_url,
fork.fork_block_number,
&config.cache_config,
)
.await
};

config.update_with_fork_details(fork_details_result).await?
}
Command::ReplayTx(replay_tx) => {
match ForkDetails::from_network_tx(
&replay_tx.network,
let fork_details_result = ForkDetails::from_network_tx(
&replay_tx.fork_url,
replay_tx.tx,
&config.cache_config,
)
.await
{
Ok(fd) => {
// Update the config here
config = config
.with_l1_gas_price(Some(fd.l1_gas_price))
.with_l2_gas_price(Some(fd.l2_fair_gas_price))
.with_l1_pubdata_price(Some(fd.fair_pubdata_price))
.with_price_scale(Some(fd.estimate_gas_price_scale_factor))
.with_gas_limit_scale(Some(fd.estimate_gas_scale_factor))
.with_chain_id(Some(fd.chain_id.as_u64() as u32));
Some(fd)
}
Err(error) => {
tracing::error!("cannot replay: {:?}", error);
return Err(anyhow!(error));
}
}
.await;

config.update_with_fork_details(fork_details_result).await?
}
};

Expand Down

0 comments on commit 4a99b85

Please sign in to comment.