diff --git a/src/errors.rs b/src/errors.rs index 68b1ef4..8726809 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -50,6 +50,21 @@ pub struct EvmError(pub Report); impl Reject for EvmError {} +#[derive(Debug)] +pub struct InvalidRpcError(); + +impl Reject for InvalidRpcError {} + +#[derive(Debug)] +pub struct RpcError(); + +impl Reject for RpcError {} + +#[derive(Debug)] +pub struct InvalidIndexError(); + +impl Reject for InvalidIndexError {} + pub async fn handle_rejection(err: Rejection) -> Result { let code; let message: String; @@ -78,6 +93,9 @@ pub async fn handle_rejection(err: Rejection) -> Result } else if let Some(_e) = err.find::() { code = StatusCode::INTERNAL_SERVER_ERROR; message = "OVERRIDE_ERROR".to_string(); + } else if let Some(_e) = err.find::() { + code = StatusCode::BAD_REQUEST; + message = "INVALID_TRANSACTION_INDEX".to_string(); } else if let Some(_e) = err.find::() { if _e.0.to_string().contains("CallGasCostMoreThanGasLimit") { code = StatusCode::BAD_REQUEST; @@ -95,6 +113,12 @@ pub async fn handle_rejection(err: Rejection) -> Result None => "BAD_REQUEST".to_string(), }; code = StatusCode::BAD_REQUEST; + } else if let Some(_e) = err.find::() { + code = StatusCode::BAD_REQUEST; + message = "INVALID_RPC".to_string(); + } else if let Some(_e) = err.find::() { + code = StatusCode::INTERNAL_SERVER_ERROR; + message = "RPC_ERROR".to_string(); } else if err.find::().is_some() { // We can handle a specific error, here METHOD_NOT_ALLOWED, // and render it however we want diff --git a/src/simulation.rs b/src/simulation.rs index 127c73b..f357ff9 100644 --- a/src/simulation.rs +++ b/src/simulation.rs @@ -20,7 +20,7 @@ use warp::Rejection; use crate::errors::{ IncorrectChainIdError, InvalidBlockNumbersError, MultipleChainIdsError, NoURLForChainIdError, - StateNotFound, + StateNotFound, RpcError }; use crate::evm::StorageOverride; use crate::SharedSimulationState; @@ -336,7 +336,12 @@ async fn apply_block_transactions( response: &mut Vec, ) -> Result<(), Rejection> { let provider = Provider::::try_from(fork_url); - let pre_transactions = provider + + if provider.is_err() { + return Err(warp::reject::custom(NoURLForChainIdError)); + } + + let block_transactions = provider .unwrap() .get_block_with_txs( transaction @@ -344,10 +349,20 @@ async fn apply_block_transactions( .block_number .expect("Transaction has no block number"), ) - .await - .unwrap() - .unwrap(); - let relevant_transactions: Vec<_> = pre_transactions + .await; + if block_transactions.is_err() { + return Err(warp::reject::custom(RpcError())); + } + let block_transactions = block_transactions.unwrap(); + + if block_transactions.is_none() { + response.push(run(evm, transaction.clone(), true).await?); + return Ok(()); + } + + let block_transactions = block_transactions.unwrap(); + + let simulation_transactions: Vec<_> = block_transactions .transactions .iter() .map(|x| SimulationRequest { @@ -365,12 +380,12 @@ async fn apply_block_transactions( state_overrides: None, }) .collect(); - let transaction_block_index = transaction.clone().transaction_block_index.unwrap(); - let transactions_before_index = relevant_transactions + let transaction_block_index = transaction.transaction_block_index.unwrap(); + let transactions_before_index = simulation_transactions .iter() .take(transaction_block_index.as_usize()) .collect::>(); - let transactions_after_index = relevant_transactions + let transactions_after_index = simulation_transactions .iter() .skip(transaction_block_index.as_usize()); for before_tx in transactions_before_index {