mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix: handle optimism deposit transactions on SenderRecovery stage (#7376)
This commit is contained in:
@ -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.
|
||||
|
||||
@ -9,7 +9,6 @@ use reth_db::{
|
||||
};
|
||||
use reth_interfaces::consensus;
|
||||
use reth_primitives::{
|
||||
keccak256,
|
||||
stage::{EntitiesCheckpoint, StageCheckpoint, StageId},
|
||||
Address, PruneSegment, StaticFileSegment, TransactionSignedNoHash, TxNumber,
|
||||
};
|
||||
@ -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))
|
||||
|
||||
Reference in New Issue
Block a user