From cc6f5343f90889739e1bd251cac6677648d1a7c8 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 18 Oct 2024 21:00:27 -0400 Subject: [PATCH] fix: correct handling of legacy signatures when encoding (#1510) --- crates/consensus/src/transaction/legacy.rs | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index 37b466f5055..47a39ba658e 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -5,6 +5,17 @@ use alloy_primitives::{keccak256, Bytes, ChainId, Parity, Signature, TxKind, B25 use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header, Result}; use core::mem; +/// Enforce correct parity for legacy transactions (EIP-155, 27 or 28). +macro_rules! legacy_sig { + ($signature:expr) => { + if let Parity::Parity(parity) = $signature.v() { + &$signature.with_parity(Parity::NonEip155(parity)) + } else { + $signature + } + }; +} + /// Legacy transaction. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] @@ -124,6 +135,21 @@ impl RlpEcdsaTx for TxLegacy { self.input.0.encode(out); } + fn rlp_encoded_length_with_signature(&self, signature: &Signature) -> usize { + // Enforce correct parity for legacy transactions (EIP-155, 27 or 28). + let signature = legacy_sig!(signature); + let header = self.rlp_header_signed(&signature); + header.length() + header.payload_length + } + + fn rlp_encode_signed(&self, signature: &Signature, out: &mut dyn BufMut) { + // Enforce correct parity for legacy transactions (EIP-155, 27 or 28). + let signature = legacy_sig!(signature); + self.rlp_header_signed(signature).encode(out); + self.rlp_encode_fields(out); + signature.write_rlp_vrs(out); + } + fn eip2718_encoded_length(&self, signature: &Signature) -> usize { self.rlp_encoded_length_with_signature(signature) }