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
7 changes: 7 additions & 0 deletions crates/optimism/rpc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use alloy_rpc_types::error::EthRpcErrorCode;
use jsonrpsee_types::error::INTERNAL_ERROR_CODE;
use reth_optimism_evm::OptimismBlockExecutionError;
use reth_primitives::revm_primitives::{InvalidTransaction, OptimismInvalidTransaction};
use reth_provider::ProviderError;
use reth_rpc_eth_api::AsEthApiError;
use reth_rpc_eth_types::EthApiError;
use reth_rpc_server_types::result::{internal_rpc_err, rpc_err};
Expand Down Expand Up @@ -113,3 +114,9 @@ impl From<SequencerClientError> for jsonrpsee_types::error::ErrorObject<'static>
)
}
}

impl From<ProviderError> for OpEthApiError {
fn from(error: ProviderError) -> Self {
Self::Eth(error.into())
}
}
lakshya-sky marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 15 additions & 7 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,22 @@ where
N: FullNodeComponents,
{
type Transaction = Transaction;
type TransactionError = OpEthApiError;

fn fill(
&self,
tx: TransactionSignedEcRecovered,
tx_info: TransactionInfo,
) -> Self::Transaction {
) -> Result<Self::Transaction, Self::TransactionError> {
//let signed_tx = tx.clone().into_signed();
//let hash = tx.hash;
//
//let mut inner =
// EthTxBuilder.fill(tx, tx_info).expect("EthTxBuilder.fill should be infallible");
//
//if signed_tx.is_deposit() {
// inner.gas_price = Some(signed_tx.max_fee_per_gas())
//}
lakshya-sky marked this conversation as resolved.
Show resolved Hide resolved
let from = tx.signer();
let TransactionSigned { transaction, signature, hash } = tx.into_signed();

Expand All @@ -105,14 +115,12 @@ where
let deposit_receipt_version = self
.inner
.provider()
.receipt_by_hash(hash)
.ok() // todo: change sig to return result
.flatten()
.receipt_by_hash(hash)?
lakshya-sky marked this conversation as resolved.
Show resolved Hide resolved
.and_then(|receipt| receipt.deposit_receipt_version);

let TransactionInfo { block_hash, block_number, index: transaction_index, .. } = tx_info;

Transaction {
Ok(Transaction {
inner: alloy_rpc_types::Transaction {
inner,
block_hash,
Expand All @@ -121,7 +129,7 @@ where
from,
},
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
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 @@ -209,7 +209,7 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
tx.clone().with_signer(*signer),
tx_info,
self.tx_resp_builder(),
)))
)?))
}
}

Expand All @@ -234,7 +234,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 @@ -292,7 +292,7 @@ pub trait EthTransactions: LoadTransaction<Provider: BlockReaderIdExt> {
)
})
})
.ok_or(EthApiError::HeaderNotFound(block_id).into())
.ok_or(EthApiError::HeaderNotFound(block_id))?
.map(Some)
}
}
Expand Down
12 changes: 10 additions & 2 deletions crates/rpc/rpc-eth-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,21 @@ pub type RpcReceipt<T> = <T as Network>::ReceiptResponse;

/// 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>,
TransactionError = Self::Error,
>,
>
{
}

