Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: returning errors from from_network and from_network_tx #316

Merged
Merged
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
104 changes: 61 additions & 43 deletions src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::{
sync::{Arc, RwLock},
};

use eyre::eyre;
use tokio::runtime::Builder;
use zksync_basic_types::{Address, L1BatchNumber, L2BlockNumber, L2ChainId, H256, U256, U64};

Expand Down Expand Up @@ -458,28 +459,30 @@ impl ForkDetails {
miniblock: u64,
chain_id: Option<L2ChainId>,
cache_config: CacheConfig,
) -> Self {
) -> eyre::Result<Self> {
let url = network.to_url();
let block_details = client
let opt_block_details = client
.get_block_details(L2BlockNumber(miniblock as u32))
.await
.unwrap()
.unwrap_or_else(|| panic!("Could not find block {:?} in {:?}", miniblock, url));

.map_err(|error| eyre!(error))?;
let block_details = opt_block_details
.ok_or_else(|| eyre!("Could not find block {:?} in {:?}", miniblock, url))?;
let root_hash = block_details
.base
.root_hash
.unwrap_or_else(|| panic!("fork block #{} missing root hash", miniblock));
let block = client
.ok_or_else(|| eyre!("fork block #{} missing root hash", miniblock))?;
let opt_block = client
.get_block_by_hash(root_hash, true)
.await
.expect("failed retrieving block")
.unwrap_or_else(|| {
panic!(
"Could not find block #{:?} ({:#x}) in {:?}",
miniblock, root_hash, url
)
});
.map_err(|error| eyre!(error))?;
let block = opt_block.ok_or_else(|| {
eyre!(
"Could not find block #{:?} ({:#x}) in {:?}",
miniblock,
root_hash,
url
)
})?;
let l1_batch_number = block_details.l1_batch_number;

tracing::info!(
Expand All @@ -489,21 +492,24 @@ impl ForkDetails {

if !block_details
.protocol_version
.map(supported_protocol_versions)
.unwrap_or(false)
.map_or(false, supported_protocol_versions)
{
panic!(
"This block is using the unsupported protocol version: {:?}. This binary supports versions {}.",
block_details.protocol_version,
supported_versions_to_string()
);
return Err(eyre!("This block is using the unsupported protocol version: {:?}. This binary supports versions {}.",
block_details.protocol_version,
supported_versions_to_string()));
}

let (estimate_gas_price_scale_factor, estimate_gas_scale_factor) =
network.local_gas_scale_factors();
let fee_params = client.get_fee_params().await.ok();
let fee_params = match client.get_fee_params().await {
Ok(fp) => Some(fp),
Err(error) => {
tracing::warn!("Cannot get fee params: {:?}", error);
None
}
};

ForkDetails {
Ok(ForkDetails {
fork_source: Box::new(HttpForkSource::new(url.to_owned(), cache_config.clone())),
l1_block: l1_batch_number,
l2_block: block,
Expand All @@ -517,15 +523,24 @@ impl ForkDetails {
estimate_gas_scale_factor,
fee_params,
cache_config,
}
})
}
/// Create a fork from a given network at a given height.
pub async fn from_network(fork: &str, fork_at: Option<u64>, cache_config: CacheConfig) -> Self {
pub async fn from_network(
fork: &str,
fork_at: Option<u64>,
cache_config: CacheConfig,
) -> eyre::Result<Self> {
let (network, client) = Self::fork_network_and_client(fork);
let l2_miniblock = if let Some(fork_at) = fork_at {
fork_at
} else {
client.get_block_number().await.unwrap().as_u64()
match client.get_block_number().await {
Ok(bn) => bn.as_u64(),
Err(error) => {
return Err(eyre!(error));
}
}
};
Self::from_network_and_miniblock_and_chain(
network,
Expand All @@ -539,23 +554,31 @@ impl ForkDetails {

/// Create a fork from a given network, at a height BEFORE a transaction.
/// This will allow us to apply this transaction locally on top of this fork.
pub async fn from_network_tx(fork: &str, tx: H256, cache_config: CacheConfig) -> Self {
pub async fn from_network_tx(
fork: &str,
tx: H256,
cache_config: CacheConfig,
) -> eyre::Result<Self> {
let (network, client) = Self::fork_network_and_client(fork);
let tx_details = client.get_transaction_by_hash(tx).await.unwrap().unwrap();
let overwrite_chain_id = Some(
L2ChainId::try_from(tx_details.chain_id.as_u64()).unwrap_or_else(|err| {
panic!("erroneous chain id {}: {:?}", tx_details.chain_id, err,)
}),
);
let miniblock_number = L2BlockNumber(tx_details.block_number.unwrap().as_u32());
let opt_tx_details = client
.get_transaction_by_hash(tx)
.await
.map_err(|error| eyre!(error))?;
let tx_details = opt_tx_details.ok_or_else(|| eyre!("could not find {:?}", tx))?;
let overwrite_chain_id = L2ChainId::try_from(tx_details.chain_id.as_u64())
.map_err(|error| eyre!("erroneous chain id {}: {:?}", tx_details.chain_id, error))?;
let block_number = tx_details
.block_number
.ok_or_else(|| eyre!("tx {:?} has no block number", tx))?;
let miniblock_number = L2BlockNumber(block_number.as_u32());
// We have to sync to the one-miniblock before the one where transaction is.
let l2_miniblock = miniblock_number.saturating_sub(1) as u64;

Self::from_network_and_miniblock_and_chain(
network,
client,
l2_miniblock,
overwrite_chain_id,
Some(overwrite_chain_id),
cache_config,
)
.await
Expand All @@ -568,12 +591,7 @@ impl ForkDetails {
cache_config: CacheConfig,
) -> eyre::Result<Self> {
let parsed_url = SensitiveUrl::from_str(&url)?;
let builder = match Client::http(parsed_url) {
Ok(b) => b,
Err(error) => {
return Err(eyre::Report::msg(error));
}
};
let builder = Client::http(parsed_url).map_err(|error| eyre!(error))?;
let client = builder.build();

block_on(async move {
Expand All @@ -583,14 +601,14 @@ impl ForkDetails {
client.get_block_number().await?.as_u64()
};

Ok(Self::from_network_and_miniblock_and_chain(
Self::from_network_and_miniblock_and_chain(
ForkNetwork::Other(url),
client,
l2_miniblock,
None,
cache_config,
)
.await)
.await
})
}

Expand Down
18 changes: 16 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::observability::Observability;
use anyhow::anyhow;
use clap::Parser;
use colored::Colorize;
use config::cli::{Cli, Command};
Expand Down Expand Up @@ -211,10 +212,23 @@ async fn main() -> anyhow::Result<()> {
let fork_details = match command {
Command::Run => None,
Command::Fork(fork) => {
Some(ForkDetails::from_network(&fork.network, fork.fork_at, config.cache).await)
match ForkDetails::from_network(&fork.network, fork.fork_at, config.cache).await {
Ok(fd) => Some(fd),
Err(error) => {
tracing::error!("cannot fork: {:?}", error);
return Err(anyhow!(error));
}
}
}
Command::ReplayTx(replay_tx) => {
Some(ForkDetails::from_network_tx(&replay_tx.network, replay_tx.tx, config.cache).await)
match ForkDetails::from_network_tx(&replay_tx.network, replay_tx.tx, config.cache).await
{
Ok(fd) => Some(fd),
Err(error) => {
tracing::error!("cannot replay: {:?}", error);
return Err(anyhow!(error));
}
}
}
};

Expand Down
Loading
Loading