diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs
index 9702ae19eb4d..8d86794db3e8 100644
--- a/crates/primitives/src/transaction/mod.rs
+++ b/crates/primitives/src/transaction/mod.rs
@@ -992,6 +992,22 @@ impl TransactionSigned {
self.signature.recover_signer(signature_hash)
}
+ /// Recover signer from signature and hash _without ensuring that the signature has a low `s`
+ /// value_.
+ ///
+ /// Returns `None` if the transaction's signature is invalid, see also
+ /// [Self::recover_signer_unchecked].
+ pub fn recover_signer_unchecked(&self) -> Option
{
+ // Optimism's Deposit transaction does not have a signature. Directly return the
+ // `from` address.
+ #[cfg(feature = "optimism")]
+ if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction {
+ return Some(from)
+ }
+ let signature_hash = self.signature_hash();
+ self.signature.recover_signer_unchecked(signature_hash)
+ }
+
/// Recovers a list of signers from a transaction list iterator
///
/// Returns `None`, if some transaction's signature is invalid, see also
diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs
index af0966162afb..ec98b9cf8c0e 100644
--- a/crates/rpc/rpc/src/eth/api/transactions.rs
+++ b/crates/rpc/rpc/src/eth/api/transactions.rs
@@ -1146,15 +1146,20 @@ impl From for Transaction {
}
/// Helper function to construct a transaction receipt
+///
+/// Note: This requires _all_ block receipts because we need to calculate the gas used by the
+/// transaction.
pub(crate) fn build_transaction_receipt_with_block_receipts(
- tx: TransactionSigned,
+ transaction: TransactionSigned,
meta: TransactionMeta,
receipt: Receipt,
all_receipts: &[Receipt],
#[cfg(feature = "optimism")] optimism_tx_meta: OptimismTxMeta,
) -> EthResult {
- let transaction =
- tx.clone().into_ecrecovered().ok_or(EthApiError::InvalidTransactionSignature)?;
+ // Note: we assume this transaction is valid, because it's mined (or part of pending block) and
+ // we don't need to check for pre EIP-2
+ let from =
+ transaction.recover_signer_unchecked().ok_or(EthApiError::InvalidTransactionSignature)?;
// get the previous transaction cumulative gas used
let gas_used = if meta.index == 0 {
@@ -1173,14 +1178,14 @@ pub(crate) fn build_transaction_receipt_with_block_receipts(
transaction_index: U64::from(meta.index),
block_hash: Some(meta.block_hash),
block_number: Some(U256::from(meta.block_number)),
- from: transaction.signer(),
+ from,
to: None,
cumulative_gas_used: U256::from(receipt.cumulative_gas_used),
gas_used: Some(U256::from(gas_used)),
contract_address: None,
logs: Vec::with_capacity(receipt.logs.len()),
effective_gas_price: U128::from(transaction.effective_gas_price(meta.base_fee)),
- transaction_type: tx.transaction.tx_type().into(),
+ transaction_type: transaction.transaction.tx_type().into(),
// TODO pre-byzantium receipts have a post-transaction state root
state_root: None,
logs_bloom: receipt.bloom_slow(),
@@ -1196,7 +1201,7 @@ pub(crate) fn build_transaction_receipt_with_block_receipts(
#[cfg(feature = "optimism")]
if let Some(l1_block_info) = optimism_tx_meta.l1_block_info {
- if !tx.is_deposit() {
+ if !transaction.is_deposit() {
res_receipt.l1_fee = optimism_tx_meta.l1_fee;
res_receipt.l1_gas_used =
optimism_tx_meta.l1_data_gas.map(|dg| dg + l1_block_info.l1_fee_overhead);
@@ -1206,10 +1211,9 @@ pub(crate) fn build_transaction_receipt_with_block_receipts(
}
}
- match tx.transaction.kind() {
+ match transaction.transaction.kind() {
Create => {
- res_receipt.contract_address =
- Some(transaction.signer().create(tx.transaction.nonce()));
+ res_receipt.contract_address = Some(from.create(transaction.transaction.nonce()));
}
Call(addr) => {
res_receipt.to = Some(*addr);