Skip to content

Commit

Permalink
fix: handle optimism deposit transactions on SenderRecovery stage (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
joshieDo authored Mar 29, 2024
1 parent 79e15b1 commit 8b88306
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
29 changes: 29 additions & 0 deletions crates/primitives/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,10 +856,39 @@ impl TransactionSignedNoHash {
///
/// Returns `None` if the transaction's signature is invalid, see also [Self::recover_signer].
pub fn recover_signer(&self) -> Option<Address> {
// 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(signature_hash)
}

/// Recover signer from signature and hash _without ensuring that the signature has a low `s`
/// value_.
///
/// Re-uses a given buffer to avoid numerous reallocations when recovering batches. **Clears the
/// buffer before use.**
///
/// Returns `None` if the transaction's signature is invalid, see also
/// [Signature::recover_signer_unchecked].
pub fn encode_and_recover_unchecked(&self, buffer: &mut Vec<u8>) -> Option<Address> {
buffer.clear();
self.transaction.encode_without_signature(buffer);

// 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)
}

self.signature.recover_signer_unchecked(keccak256(buffer))
}

/// Converts into a transaction type with its hash: [`TransactionSigned`].
///
/// Note: This will recalculate the hash of the transaction.
Expand Down
6 changes: 1 addition & 5 deletions crates/stages/src/stages/sender_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use reth_db::{
};
use reth_interfaces::consensus;
use reth_primitives::{
keccak256,
stage::{EntitiesCheckpoint, StageCheckpoint, StageId},
Address, PruneSegment, StaticFileSegment, TransactionSignedNoHash, TxNumber,
};
Expand Down Expand Up @@ -229,16 +228,13 @@ fn recover_sender(
(tx_id, tx): (TxNumber, TransactionSignedNoHash),
rlp_buf: &mut Vec<u8>,
) -> Result<(u64, Address), Box<SenderRecoveryStageError>> {
tx.transaction.encode_without_signature(rlp_buf);

// We call [Signature::recover_signer_unchecked] because transactions run in the pipeline are
// known to be valid - this means that we do not need to check whether or not the `s` value is
// greater than `secp256k1n / 2` if past EIP-2. There are transactions pre-homestead which have
// large `s` values, so using [Signature::recover_signer] here would not be
// backwards-compatible.
let sender = tx
.signature
.recover_signer_unchecked(keccak256(rlp_buf))
.encode_and_recover_unchecked(rlp_buf)
.ok_or(SenderRecoveryStageError::FailedRecovery(FailedSenderRecoveryError { tx: tx_id }))?;

Ok((tx_id, sender))
Expand Down

0 comments on commit 8b88306

Please sign in to comment.