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

use result for TransactionCompact::fill. #12170

Merged
Merged
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion crates/optimism/rpc/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! RPC errors specific to OP.

use alloy_rpc_types_eth::error::EthRpcErrorCode;
use alloy_rpc_types_eth::{error::EthRpcErrorCode, BlockError};
use jsonrpsee_types::error::INTERNAL_ERROR_CODE;
use reth_optimism_evm::OpBlockExecutionError;
use reth_primitives::revm_primitives::{InvalidTransaction, OptimismInvalidTransaction};
Expand Down Expand Up @@ -113,3 +113,9 @@ impl From<SequencerClientError> for jsonrpsee_types::error::ErrorObject<'static>
)
}
}

impl From<BlockError> for OpEthApiError {
fn from(error: BlockError) -> Self {
Self::Eth(error.into())
}
}
12 changes: 6 additions & 6 deletions crates/optimism/rpc/src/eth/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use reth_rpc_eth_api::{
use reth_rpc_eth_types::utils::recover_raw_transaction;
use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool};

use crate::{OpEthApi, SequencerClient};
use crate::{OpEthApi, OpEthApiError, SequencerClient};

impl<N> EthTransactions for OpEthApi<N>
where
Expand Down Expand Up @@ -76,12 +76,13 @@ where
N: FullNodeComponents,
{
type Transaction = Transaction;
type Error = OpEthApiError;

fn fill(
&self,
tx: TransactionSignedEcRecovered,
tx_info: TransactionInfo,
) -> Self::Transaction {
) -> Result<Self::Transaction, Self::Error> {
let from = tx.signer();
let TransactionSigned { transaction, signature, hash } = tx.into_signed();

Expand All @@ -106,8 +107,7 @@ where
.inner
.provider()
.receipt_by_hash(hash)
.ok() // todo: change sig to return result
.flatten()
.map_err(Self::Error::from_eth_err)?
.and_then(|receipt| receipt.deposit_receipt_version);

let TransactionInfo {
Expand All @@ -120,7 +120,7 @@ where
})
.unwrap_or_else(|| inner.max_fee_per_gas());

Transaction {
Ok(Transaction {
inner: alloy_rpc_types_eth::Transaction {
inner,
block_hash,
Expand All @@ -130,7 +130,7 @@ where
effective_gas_price: Some(effective_gas_price),
},
deposit_receipt_version,
}
})
}

fn otterscan_api_truncate_input(tx: &mut Self::Transaction) {
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc/rpc-eth-api/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,8 @@ where
trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash");
Ok(EthTransactions::transaction_by_hash(self, hash)
.await?
.map(|tx| tx.into_transaction(self.tx_resp_builder())))
.map(|tx| tx.into_transaction(self.tx_resp_builder()))
.transpose()?)
}

/// Handler for: `eth_getRawTransactionByBlockHashAndIndex`
Expand Down
3 changes: 1 addition & 2 deletions crates/rpc/rpc-eth-api/src/helpers/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ pub trait EthBlocks: LoadBlock {
full.into(),
Some(block_hash),
self.tx_resp_builder(),
)
.map_err(Self::Error::from_eth_err)?;
)?;
Ok(Some(block))
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/rpc/rpc-eth-api/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
pub mod block;
pub mod blocking_task;
pub mod call;
pub mod error;
pub mod fee;
pub mod pending_block;
pub mod receipt;
Expand Down
6 changes: 3 additions & 3 deletions crates/rpc/rpc-eth-api/src/helpers/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
tx.clone().with_signer(*signer),
tx_info,
self.tx_resp_builder(),
)))
)?))
}
}

Expand All @@ -233,7 +233,7 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
RpcNodeCore::pool(self).get_transaction_by_sender_and_nonce(sender, nonce)
{
let transaction = tx.transaction.clone().into_consensus();
return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder())));
return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder())?));
}
}