impl<T> FullEthApiTypes for T where
T: EthApiTypes<
TransactionCompat: TransactionCompat<Transaction = RpcTransaction<T::NetworkTypes>>,
TransactionCompat: TransactionCompat<
Transaction = RpcTransaction<T::NetworkTypes>,
TransactionError = T::Error,
>,
>
{
}
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::TransactionError> {
match self {
Self::Pool(tx) => from_recovered(tx, resp_builder),
Self::Block { transaction, index, block_hash, block_number, base_fee } => {
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc/rpc-types-compat/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ 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::TransactionError>>()
.expect("fill should be infallible");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this expect still needs to go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this one what do you think is the best idea? I was thinking to add TransactionCompatError inside alloy_rpc_eth::BlockError and maping the error to BlockError. Which would require making a pr to alloy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes indeed it does require a pr to alloy, you're right. suggest making a pr to alloy adding error variant BlockError::Custom(Box<dyn Error>) or BlockError::Custom(String) - would you please open the pr?

not to block this pr until next alloy release, let's log the error here, and would you please open an issue to propagate the error here instead when the alloy change is available.

Copy link
Member

@emhane emhane Nov 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually makes most sense to change the signature of from_block_full to return TransactionCompat::Error, and add trait bound From<BlockError> to the associated type


Ok(from_block_with_transactions(
block_length,
Expand Down
14 changes: 11 additions & 3 deletions crates/rpc/rpc-types-compat/src/transaction/mod.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::TransactionError> {
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::TransactionError> {
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 TransactionError: error::Error;
lakshya-sky marked this conversation as resolved.
Show resolved Hide resolved

/// 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::TransactionError>;

/// 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
8 changes: 4 additions & 4 deletions crates/rpc/rpc/src/eth/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,10 +625,10 @@ 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,
))
pending_txs.push(
from_recovered(tx.transaction.to_recovered_transaction(), &self.tx_resp_builder)
.expect("fill should be infallible"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this expect still needs to go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the expect and tried logging the error so that it doesn't become nightmare to propagate the error.(I tried propagating it first but requires changing a lot of types).

);
}
FilterChanges::Transactions(pending_txs)
}
Expand Down
7 changes: 5 additions & 2 deletions crates/rpc/rpc/src/eth/helpers/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use alloy_consensus::{Signed, TxEip4844Variant, TxEnvelope};
use alloy_network::{Ethereum, Network};
use alloy_rpc_types::{Transaction, TransactionInfo};
use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered};
use reth_rpc_eth_types::EthApiError;
use reth_rpc_types_compat::TransactionCompat;

/// Builds RPC transaction response for l1.
Expand All @@ -16,11 +17,13 @@ where
{
type Transaction = <Ethereum as Network>::TransactionResponse;

type TransactionError = EthApiError;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be the Infallible type right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can, and was initially set to infallible by @lakshya-sky . however it became complicated converting the error to an EthApiError and OpEthApiError in order to propagate it, it required explicit trait bounds for the conversion all over the place and got very messy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm, I see, I'm assuming it wasn't as easy as unwrapping when this was called at a higher level?


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

Expand All @@ -46,7 +49,7 @@ where

let TransactionInfo { block_hash, block_number, index: transaction_index, .. } = tx_info;

Transaction { inner, block_hash, block_number, transaction_index, from }
Ok(Transaction { inner, block_hash, block_number, transaction_index, from })
}

fn otterscan_api_truncate_input(tx: &mut Self::Transaction) {
Expand Down
11 changes: 7 additions & 4 deletions crates/rpc/rpc/src/eth/pubsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,13 @@ where
Params::Bool(true) => {
// full transaction objects requested
let stream = pubsub.full_pending_transaction_stream().map(|tx| {
EthSubscriptionResult::FullTransaction(Box::new(from_recovered(
tx.transaction.to_recovered_transaction(),
&tx_resp_builder,
)))
EthSubscriptionResult::FullTransaction(Box::new(
from_recovered(
tx.transaction.to_recovered_transaction(),
&tx_resp_builder,
)
.expect("fill should be infallible"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this expect still needs to go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also I've tried to log the error, otherwise it requires TransactionCompat::Error : Serialize + Send, which is something I don't know how to do.

))
});
return pipe_from_stream(accepted_sink, stream).await
}
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc/rpc/src/txpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ where
{
content.entry(tx.sender()).or_default().insert(
tx.nonce().to_string(),
from_recovered(tx.clone().into_consensus().into(), resp_builder),
from_recovered(tx.clone().into_consensus().into(), resp_builder)
.expect("fill should be infallible"),
emhane marked this conversation as resolved.
Show resolved Hide resolved
);
}

Expand Down
Loading