Skip to content

Commit

Permalink
fix: returning errors from fork handling (#335)
Browse files Browse the repository at this point in the history
* not panicking in is_write_initial_internal

* not panicking in fork_network_and_client

* not panicking in get_earlier_transactions_in_same_block

* not panicking in get_block_gas_details

* Update src/fork.rs

Co-authored-by: AnastasiiaVashchuk <72273339+AnastasiiaVashchuk@users.noreply.github.com>

* more specific error message

* more specific error message

* added miniblock number to error message

---------

Co-authored-by: AnastasiiaVashchuk <72273339+AnastasiiaVashchuk@users.noreply.github.com>
  • Loading branch information
vbar and AnastasiiaVashchuk committed Aug 27, 2024
1 parent b50fcd1 commit c797d5f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 37 deletions.
88 changes: 53 additions & 35 deletions src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@ impl<S: ForkSource> ForkStorage<S> {

// If value was 0, there is still a chance, that the slot was written to in the past - and only now set to 0.
// We unfortunately don't have the API to check it on the fork, but we can at least try to check it on local storage.
let mut mutator = self.inner.write().unwrap();
let mut mutator = self
.inner
.write()
.map_err(|err| eyre!("failed acquiring write lock on fork storage: {:?}", err))?;
Ok(mutator.raw_storage.is_write_initial(key))
}

Expand Down Expand Up @@ -531,7 +534,7 @@ impl ForkDetails {
fork_at: Option<u64>,
cache_config: CacheConfig,
) -> eyre::Result<Self> {
let (network, client) = Self::fork_network_and_client(fork);
let (network, client) = Self::fork_network_and_client(fork)?;
let l2_miniblock = if let Some(fork_at) = fork_at {
fork_at
} else {
Expand Down Expand Up @@ -559,7 +562,7 @@ impl ForkDetails {
tx: H256,
cache_config: CacheConfig,
) -> eyre::Result<Self> {
let (network, client) = Self::fork_network_and_client(fork);
let (network, client) = Self::fork_network_and_client(fork)?;
let opt_tx_details = client
.get_transaction_by_hash(tx)
.await
Expand Down Expand Up @@ -613,7 +616,7 @@ impl ForkDetails {
}

/// Return [`ForkNetwork`] and HTTP client for a given fork name.
pub fn fork_network_and_client(fork: &str) -> (ForkNetwork, Client<L2>) {
pub fn fork_network_and_client(fork: &str) -> eyre::Result<(ForkNetwork, Client<L2>)> {
let network = match fork {
"mainnet" => ForkNetwork::Mainnet,
"sepolia-testnet" => ForkNetwork::SepoliaTestnet,
Expand All @@ -623,44 +626,51 @@ impl ForkDetails {

let url = network.to_url();
let parsed_url = SensitiveUrl::from_str(url)
.unwrap_or_else(|_| panic!("Unable to parse client URL: {}", &url));
let client = Client::http(parsed_url)
.unwrap_or_else(|_| panic!("Unable to create a client for fork: {}", &url))
.build();

(network, client)
.map_err(|_| eyre!("Unable to parse client URL: {}", &url))?;
let builder = Client::http(parsed_url)
.map_err(|_| eyre!("Unable to create a client for fork: {}", &url))?;
Ok((network, builder.build()))
}

/// Returns transactions that are in the same L2 miniblock as replay_tx, but were executed before it.
pub async fn get_earlier_transactions_in_same_block(&self, replay_tx: H256) -> Vec<L2Tx> {
let tx_details = self
pub fn get_earlier_transactions_in_same_block(
&self,
replay_tx: H256,
) -> eyre::Result<Vec<L2Tx>> {
let opt_tx_details = self
.fork_source
.get_transaction_by_hash(replay_tx)
.unwrap()
.unwrap();
let miniblock = L2BlockNumber(tx_details.block_number.unwrap().as_u32());
.map_err(|err| {
eyre!(
"Cannot get transaction to replay by hash from fork source: {:?}",
err
)
})?;
let tx_details =
opt_tx_details.ok_or_else(|| eyre!("Cannot find transaction {:?}", replay_tx))?;
let block_number = tx_details
.block_number
.ok_or_else(|| eyre!("Block has no number"))?;
let miniblock = L2BlockNumber(block_number.as_u32());

// And we're fetching all the transactions from this miniblock.
let block_transactions = self
.fork_source
.get_raw_block_transactions(miniblock)
.unwrap();
let block_transactions = self.fork_source.get_raw_block_transactions(miniblock)?;

let mut tx_to_apply = Vec::new();

for tx in block_transactions {
let h = tx.hash();
let l2_tx: L2Tx = tx.try_into().unwrap();
tx_to_apply.push(l2_tx);

if h == replay_tx {
return tx_to_apply;
return Ok(tx_to_apply);
}
}
panic!(
Err(eyre!(
"Cound not find tx {:?} in miniblock: {:?}",
replay_tx, miniblock
);
replay_tx,
miniblock
))
}

/// Returns
Expand All @@ -673,18 +683,26 @@ impl ForkDetails {
pub fn get_block_gas_details(&self, miniblock: u32) -> Option<(u64, u64, u64)> {
let res_opt_block_details = self.fork_source.get_block_details(L2BlockNumber(miniblock));
match res_opt_block_details {
Ok(opt_block_details) => opt_block_details.map(|block_details| {
(
block_details.base.l1_gas_price,
block_details.base.l2_fair_gas_price,
block_details.base.fair_pubdata_price.unwrap_or_else(|| {
panic!(
"fair pubdata price is not present in {} l2 block details",
Ok(opt_block_details) => {
if let Some(block_details) = opt_block_details {
if let Some(fair_pubdata_price) = block_details.base.fair_pubdata_price {
Some((
block_details.base.l1_gas_price,
block_details.base.l2_fair_gas_price,
fair_pubdata_price,
))
} else {
tracing::warn!(
"Fair pubdata price is not present in {} l2 block details",
miniblock
)
}),
)
}),
);
None
}
} else {
tracing::warn!("No block details for {}", miniblock);
None
}
}
Err(e) => {
tracing::warn!("Error getting block details: {:?}", e);
None
Expand Down
13 changes: 11 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,20 @@ async fn main() -> anyhow::Result<()> {
// If we're replaying the transaction, we need to sync to the previous block
// and then replay all the transactions that happened in
let transactions_to_replay = if let Command::ReplayTx(replay_tx) = command {
fork_details
match fork_details
.as_ref()
.unwrap()
.get_earlier_transactions_in_same_block(replay_tx.tx)
.await
{
Ok(txs) => txs,
Err(error) => {
tracing::error!(
"failed to get earlier transactions in the same block for replay tx: {:?}",
error
);
return Err(anyhow!(error));
}
}
} else {
vec![]
};
Expand Down

0 comments on commit c797d5f

Please sign in to comment.