Expand Down Expand Up @@ -291,7 +291,7 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
)
})
})
.ok_or(EthApiError::HeaderNotFound(block_id).into())
.ok_or(EthApiError::HeaderNotFound(block_id))?
.map(Some)
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/rpc/rpc-eth-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ pub mod node;
pub mod pubsub;
pub mod types;

pub use reth_rpc_eth_types::error::{
AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError,
};
pub use reth_rpc_types_compat::TransactionCompat;

pub use bundle::{EthBundleApiServer, EthCallBundleApiServer};
pub use core::{EthApiServer, FullEthApiServer};
pub use filter::EthFilterApiServer;
pub use helpers::error::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError};
pub use node::{RpcNodeCore, RpcNodeCoreExt};
pub use pubsub::EthPubSubApiServer;
pub use types::{EthApiTypes, FullEthApiTypes, RpcBlock, RpcReceipt, RpcTransaction};
Expand Down
15 changes: 13 additions & 2 deletions crates/rpc/rpc-eth-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,26 @@ pub type RpcBlock<T> = Block<RpcTransaction<T>, <T as Network>::HeaderResponse>;
/// Adapter for network specific receipt type.
pub type RpcReceipt<T> = <T as Network>::ReceiptResponse;

/// Adapter for network specific error type.
pub type RpcError<T> = <T as EthApiTypes>::Error;

/// Helper trait holds necessary trait bounds on [`EthApiTypes`] to implement `eth` API.
pub trait FullEthApiTypes:
EthApiTypes<TransactionCompat: TransactionCompat<Transaction = RpcTransaction<Self::NetworkTypes>>>
EthApiTypes<
TransactionCompat: TransactionCompat<
Transaction = RpcTransaction<Self::NetworkTypes>,
Error = RpcError<Self>,
>,
>
{
}

