Skip to content

Commit

Permalink
simplify EthereumDataFormatError usage reusing existing types (#1474)
Browse files Browse the repository at this point in the history
simplify EthereumDataFormatError usage reusing existing types

Co-authored-by: greged93 <[email protected]>
  • Loading branch information
tcoratger and greged93 authored Oct 23, 2024
1 parent 579af89 commit c48c902
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 43 deletions.
5 changes: 2 additions & 3 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
providers::{
eth_provider::{
database::Database,
error::{EthApiError, EthereumDataFormatError, SignatureError},
error::SignatureError,
provider::{EthApiResult, EthDataProvider},
TransactionProvider, TxPoolProvider,
},
Expand Down Expand Up @@ -99,8 +99,7 @@ where
{
async fn send_raw_transaction(&self, transaction: Bytes) -> EthApiResult<B256> {
// Decode the transaction data
let transaction_signed = TransactionSigned::decode(&mut transaction.0.as_ref())
.map_err(|_| EthApiError::EthereumDataFormat(EthereumDataFormatError::TransactionConversion))?;
let transaction_signed = TransactionSigned::decode(&mut transaction.0.as_ref())?;

// Recover the signer from the transaction
let signer = transaction_signed.recover_signer().ok_or(SignatureError::Recovery)?;
Expand Down
27 changes: 7 additions & 20 deletions src/providers/debug_provider.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
providers::eth_provider::{
error::{EthApiError, EthereumDataFormatError, SignatureError},
error::{EthApiError, SignatureError},
provider::{EthApiResult, EthereumProvider},
},
tracing::builder::TracerBuilder,
Expand Down Expand Up @@ -61,14 +61,7 @@ impl<P: EthereumProvider> DebugDataProvider<P> {
impl<P: EthereumProvider + Send + Sync + 'static> DebugProvider for DebugDataProvider<P> {
async fn raw_header(&self, block_id: BlockId) -> EthApiResult<Bytes> {
let mut res = Vec::new();
if let Some(header) = self
.eth_provider
.header(&block_id)
.await?
.map(Header::try_from)
.transpose()
.map_err(|_| EthApiError::EthereumDataFormat(EthereumDataFormatError::HeaderConversion))?
{
if let Some(header) = self.eth_provider.header(&block_id).await?.map(Header::try_from).transpose()? {
header.encode(&mut res);
}

Expand All @@ -82,8 +75,7 @@ impl<P: EthereumProvider + Send + Sync + 'static> DebugProvider for DebugDataPro
};
let mut raw_block = Vec::new();
if let Some(block) = block {
let block =
Block::try_from(block.inner).map_err(|_| EthApiError::from(EthereumDataFormatError::Primitive))?;
let block = Block::try_from(block.inner)?;
block.encode(&mut raw_block);
}
Ok(raw_block.into())
Expand All @@ -94,9 +86,8 @@ impl<P: EthereumProvider + Send + Sync + 'static> DebugProvider for DebugDataPro

if let Some(tx) = transaction {
let signature = tx.signature.ok_or_else(|| EthApiError::from(SignatureError::MissingSignature))?;
let tx = tx.try_into().map_err(|_| EthApiError::EthereumDataFormat(EthereumDataFormatError::Primitive))?;
let bytes = TransactionSigned::from_transaction_and_signature(
tx,
tx.try_into()?,
reth_primitives::Signature::from_rs_and_parity(
signature.r,
signature.s,
Expand All @@ -118,9 +109,8 @@ impl<P: EthereumProvider + Send + Sync + 'static> DebugProvider for DebugDataPro

for t in transactions {
let signature = t.signature.ok_or_else(|| EthApiError::from(SignatureError::MissingSignature))?;
let tx = t.try_into().map_err(|_| EthApiError::EthereumDataFormat(EthereumDataFormatError::Primitive))?;
let bytes = TransactionSigned::from_transaction_and_signature(
tx,
t.try_into()?,
reth_primitives::Signature::from_rs_and_parity(
signature.r,
signature.s,
Expand All @@ -145,13 +135,10 @@ impl<P: EthereumProvider + Send + Sync + 'static> DebugProvider for DebugDataPro
// Iterates through the receipts of the block using the `block_receipts` method of the Ethereum API
for receipt in receipts {
// Converts the transaction type to a u8 and then tries to convert it into TxType
let tx_type = Into::<u8>::into(receipt.transaction_type())
.try_into()
.map_err(|_| EthApiError::EthereumDataFormat(EthereumDataFormatError::ReceiptConversion))?;
let tx_type = Into::<u8>::into(receipt.transaction_type()).try_into()?;

// Tries to convert the cumulative gas used to u64
let cumulative_gas_used = TryInto::<u64>::try_into(receipt.inner.inner.cumulative_gas_used())
.map_err(|_| EthApiError::EthereumDataFormat(EthereumDataFormatError::ReceiptConversion))?;
let cumulative_gas_used = receipt.inner.inner.cumulative_gas_used().try_into()?;

// Creates a ReceiptWithBloom from the receipt data
raw_receipts.push(
Expand Down
20 changes: 7 additions & 13 deletions src/providers/eth_provider/database/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use super::{
types::{header::StoredHeader, transaction::StoredTransaction},
Database,
};
use crate::providers::eth_provider::error::{EthApiError, EthereumDataFormatError};
use crate::providers::eth_provider::error::EthApiError;
use alloy_primitives::{B256, U256};
use alloy_rlp::Encodable;
use alloy_rpc_types::{Block, BlockHashOrNumber, BlockTransactions, Header, Transaction};
use alloy_serde::WithOtherFields;
use async_trait::async_trait;
use mongodb::bson::doc;
use reth_primitives::{constants::EMPTY_ROOT_HASH, TransactionSigned};
use reth_primitives::{constants::EMPTY_ROOT_HASH, BlockBody};
use tracing::instrument;

/// Trait for interacting with a database that stores Ethereum typed
Expand Down Expand Up @@ -132,19 +132,13 @@ impl EthereumBlockStore for Database {
BlockTransactions::Hashes(transactions.iter().map(|tx| tx.hash).collect())
};

let signed_transactions = transactions
.into_iter()
.map(|tx| TransactionSigned::try_from(tx).map_err(|_| EthereumDataFormatError::TransactionConversion))
.collect::<Result<Vec<_>, _>>()?;

let block = reth_primitives::Block {
body: reth_primitives::BlockBody {
transactions: signed_transactions,
body: BlockBody {
transactions: transactions.into_iter().map(TryFrom::try_from).collect::<Result<_, _>>()?,
withdrawals: Some(Default::default()),
..Default::default()
},
header: reth_primitives::Header::try_from(header.clone())
.map_err(|_| EthereumDataFormatError::Primitive)?,
header: header.clone().try_into()?,
};

// This is how Reth computes the block size.
Expand Down Expand Up @@ -325,10 +319,10 @@ mod tests {
let block_transactions = BlockTransactions::Full(transactions.clone());

let signed_transactions =
transactions.into_iter().map(TransactionSigned::try_from).collect::<Result<Vec<_>, _>>().unwrap();
transactions.into_iter().map(TryFrom::try_from).collect::<Result<_, _>>().unwrap();

let block = reth_primitives::Block {
body: reth_primitives::BlockBody {
body: BlockBody {
transactions: signed_transactions,
withdrawals: Some(Default::default()),
..Default::default()
Expand Down
36 changes: 36 additions & 0 deletions src/providers/eth_provider/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,42 @@ pub enum EthereumDataFormatError {
/// Error related to starknet to eth conversion or vice versa.
#[error("primitive conversion error")]
Primitive,
/// Error related to rlp conversion.
#[error(transparent)]
Rlp(#[from] alloy_rlp::Error),
/// Error related to alloy rpc/primitive conversion.
#[error(transparent)]
AlloyTransactionConversion(#[from] alloy_rpc_types::ConversionError),
/// Error related to integer conversion.
#[error(transparent)]
IntConversions(#[from] std::num::TryFromIntError),
/// Custom error with a static string.
#[error("{0}")]
CustomError(&'static str),
}

impl From<alloy_rlp::Error> for EthApiError {
fn from(value: alloy_rlp::Error) -> Self {
Self::EthereumDataFormat(EthereumDataFormatError::Rlp(value))
}
}

impl From<alloy_rpc_types::ConversionError> for EthApiError {
fn from(value: alloy_rpc_types::ConversionError) -> Self {
Self::EthereumDataFormat(EthereumDataFormatError::AlloyTransactionConversion(value))
}
}

impl From<&'static str> for EthApiError {
fn from(value: &'static str) -> Self {
Self::EthereumDataFormat(EthereumDataFormatError::CustomError(value))
}
}

impl From<std::num::TryFromIntError> for EthApiError {
fn from(value: std::num::TryFromIntError) -> Self {
Self::EthereumDataFormat(EthereumDataFormatError::IntConversions(value))
}
}

#[cfg(test)]
Expand Down
4 changes: 1 addition & 3 deletions src/providers/eth_provider/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,7 @@ where
block_id: Option<BlockId>,
) -> EthApiResult<starknet::core::types::BlockId> {
match block_id {
Some(BlockId::Hash(hash)) => {
Ok(EthBlockId::new(BlockId::Hash(hash)).try_into().map_err(EthereumDataFormatError::from)?)
}
Some(BlockId::Hash(hash)) => Ok(EthBlockId::new(BlockId::Hash(hash)).try_into()?),
Some(BlockId::Number(number_or_tag)) => {
// There is a need to separate the BlockNumberOrTag case into three subcases
// because pending Starknet blocks don't have a number.
Expand Down
6 changes: 2 additions & 4 deletions src/tracing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod builder;
use crate::{
providers::eth_provider::{
database::state::EthCacheDatabase,
error::{EthApiError, EthereumDataFormatError, TransactionError},
error::{EthApiError, TransactionError},
provider::EthereumProvider,
},
tracing::builder::TracingOptions,
Expand Down Expand Up @@ -375,9 +375,7 @@ fn env_with_tx(
tx: WithOtherFields<alloy_rpc_types::Transaction>,
) -> TracerResult<EnvWithHandlerCfg> {
// Convert the transaction to an ec recovered transaction and update the env with it.
let tx_ec_recovered = tx.try_into().map_err(|_| EthereumDataFormatError::TransactionConversion)?;

let tx_env = EthEvmConfig::new(Arc::new(Default::default())).tx_env(&tx_ec_recovered);
let tx_env = EthEvmConfig::new(Arc::new(Default::default())).tx_env(&tx.try_into()?);

Ok(EnvWithHandlerCfg {
env: Env::boxed(env.env.cfg.clone(), env.env.block.clone(), tx_env),
Expand Down

0 comments on commit c48c902

Please sign in to comment.