impl<T> FullEthApiTypes for T where
T: EthApiTypes<
TransactionCompat: TransactionCompat<Transaction = RpcTransaction<T::NetworkTypes>>,
TransactionCompat: TransactionCompat<
Transaction = RpcTransaction<T::NetworkTypes>,
Error = RpcError<T>,
>,
>
{
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//! Helper traits to wrap generic l1 errors, in network specific error type configured in
//! [`EthApiTypes`](crate::EthApiTypes).
//! `reth_rpc_eth_api::EthApiTypes`.

use reth_rpc_eth_types::EthApiError;
use revm_primitives::EVMError;

use crate::EthApiError;

/// Helper trait to wrap core [`EthApiError`].
pub trait FromEthApiError: From<EthApiError> {
/// Converts from error via [`EthApiError`].
Expand Down Expand Up @@ -51,7 +52,7 @@ pub trait AsEthApiError {
fn as_err(&self) -> Option<&EthApiError>;

/// Returns `true` if error is
/// [`RpcInvalidTransactionError::GasTooHigh`](reth_rpc_eth_types::RpcInvalidTransactionError::GasTooHigh).
/// [`RpcInvalidTransactionError::GasTooHigh`](crate::RpcInvalidTransactionError::GasTooHigh).
fn is_gas_too_high(&self) -> bool {
if let Some(err) = self.as_err() {
return err.is_gas_too_high()
Expand All @@ -61,7 +62,7 @@ pub trait AsEthApiError {
}

/// Returns `true` if error is
/// [`RpcInvalidTransactionError::GasTooLow`](reth_rpc_eth_types::RpcInvalidTransactionError::GasTooLow).
/// [`RpcInvalidTransactionError::GasTooLow`](crate::RpcInvalidTransactionError::GasTooLow).
fn is_gas_too_low(&self) -> bool {
if let Some(err) = self.as_err() {
return err.is_gas_too_low()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Implementation specific Errors for the `eth_` namespace.

use std::time::Duration;
pub mod api;
pub use api::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError};

use core::time::Duration;

use alloy_eips::BlockId;
use alloy_primitives::{Address, Bytes, U256};
Expand Down
11 changes: 6 additions & 5 deletions crates/rpc/rpc-eth-types/src/simulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ use revm::{db::CacheDB, Database};
use revm_primitives::{keccak256, Address, BlockEnv, Bytes, ExecutionResult, TxKind, B256, U256};

use crate::{
cache::db::StateProviderTraitObjWrapper, error::ToRpcError, EthApiError, RevertError,
RpcInvalidTransactionError,
cache::db::StateProviderTraitObjWrapper,
error::{api::FromEthApiError, ToRpcError},
EthApiError, RevertError, RpcInvalidTransactionError,
};

/// Errors which may occur during `eth_simulateV1` execution.
Expand Down Expand Up @@ -170,7 +171,7 @@ where

/// Handles outputs of the calls execution and builds a [`SimulatedBlock`].
#[expect(clippy::complexity)]
pub fn build_block<T: TransactionCompat>(
pub fn build_block<T: TransactionCompat<Error: FromEthApiError>>(
results: Vec<(Address, ExecutionResult)>,
transactions: Vec<TransactionSigned>,
block_env: &BlockEnv,
Expand All @@ -179,7 +180,7 @@ pub fn build_block<T: TransactionCompat>(
full_transactions: bool,
db: &CacheDB<StateProviderDatabase<StateProviderTraitObjWrapper<'_>>>,
tx_resp_builder: &T,
) -> Result<SimulatedBlock<Block<T::Transaction>>, EthApiError> {
) -> Result<SimulatedBlock<Block<T::Transaction>>, T::Error> {
let mut calls: Vec<SimCallResult> = Vec::with_capacity(results.len());
let mut senders = Vec::with_capacity(results.len());
let mut receipts = Vec::with_capacity(results.len());
Expand Down Expand Up @@ -272,7 +273,7 @@ pub fn build_block<T: TransactionCompat>(
}
}

let state_root = db.db.state_root(hashed_state)?;
let state_root = db.db.state_root(hashed_state).map_err(T::Error::from_eth_err)?;

let header = reth_primitives::Header {
beneficiary: block_env.coinbase,
Expand Down
5 changes: 4 additions & 1 deletion crates/rpc/rpc-eth-types/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ impl TransactionSource {
}

/// Conversion into network specific transaction type.
pub fn into_transaction<T: TransactionCompat>(self, resp_builder: &T) -> T::Transaction {
pub fn into_transaction<T: TransactionCompat>(
self,
resp_builder: &T,
) -> Result<T::Transaction, T::Error> {
match self {
Self::Pool(tx) => from_recovered(tx, resp_builder),
Self::Block { transaction, index, block_hash, block_number, base_fee } => {
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/rpc-types-compat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ alloy-consensus.workspace = true

# io
serde.workspace = true
jsonrpsee-types.workspace = true

[dev-dependencies]
serde_json.workspace = true
11 changes: 6 additions & 5 deletions crates/rpc/rpc-types-compat/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Compatibility functions for rpc `Block` type.

use crate::{transaction::from_recovered_with_block_context, TransactionCompat};
use alloy_consensus::Sealed;
use alloy_eips::eip4895::Withdrawals;
use alloy_primitives::{B256, U256};
use alloy_rlp::Encodable;
use alloy_rpc_types_eth::{
Block, BlockError, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
};
use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders};

use crate::{transaction::from_recovered_with_block_context, TransactionCompat};

/// Converts the given primitive block into a [`Block`] response with the given
/// [`BlockTransactionsKind`]
///
Expand All @@ -20,7 +21,7 @@ pub fn from_block<T: TransactionCompat>(
kind: BlockTransactionsKind,
block_hash: Option<B256>,
tx_resp_builder: &T,
) -> Result<Block<T::Transaction>, BlockError> {
) -> Result<Block<T::Transaction>, T::Error> {
match kind {
BlockTransactionsKind::Hashes => {
Ok(from_block_with_tx_hashes::<T::Transaction>(block, total_difficulty, block_hash))
Expand Down Expand Up @@ -63,7 +64,7 @@ pub fn from_block_full<T: TransactionCompat>(
total_difficulty: U256,
block_hash: Option<B256>,
tx_resp_builder: &T,
) -> Result<Block<T::Transaction>, BlockError> {
) -> Result<Block<T::Transaction>, T::Error> {
let block_hash = block_hash.unwrap_or_else(|| block.block.header.hash_slow());
let block_number = block.block.number;
let base_fee_per_gas = block.block.base_fee_per_gas;
Expand All @@ -88,7 +89,7 @@ pub fn from_block_full<T: TransactionCompat>(

from_recovered_with_block_context::<T>(signed_tx_ec_recovered, tx_info, tx_resp_builder)
})
.collect::<Vec<_>>();
.collect::<Result<Vec<_>, T::Error>>()?;

Ok(from_block_with_transactions(
block_length,
Expand Down
14 changes: 11 additions & 3 deletions crates/rpc/rpc-types-compat/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Compatibility functions for rpc `Transaction` type.

use core::error;
use std::fmt;

use alloy_consensus::Transaction as _;
Expand All @@ -19,7 +20,7 @@ pub fn from_recovered_with_block_context<T: TransactionCompat>(
tx: TransactionSignedEcRecovered,
tx_info: TransactionInfo,
resp_builder: &T,
) -> T::Transaction {
) -> Result<T::Transaction, T::Error> {
resp_builder.fill(tx, tx_info)
}

Expand All @@ -28,7 +29,7 @@ pub fn from_recovered_with_block_context<T: TransactionCompat>(
pub fn from_recovered<T: TransactionCompat>(
tx: TransactionSignedEcRecovered,
resp_builder: &T,
) -> T::Transaction {
) -> Result<T::Transaction, T::Error> {
resp_builder.fill(tx, TransactionInfo::default())
}

Expand All @@ -43,9 +44,16 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug {
+ Clone
+ fmt::Debug;

/// RPC transaction error type.
type Error: error::Error + Into<jsonrpsee_types::ErrorObject<'static>>;

/// Create a new rpc transaction result for a _pending_ signed transaction, setting block
/// environment related fields to `None`.
fn fill(&self, tx: TransactionSignedEcRecovered, tx_inf: TransactionInfo) -> Self::Transaction;
fn fill(
&self,
tx: TransactionSignedEcRecovered,
tx_inf: TransactionInfo,
) -> Result<Self::Transaction, Self::Error>;

/// Truncates the input of a transaction to only the first 4 bytes.
// todo: remove in favour of using constructor on `TransactionResponse` or similar
Expand Down
15 changes: 10 additions & 5 deletions crates/rpc/rpc/src/eth/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use tokio::{
sync::{mpsc::Receiver, Mutex},
time::MissedTickBehavior,
};
use tracing::trace;
use tracing::{error, trace};

/// The maximum number of headers we read at once when handling a range filter.
const MAX_HEADERS_RANGE: u64 = 1_000; // with ~530bytes per header this is ~500kb
Expand Down Expand Up @@ -625,10 +625,15 @@ where
let mut prepared_stream = self.txs_stream.lock().await;

while let Ok(tx) = prepared_stream.try_recv() {
pending_txs.push(from_recovered(
tx.transaction.to_recovered_transaction(),
&self.tx_resp_builder,
))
match from_recovered(tx.transaction.to_recovered_transaction(), &self.tx_resp_builder) {
Ok(tx) => pending_txs.push(tx),
Err(err) => {
error!(target: "rpc",
%err,
"Failed to fill txn with block context"
);
}
}
}
FilterChanges::Transactions(pending_txs)
}
Expand Down
Loading
Loading