diff --git a/Cargo.toml b/Cargo.toml index 92cead9ea36..cb18c4019e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,11 +70,11 @@ alloy-transport-ipc = { version = "0.5", path = "crates/transport-ipc", default- alloy-transport-ws = { version = "0.5", path = "crates/transport-ws", default-features = false } alloy-eip5792 = { version = "0.5", path = "crates/eip5792", default-features = false } -alloy-core = { version = "0.8.5", default-features = false } -alloy-dyn-abi = { version = "0.8.5", default-features = false } -alloy-json-abi = { version = "0.8.5", default-features = false } -alloy-primitives = { version = "0.8.5", default-features = false } -alloy-sol-types = { version = "0.8.5", default-features = false } +alloy-core = { version = "0.8.11", default-features = false } +alloy-dyn-abi = { version = "0.8.11", default-features = false } +alloy-json-abi = { version = "0.8.11", default-features = false } +alloy-primitives = { version = "0.8.11", default-features = false } +alloy-sol-types = { version = "0.8.11", default-features = false } alloy-rlp = { version = "0.3.9", default-features = false } @@ -82,7 +82,7 @@ alloy-chains = { version = "0.1.18", default-features = false } # eips alloy-eip2930 = { version = "0.1.0", default-features = false } -alloy-eip7702 = { version = "0.3.2", default-features = false } +alloy-eip7702 = { version = "0.4", default-features = false } # ethereum ethereum_ssz_derive = "0.8" diff --git a/crates/consensus/src/encodable_signature.rs b/crates/consensus/src/encodable_signature.rs deleted file mode 100644 index 02d8a434421..00000000000 --- a/crates/consensus/src/encodable_signature.rs +++ /dev/null @@ -1,108 +0,0 @@ -use alloy_primitives::{Parity, SignatureError, U256}; - -/// Helper trait used to streamline signatures encoding. -pub trait EncodableSignature: Sized { - /// Instantiate from v, r, s. - fn from_rs_and_parity, E: Into>( - r: U256, - s: U256, - parity: P, - ) -> Result; - - /// Returns the `r` component of this signature. - fn r(&self) -> U256; - - /// Returns the `s` component of this signature. - fn s(&self) -> U256; - - /// Returns the recovery ID as a `u8`. - fn v(&self) -> Parity; - - /// Sets the recovery ID by normalizing a `v` value. - fn with_parity>(self, parity: T) -> Self; - - /// Modifies the recovery ID by applying [EIP-155] to a `v` value. - /// - /// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155 - #[inline] - fn with_chain_id(self, chain_id: u64) -> Self - where - Self: Copy, - { - self.with_parity(self.v().with_chain_id(chain_id)) - } - - /// Modifies the recovery ID by dropping any [EIP-155] v value, converting - /// to a simple parity bool. - fn with_parity_bool(self) -> Self - where - Self: Copy, - { - self.with_parity(self.v().to_parity_bool()) - } - - /// Decode an RLP-encoded VRS signature. - fn decode_rlp_vrs(buf: &mut &[u8]) -> Result { - use alloy_rlp::Decodable; - - let parity: Parity = Decodable::decode(buf)?; - let r = Decodable::decode(buf)?; - let s = Decodable::decode(buf)?; - - Self::from_rs_and_parity(r, s, parity) - .map_err(|_| alloy_rlp::Error::Custom("attempted to decode invalid field element")) - } - - /// Length of RLP RS field encoding - fn rlp_rs_len(&self) -> usize { - alloy_rlp::Encodable::length(&self.r()) + alloy_rlp::Encodable::length(&self.s()) - } - - /// Length of RLP V field encoding - fn rlp_vrs_len(&self) -> usize { - self.rlp_rs_len() + alloy_rlp::Encodable::length(&self.v()) - } - - /// Write R and S to an RLP buffer in progress. - fn write_rlp_rs(&self, out: &mut dyn alloy_rlp::BufMut) { - alloy_rlp::Encodable::encode(&self.r(), out); - alloy_rlp::Encodable::encode(&self.s(), out); - } - - /// Write the V to an RLP buffer without using EIP-155. - fn write_rlp_v(&self, out: &mut dyn alloy_rlp::BufMut) { - alloy_rlp::Encodable::encode(&self.v(), out); - } - - /// Write the VRS to the output. The V will always be 27 or 28. - fn write_rlp_vrs(&self, out: &mut dyn alloy_rlp::BufMut) { - self.write_rlp_v(out); - self.write_rlp_rs(out); - } -} - -impl EncodableSignature for alloy_primitives::Signature { - fn from_rs_and_parity, E: Into>( - r: U256, - s: U256, - parity: P, - ) -> Result { - Self::from_rs_and_parity(r, s, parity) - } - - fn r(&self) -> U256 { - self.r() - } - - fn s(&self) -> U256 { - self.s() - } - - fn v(&self) -> Parity { - self.v() - } - - fn with_parity>(self, parity: T) -> Self { - self.with_parity(parity) - } -} diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index a722ad43415..55ddaf145ea 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -18,9 +18,6 @@ pub use block::{AnyHeader, Block, BlockBody, BlockHeader, Header}; pub mod constants; pub use constants::{EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; -mod encodable_signature; -pub use encodable_signature::EncodableSignature; - mod receipt; pub use receipt::{ AnyReceiptEnvelope, Eip658Value, Receipt, ReceiptEnvelope, ReceiptWithBloom, Receipts, diff --git a/crates/consensus/src/signed.rs b/crates/consensus/src/signed.rs index 3ab12128fe2..3fe0c90424e 100644 --- a/crates/consensus/src/signed.rs +++ b/crates/consensus/src/signed.rs @@ -1,6 +1,6 @@ use crate::transaction::{RlpEcdsaTx, SignableTransaction}; use alloy_eips::eip2718::Eip2718Result; -use alloy_primitives::{Signature, B256}; +use alloy_primitives::{PrimitiveSignature as Signature, B256}; use alloy_rlp::BufMut; /// A transaction with a signature and hash seal. @@ -17,12 +17,22 @@ pub struct Signed { } impl Signed { + /// Instantiate from a transaction and signature. Does not verify the signature. + pub const fn new_unchecked(tx: T, signature: Sig, hash: B256) -> Self { + Self { tx, signature, hash } + } + /// Returns a reference to the transaction. #[doc(alias = "transaction")] pub const fn tx(&self) -> &T { &self.tx } + /// Returns a mutable reference to the transaction. + pub fn tx_mut(&mut self) -> &mut T { + &mut self.tx + } + /// Returns a reference to the signature. pub const fn signature(&self) -> &Sig { &self.signature @@ -46,11 +56,6 @@ impl Signed { } impl, Sig> Signed { - /// Instantiate from a transaction and signature. Does not verify the signature. - pub const fn new_unchecked(tx: T, signature: Sig, hash: B256) -> Self { - Self { tx, signature, hash } - } - /// Calculate the signing hash for the transaction. pub fn signature_hash(&self) -> B256 { self.tx.signature_hash() diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index e71ef3373be..db417ba6a52 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -1,6 +1,6 @@ use crate::{transaction::RlpEcdsaTx, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; -use alloy_primitives::{Bytes, ChainId, Signature, TxKind, B256, U256}; +use alloy_primitives::{Bytes, ChainId, PrimitiveSignature as Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable}; use core::mem; @@ -248,10 +248,6 @@ impl SignableTransaction for TxEip1559 { } fn into_signed(self, signature: Signature) -> Signed { - // Drop any v chain id value to ensure the signature format is correct at the time of - // combination for an EIP-1559 transaction. V should indicate the y-parity of the - // signature. - let signature = signature.with_parity_bool(); let tx_hash = self.tx_hash(&signature); Signed::new_unchecked(self, signature, tx_hash) } @@ -398,7 +394,9 @@ mod tests { use super::TxEip1559; use crate::{transaction::RlpEcdsaTx, SignableTransaction}; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{address, b256, hex, Address, Signature, B256, U256}; + use alloy_primitives::{ + address, b256, hex, Address, PrimitiveSignature as Signature, B256, U256, + }; #[test] fn recover_signer_eip1559() { @@ -421,8 +419,7 @@ mod tests { b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), false, - ) - .unwrap(); + ); assert_eq!( tx.signature_hash(), @@ -454,8 +451,7 @@ mod tests { b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), false, - ) - .unwrap(); + ); let mut buf = vec![]; tx.rlp_encode_signed(&sig, &mut buf); diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index 67dbbbeeefc..4b243fc8b17 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -1,6 +1,6 @@ use crate::{SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; -use alloy_primitives::{Bytes, ChainId, Signature, TxKind, B256, U256}; +use alloy_primitives::{Bytes, ChainId, PrimitiveSignature as Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable}; use core::mem; @@ -198,10 +198,6 @@ impl SignableTransaction for TxEip2930 { } fn into_signed(self, signature: Signature) -> Signed { - // Drop any v chain id value to ensure the signature format is correct - // at the time of combination for an EIP-2930 transaction. V should - // indicate the y-parity of the signature. - let signature = signature.with_parity_bool(); let tx_hash = self.tx_hash(&signature); Signed::new_unchecked(self, signature, tx_hash) } @@ -227,7 +223,7 @@ impl Decodable for TxEip2930 { mod tests { use super::TxEip2930; use crate::{transaction::RlpEcdsaTx, SignableTransaction, TxEnvelope}; - use alloy_primitives::{Address, Signature, TxKind, U256}; + use alloy_primitives::{Address, PrimitiveSignature as Signature, TxKind, U256}; use alloy_rlp::{Decodable, Encodable}; #[test] diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index 7df9c6994d8..8e0c948ed58 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -2,7 +2,9 @@ use crate::{SignableTransaction, Signed, Transaction, TxType}; use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB, eip7702::SignedAuthorization}; -use alloy_primitives::{Address, Bytes, ChainId, Signature, TxKind, B256, U256}; +use alloy_primitives::{ + Address, Bytes, ChainId, PrimitiveSignature as Signature, TxKind, B256, U256, +}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; @@ -345,11 +347,6 @@ impl SignableTransaction for TxEip4844Variant { } fn into_signed(self, signature: Signature) -> Signed { - // Drop any v chain id value to ensure the signature format is correct at the time of - // combination for an EIP-4844 transaction. V should indicate the y-parity of the - // signature. - let signature = signature.with_parity_bool(); - let hash = self.tx_hash(&signature); Signed::new_unchecked(self, signature, hash) @@ -567,10 +564,6 @@ impl SignableTransaction for TxEip4844 { } fn into_signed(self, signature: Signature) -> Signed { - // Drop any v chain id value to ensure the signature format is correct at the time of - // combination for an EIP-4844 transaction. V should indicate the y-parity of the - // signature. - let signature = signature.with_parity_bool(); let hash = self.tx_hash(&signature); Signed::new_unchecked(self, signature, hash) } @@ -753,11 +746,6 @@ impl SignableTransaction for TxEip4844WithSidecar { } fn into_signed(self, signature: Signature) -> Signed { - // Drop any v chain id value to ensure the signature format is correct at the time of - // combination for an EIP-4844 transaction. V should indicate the y-parity of the - // signature. - let signature = signature.with_parity_bool(); - // important: must hash the tx WITHOUT the sidecar let hash = self.tx_hash(&signature); @@ -885,7 +873,7 @@ mod tests { use super::{BlobTransactionSidecar, TxEip4844, TxEip4844WithSidecar}; use crate::{transaction::eip4844::TxEip4844Variant, SignableTransaction, TxEnvelope}; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{address, b256, bytes, Signature, U256}; + use alloy_primitives::{address, b256, bytes, PrimitiveSignature as Signature, U256}; use alloy_rlp::{Decodable, Encodable}; #[test] @@ -969,12 +957,11 @@ mod tests { input: bytes!("701f58c50000000000000000000000000000000000000000000000000000000000073fb1ed12e288def5b439ea074b398dbb4c967f2852baac3238c5fe4b62b871a59a6d00000000000000000000000000000000000000000000000000000000123971da000000000000000000000000000000000000000000000000000000000000000ac39b2a24e1dbdd11a1e7bd7c0f4dfd7d9b9cfa0997d033ad05f961ba3b82c6c83312c967f10daf5ed2bffe309249416e03ee0b101f2b84d2102b9e38b0e4dfdf0000000000000000000000000000000000000000000000000000000066254c8b538dcc33ecf5334bbd294469f9d4fd084a3090693599a46d6c62567747cbc8660000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000073fb20000000000000000000000000000000000000000000000000000000066254da10000000000000000000000000000000000000000000000000000000012397d5e20b09b263779fda4171c341e720af8fa469621ff548651f8dbbc06c2d320400c000000000000000000000000000000000000000000000000000000000000000b50a833bb11af92814e99c6ff7cf7ba7042827549d6f306a04270753702d897d8fc3c411b99159939ac1c16d21d3057ddc8b2333d1331ab34c938cff0eb29ce2e43241c170344db6819f76b1f1e0ab8206f3ec34120312d275c4f5bbea7f5c55700000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000031800000000000000000000000000000000000000000000800b0000000000000000000000000000000000000000000000000000000000000004ed12e288def5b439ea074b398dbb4c967f2852baac3238c5fe4b62b871a59a6d00000ca8000000000000000000000000000000000000800b000000000000000000000000000000000000000000000000000000000000000300000000000000000000000066254da100000000000000000000000066254e9d00010ca80000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000550a833bb11af92814e99c6ff7cf7ba7042827549d6f306a04270753702d897d800010ca800000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000b00010ca8000000000000000000000000000000000000801100000000000000000000000000000000000000000000000000000000000000075c1cd5bd0fd333ce9d7c8edfc79f43b8f345b4a394f6aba12a2cc78ce4012ed700010ca80000000000000000000000000000000000008011000000000000000000000000000000000000000000000000000000000000000845392775318aa47beaafbdc827da38c9f1e88c3bdcabba2cb493062e17cbf21e00010ca800000000000000000000000000000000000080080000000000000000000000000000000000000000000000000000000000000000c094e20e7ac9b433f44a5885e3bdc07e51b309aeb993caa24ba84a661ac010c100010ca800000000000000000000000000000000000080080000000000000000000000000000000000000000000000000000000000000001ab42db8f4ed810bdb143368a2b641edf242af6e3d0de8b1486e2b0e7880d431100010ca8000000000000000000000000000000000000800800000000000000000000000000000000000000000000000000000000000000022d94e4cc4525e4e2d81e8227b6172e97076431a2cf98792d978035edd6e6f3100000000000000000000000000000000000000000000000000000000000000000000000000000012101c74dfb80a80fccb9a4022b2406f79f56305e6a7c931d30140f5d372fe793837e93f9ec6b8d89a9d0ab222eeb27547f66b90ec40fbbdd2a4936b0b0c19ca684ff78888fbf5840d7c8dc3c493b139471750938d7d2c443e2d283e6c5ee9fde3765a756542c42f002af45c362b4b5b1687a8fc24cbf16532b903f7bb289728170dcf597f5255508c623ba247735538376f494cdcdd5bd0c4cb067526eeda0f4745a28d8baf8893ecc1b8cee80690538d66455294a028da03ff2add9d8a88e6ee03ba9ffe3ad7d91d6ac9c69a1f28c468f00fe55eba5651a2b32dc2458e0d14b4dd6d0173df255cd56aa01e8e38edec17ea8933f68543cbdc713279d195551d4211bed5c91f77259a695e6768f6c4b110b2158fcc42423a96dcc4e7f6fddb3e2369d00000000000000000000000000000000000000000000000000000000000000") }; let variant = TxEip4844Variant::TxEip4844(tx); - let signature = Signature::from_rs_and_parity( + let signature = Signature::new( b256!("6c173c3c8db3e3299f2f728d293b912c12e75243e3aa66911c2329b58434e2a4").into(), b256!("7dd4d1c228cedc5a414a668ab165d9e888e61e4c3b44cd7daf9cdcc4cec5d6b2").into(), false, - ) - .unwrap(); + ); let signed = variant.into_signed(signature); assert_eq!( diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index d428166b116..3de7ebdc708 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -4,7 +4,9 @@ use alloy_eips::{ eip2930::AccessList, eip7702::{constants::EIP7702_TX_TYPE_ID, SignedAuthorization}, }; -use alloy_primitives::{Address, Bytes, ChainId, Signature, TxKind, B256, U256}; +use alloy_primitives::{ + Address, Bytes, ChainId, PrimitiveSignature as Signature, TxKind, B256, U256, +}; use alloy_rlp::{BufMut, Decodable, Encodable}; use core::mem; @@ -244,10 +246,6 @@ impl SignableTransaction for TxEip7702 { } fn into_signed(self, signature: Signature) -> Signed { - // Drop any v chain id value to ensure the signature format is correct at the time of - // combination for an EIP-7702 transaction. V should indicate the y-parity of the - // signature. - let signature = signature.with_parity_bool(); let tx_hash = self.tx_hash(&signature); Signed::new_unchecked(self, signature, tx_hash) @@ -397,7 +395,7 @@ mod tests { use super::*; use crate::SignableTransaction; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{address, b256, hex, Address, Signature, U256}; + use alloy_primitives::{address, b256, hex, Address, PrimitiveSignature as Signature, U256}; #[test] fn encode_decode_eip7702() { @@ -418,8 +416,7 @@ mod tests { b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), false, - ) - .unwrap(); + ); let mut buf = vec![]; tx.rlp_encode_signed(&sig, &mut buf); @@ -446,8 +443,7 @@ mod tests { b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), false, - ) - .unwrap(); + ); let mut buf = vec![]; tx.rlp_encode_signed(&sig, &mut buf); let decoded = TxEip7702::rlp_decode_signed(&mut &buf[..]).unwrap(); @@ -473,8 +469,7 @@ mod tests { b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), false, - ) - .unwrap(); + ); let mut buf = vec![]; tx.rlp_encode_signed(&sig, &mut buf); diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 417cb552955..9af4c1a5d27 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -201,8 +201,10 @@ impl TxEnvelope { /// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155 #[inline] pub const fn is_replay_protected(&self) -> bool { - let Self::Legacy(ref tx) = self else { return true }; - tx.signature().v().chain_id().is_some() + match self { + Self::Legacy(tx) => tx.tx().chain_id.is_some(), + _ => true, + } } /// Returns the [`TxLegacy`] variant if the transaction is a legacy transaction. @@ -555,7 +557,7 @@ mod serde_from { Untagged { #[serde(default, rename = "type", deserialize_with = "alloy_serde::reject_if_some")] _ty: Option<()>, - #[serde(flatten)] + #[serde(flatten, with = "crate::transaction::signed_legacy_serde")] tx: Signed, }, } @@ -563,7 +565,7 @@ mod serde_from { #[derive(Debug, serde::Serialize, serde::Deserialize)] #[serde(tag = "type")] pub(crate) enum TaggedTxEnvelope { - #[serde(rename = "0x0", alias = "0x00")] + #[serde(rename = "0x0", alias = "0x00", with = "crate::transaction::signed_legacy_serde")] Legacy(Signed), #[serde(rename = "0x1", alias = "0x01")] Eip2930(Signed), @@ -621,7 +623,7 @@ mod tests { }; #[allow(unused_imports)] use alloy_primitives::{b256, Bytes, TxKind}; - use alloy_primitives::{hex, Address, Parity, Signature, U256}; + use alloy_primitives::{hex, Address, PrimitiveSignature as Signature, U256}; use std::{fs, path::PathBuf, str::FromStr, vec}; #[test] @@ -656,8 +658,8 @@ mod tests { .is_replay_protected()); let r = b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"); let s = b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"); - let v = 27; - let valid_sig = Signature::from_scalars_and_parity(r, s, v).unwrap(); + let v = false; + let valid_sig = Signature::from_scalars_and_parity(r, s, v); assert!(!&TxEnvelope::Legacy(Signed::new_unchecked( TxLegacy::default(), valid_sig, @@ -786,10 +788,7 @@ mod tests { value: U256::from(7_u64), ..Default::default() }; - test_encode_decode_roundtrip( - tx, - Some(Signature::test_signature().with_parity(Parity::NonEip155(true))), - ); + test_encode_decode_roundtrip(tx, Some(Signature::test_signature().with_parity(true))); } #[test] @@ -821,7 +820,7 @@ mod tests { input: vec![8].into(), access_list: Default::default(), }; - let signature = Signature::test_signature().with_parity(Parity::Eip155(42)); + let signature = Signature::test_signature().with_parity(true); test_encode_decode_roundtrip(tx, Some(signature)); } @@ -838,7 +837,7 @@ mod tests { input: vec![7].into(), access_list: Default::default(), }; - let signature = Signature::test_signature().with_parity(Parity::Eip155(42)); + let signature = Signature::test_signature().with_parity(true); test_encode_decode_roundtrip(tx, Some(signature)); } @@ -860,7 +859,7 @@ mod tests { blob_versioned_hashes: vec![B256::random()], max_fee_per_blob_gas: 0, }; - let signature = Signature::test_signature().with_parity(Parity::Eip155(42)); + let signature = Signature::test_signature().with_parity(true); test_encode_decode_roundtrip(tx, Some(signature)); } @@ -888,7 +887,7 @@ mod tests { proofs: vec![[4; 48].into()], }; let tx = TxEip4844WithSidecar { tx, sidecar }; - let signature = Signature::test_signature().with_parity(Parity::Eip155(42)); + let signature = Signature::test_signature().with_parity(true); let tx_signed = tx.into_signed(signature); let tx_envelope: TxEnvelope = tx_signed.into(); @@ -921,7 +920,7 @@ mod tests { max_fee_per_blob_gas: 0, }; let tx = TxEip4844Variant::TxEip4844(tx); - let signature = Signature::test_signature().with_parity(Parity::Eip155(42)); + let signature = Signature::test_signature().with_parity(true); test_encode_decode_roundtrip(tx, Some(signature)); } diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index 518e697dc19..7d9f41f3d6b 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -1,21 +1,12 @@ use crate::{transaction::RlpEcdsaTx, SignableTransaction, Signed, Transaction, TxType}; use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; -use alloy_primitives::{keccak256, Bytes, ChainId, Parity, Signature, TxKind, B256, U256}; +use alloy_primitives::{ + keccak256, Bytes, ChainId, PrimitiveSignature as Signature, TxKind, B256, U256, +}; 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))] @@ -137,18 +128,23 @@ impl RlpEcdsaTx for TxLegacy { self.input.0.encode(out); } + fn rlp_header_signed(&self, signature: &Signature) -> Header { + let payload_length = self.rlp_encoded_fields_length() + + signature.rlp_rs_len() + + to_eip155_value(signature.v(), self.chain_id).length(); + Header { list: true, payload_length } + } + 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); self.rlp_header_signed(signature).length_with_payload() } 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); + signature.write_rlp_vrs(out, to_eip155_value(signature.v(), self.chain_id)); } fn eip2718_encoded_length(&self, signature: &Signature) -> usize { @@ -191,13 +187,13 @@ impl RlpEcdsaTx for TxLegacy { let remaining = buf.len(); let mut tx = Self::rlp_decode_fields(buf)?; - let signature = Signature::decode_rlp_vrs(buf)?; - - if !matches!(signature.v(), Parity::Eip155(_) | Parity::NonEip155(_)) { - return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); - } - - tx.chain_id = signature.v().chain_id(); + let signature = Signature::decode_rlp_vrs(buf, |buf| { + let value = u64::decode(buf)?; + let (parity, chain_id) = + from_eip155_value(value).ok_or(alloy_rlp::Error::Custom("invalid parity value"))?; + tx.chain_id = chain_id; + Ok(parity) + })?; if buf.len() + header.payload_length != remaining { return Err(alloy_rlp::Error::ListLengthMismatch { @@ -297,10 +293,6 @@ impl Transaction for TxLegacy { } impl SignableTransaction for TxLegacy { - fn use_eip155(&self) -> bool { - self.chain_id.is_some() - } - fn set_chain_id(&mut self, chain_id: ChainId) { self.chain_id = Some(chain_id); } @@ -322,13 +314,6 @@ impl SignableTransaction for TxLegacy { } fn into_signed(self, signature: Signature) -> Signed { - // Enforce correct parity for legacy transactions (EIP-155, 27 or 28). - let signature = if let Parity::Parity(parity) = signature.v() { - signature.with_parity(Parity::NonEip155(parity)) - } else { - signature - }; - let hash = self.tx_hash(&signature); Signed::new_unchecked(self, signature, hash) } @@ -375,6 +360,133 @@ impl Decodable for TxLegacy { } } +/// Helper for encoding `y_parity` boolean and optional `chain_id` into EIP-155 `v` value. +pub const fn to_eip155_value(y_parity: bool, chain_id: Option) -> u64 { + match chain_id { + Some(id) => 35 + id * 2 + y_parity as u64, + None => 27 + y_parity as u64, + } +} + +/// Helper for decoding EIP-155 `v` value into `y_parity` boolean and optional `chain_id`. +pub const fn from_eip155_value(value: u64) -> Option<(bool, Option)> { + match value { + 27 => Some((false, None)), + 28 => Some((true, None)), + v @ 35.. => Some((((v - 35) % 2) != 0, Some((v - 35) / 2))), + _ => None, + } +} + +#[cfg(feature = "serde")] +pub mod signed_legacy_serde { + //! Helper module for encoding signatures of transactions wrapped into [`Signed`] in legacy + //! format. + //! + //! By default, signatures are encoded as a single boolean under `yParity` key. However, for + //! legacy transactions parity byte is encoded as `v` key respecting EIP-155 format. + use super::*; + use alloc::borrow::Cow; + use alloy_primitives::U64; + use serde::{Deserialize, Serialize}; + + struct LegacySignature { + r: U256, + s: U256, + v: U64, + } + + #[derive(Serialize, Deserialize)] + struct HumanReadableRepr { + r: U256, + s: U256, + v: U64, + } + + #[derive(Serialize, Deserialize)] + #[serde(transparent)] + struct NonHumanReadableRepr((U256, U256, U64)); + + impl Serialize for LegacySignature { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + HumanReadableRepr { r: self.r, s: self.s, v: self.v }.serialize(serializer) + } else { + NonHumanReadableRepr((self.r, self.s, self.v)).serialize(serializer) + } + } + } + + impl<'de> Deserialize<'de> for LegacySignature { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + if deserializer.is_human_readable() { + HumanReadableRepr::deserialize(deserializer).map(|repr| Self { + r: repr.r, + s: repr.s, + v: repr.v, + }) + } else { + NonHumanReadableRepr::deserialize(deserializer).map(|repr| Self { + r: repr.0 .0, + s: repr.0 .1, + v: repr.0 .2, + }) + } + } + } + + #[derive(Serialize, Deserialize)] + struct SignedLegacy<'a> { + #[serde(flatten)] + tx: Cow<'a, TxLegacy>, + #[serde(flatten)] + signature: LegacySignature, + hash: B256, + } + + /// Serializes signed transaction with `v` key for signature parity. + pub fn serialize(signed: &crate::Signed, serializer: S) -> Result + where + S: serde::Serializer, + { + SignedLegacy { + tx: Cow::Borrowed(signed.tx()), + signature: LegacySignature { + v: U64::from(to_eip155_value(signed.signature().v(), signed.tx().chain_id())), + r: signed.signature().r(), + s: signed.signature().s(), + }, + hash: *signed.hash(), + } + .serialize(serializer) + } + + /// Deserializes signed transaction expecting `v` key for signature parity. + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: serde::Deserializer<'de>, + { + let SignedLegacy { tx, signature, hash } = SignedLegacy::deserialize(deserializer)?; + let (parity, chain_id) = from_eip155_value(signature.v.to::()) + .ok_or_else(|| serde::de::Error::custom("invalid EIP-155 signature parity value"))?; + if let Some(tx_chain_id) = tx.chain_id() { + // Some nodes respond with 0 chain ID for legacy transactions when it is missing. + if tx_chain_id > 0 && chain_id != Some(tx_chain_id) { + return Err(serde::de::Error::custom("chain id mismatch")); + } + } + let mut tx = tx.into_owned(); + tx.chain_id = chain_id; + Ok(Signed::new_unchecked(tx, Signature::new(signature.r, signature.s, parity), hash)) + } +} + /// Bincode-compatible [`TxLegacy`] serde implementation. #[cfg(all(feature = "serde", feature = "serde-bincode-compat"))] pub(super) mod serde_bincode_compat { @@ -492,7 +604,9 @@ pub(super) mod serde_bincode_compat { #[cfg(all(test, feature = "k256"))] mod tests { use crate::{SignableTransaction, TxLegacy}; - use alloy_primitives::{address, b256, hex, Address, Signature, TxKind, B256, U256}; + use alloy_primitives::{ + address, b256, hex, Address, PrimitiveSignature as Signature, TxKind, B256, U256, + }; #[test] fn recover_signer_legacy() { @@ -513,9 +627,8 @@ mod tests { let sig = Signature::from_scalars_and_parity( b256!("2a378831cf81d99a3f06a18ae1b6ca366817ab4d88a70053c41d7a8f0368e031"), b256!("450d831a05b6e418724436c05c155e0a1b7b921015d0fbc2f667aed709ac4fb5"), - 37, - ) - .unwrap(); + false, + ); let signed_tx = tx.into_signed(sig); diff --git a/crates/consensus/src/transaction/mod.rs b/crates/consensus/src/transaction/mod.rs index a9a5c491f8a..0b08528b1e6 100644 --- a/crates/consensus/src/transaction/mod.rs +++ b/crates/consensus/src/transaction/mod.rs @@ -30,7 +30,7 @@ mod envelope; pub use envelope::{TxEnvelope, TxType}; mod legacy; -pub use legacy::TxLegacy; +pub use legacy::{from_eip155_value, to_eip155_value, TxLegacy}; mod rlp; #[doc(hidden)] @@ -39,6 +39,9 @@ pub use rlp::RlpEcdsaTx; mod typed; pub use typed::TypedTransaction; +#[cfg(feature = "serde")] +pub use legacy::signed_legacy_serde; + /// Bincode-compatible serde implementations for transaction types. #[cfg(all(feature = "serde", feature = "serde-bincode-compat"))] pub mod serde_bincode_compat { @@ -155,11 +158,6 @@ pub trait Transaction: fmt::Debug + any::Any + Send + Sync + 'static { /// unit type `()`. #[doc(alias = "SignableTx", alias = "TxSignable")] pub trait SignableTransaction: Transaction { - /// True if the transaction uses EIP-155 signatures. - fn use_eip155(&self) -> bool { - false - } - /// Sets `chain_id`. /// /// Prefer [`set_chain_id_checked`](Self::set_chain_id_checked). diff --git a/crates/consensus/src/transaction/rlp.rs b/crates/consensus/src/transaction/rlp.rs index b3656696867..f459bc0c1dc 100644 --- a/crates/consensus/src/transaction/rlp.rs +++ b/crates/consensus/src/transaction/rlp.rs @@ -1,8 +1,8 @@ use crate::{SignableTransaction, Signed}; use alloc::vec::Vec; use alloy_eips::eip2718::{Eip2718Error, Eip2718Result}; -use alloy_primitives::{keccak256, Parity, Signature, TxHash}; -use alloy_rlp::{Buf, BufMut, Header}; +use alloy_primitives::{keccak256, PrimitiveSignature as Signature, TxHash}; +use alloy_rlp::{Buf, BufMut, Decodable, Encodable, Header}; /// Helper trait for managing RLP encoding of transactions inside 2718 /// envelopes. @@ -37,7 +37,8 @@ pub trait RlpEcdsaTx: SignableTransaction + Sized { /// Create an rlp list header for the signed transaction. fn rlp_header_signed(&self, signature: &Signature) -> Header { - let payload_length = self.rlp_encoded_fields_length() + signature.rlp_vrs_len(); + let payload_length = + self.rlp_encoded_fields_length() + signature.rlp_rs_len() + signature.v().length(); Header { list: true, payload_length } } @@ -51,7 +52,7 @@ pub trait RlpEcdsaTx: SignableTransaction + Sized { fn rlp_encode_signed(&self, signature: &Signature, out: &mut dyn BufMut) { self.rlp_header_signed(signature).encode(out); self.rlp_encode_fields(out); - signature.write_rlp_vrs(out); + signature.write_rlp_vrs(out, signature.v()); } /// Get the length of the transaction when EIP-2718 encoded. This is the @@ -133,13 +134,7 @@ pub trait RlpEcdsaTx: SignableTransaction + Sized { let remaining = buf.len(); let tx = Self::rlp_decode_fields(buf)?; - let signature = Signature::decode_rlp_vrs(buf)?; - - if !matches!(signature.v(), Parity::Parity(_)) { - return Err(alloy_rlp::Error::Custom( - "invalid parity for non-legacy typed transaction", - )); - } + let signature = Signature::decode_rlp_vrs(buf, bool::decode)?; if buf.len() + header.payload_length != remaining { return Err(alloy_rlp::Error::ListLengthMismatch { diff --git a/crates/network/src/ethereum/builder.rs b/crates/network/src/ethereum/builder.rs index 6850a42ac44..d4a6b02f7e7 100644 --- a/crates/network/src/ethereum/builder.rs +++ b/crates/network/src/ethereum/builder.rs @@ -173,7 +173,7 @@ mod tests { }; use alloy_consensus::{BlobTransactionSidecar, TxEip1559, TxType, TypedTransaction}; use alloy_eips::eip7702::Authorization; - use alloy_primitives::{Address, Signature}; + use alloy_primitives::{Address, PrimitiveSignature as Signature}; use alloy_rpc_types_eth::{AccessList, TransactionRequest}; use std::str::FromStr; diff --git a/crates/network/src/ethereum/wallet.rs b/crates/network/src/ethereum/wallet.rs index 98f234f0860..045f9643add 100644 --- a/crates/network/src/ethereum/wallet.rs +++ b/crates/network/src/ethereum/wallet.rs @@ -1,7 +1,6 @@ use crate::{Network, NetworkWallet, TxSigner}; use alloy_consensus::{SignableTransaction, TxEnvelope, TypedTransaction}; -use alloy_primitives::{map::AddressHashMap, Address}; -use alloy_signer::Signature; +use alloy_primitives::{map::AddressHashMap, Address, PrimitiveSignature as Signature}; use std::sync::Arc; /// A wallet capable of signing any transaction for the Ethereum network. diff --git a/crates/rpc-types-txpool/src/txpool.rs b/crates/rpc-types-txpool/src/txpool.rs index b0bd5a773a0..2207a86c794 100644 --- a/crates/rpc-types-txpool/src/txpool.rs +++ b/crates/rpc-types-txpool/src/txpool.rs @@ -213,6 +213,7 @@ mod tests { "transactionIndex": null, "value": "0x0", "type": "0x2", + "v": "0x0", "accessList": [], "chainId": "0x1", "yParity": "0x0", @@ -235,7 +236,7 @@ mod tests { "value": "0x0", "type": "0x0", "chainId": "0x1", - "yParity": "0x0", + "v": "0x25", "r": "0xaf46b2c0f067f7d1d63ac19daa349c0e1eb83f019ee00542ffa7095e05352e92", "s": "0x21d6d24d58ec361379ffffe4cc17bec8ce2b9f5f9759a91afc9a54dfdfa519c2" } @@ -255,6 +256,7 @@ mod tests { "transactionIndex": null, "value": "0x0", "type": "0x2", + "v": "0x0", "accessList": [], "chainId": "0x1", "yParity": "0x0", @@ -279,6 +281,7 @@ mod tests { "transactionIndex": null, "value": "0x1f58a57c1794eb", "type": "0x2", + "v": "0x0", "accessList": [], "chainId": "0x1", "yParity": "0x0", @@ -301,6 +304,7 @@ mod tests { "transactionIndex": null, "value": "0x0", "type": "0x2", + "v": "0x0", "accessList": [], "chainId": "0x1", "yParity": "0x0", @@ -321,6 +325,7 @@ mod tests { "transactionIndex": null, "value": "0x0", "type": "0x2", + "v": "0x1", "accessList": [], "chainId": "0x1", "yParity": "0x1", @@ -343,6 +348,7 @@ mod tests { "transactionIndex": null, "value": "0x0", "type": "0x2", + "v": "0x0", "accessList": [], "chainId": "0x1", "yParity": "0x0", diff --git a/crates/signer-aws/src/signer.rs b/crates/signer-aws/src/signer.rs index fbb9b7f7109..42f6307a717 100644 --- a/crates/signer-aws/src/signer.rs +++ b/crates/signer-aws/src/signer.rs @@ -1,6 +1,6 @@ use alloy_consensus::SignableTransaction; -use alloy_primitives::{hex, Address, ChainId, B256}; -use alloy_signer::{sign_transaction_with_chain_id, Result, Signature, Signer}; +use alloy_primitives::{hex, Address, ChainId, PrimitiveSignature as Signature, B256}; +use alloy_signer::{sign_transaction_with_chain_id, Result, Signer}; use async_trait::async_trait; use aws_sdk_kms::{ error::SdkError, @@ -180,11 +180,7 @@ impl AwsSigner { #[instrument(err, skip(digest), fields(digest = %hex::encode(digest)))] async fn sign_digest_inner(&self, digest: &B256) -> Result { let sig = self.sign_digest(digest).await?; - let mut sig = sig_from_digest_bytes_trial_recovery(sig, digest, &self.pubkey); - if let Some(chain_id) = self.chain_id { - sig = sig.with_chain_id(chain_id); - } - Ok(sig) + Ok(sig_from_digest_bytes_trial_recovery(sig, digest, &self.pubkey)) } } @@ -233,7 +229,7 @@ fn sig_from_digest_bytes_trial_recovery( hash: &B256, pubkey: &VerifyingKey, ) -> Signature { - let signature = Signature::from_signature_and_parity(sig, false).unwrap(); + let signature = Signature::from_signature_and_parity(sig, false); if check_candidate(&signature, hash, pubkey) { return signature; } diff --git a/crates/signer-gcp/src/signer.rs b/crates/signer-gcp/src/signer.rs index 6bf6c3273bc..a621d191e98 100644 --- a/crates/signer-gcp/src/signer.rs +++ b/crates/signer-gcp/src/signer.rs @@ -1,6 +1,6 @@ use alloy_consensus::SignableTransaction; -use alloy_primitives::{hex, Address, ChainId, B256}; -use alloy_signer::{sign_transaction_with_chain_id, Result, Signature, Signer}; +use alloy_primitives::{hex, Address, ChainId, PrimitiveSignature as Signature, B256}; +use alloy_signer::{sign_transaction_with_chain_id, Result, Signer}; use async_trait::async_trait; use gcloud_sdk::{ google::cloud::kms::{ @@ -220,11 +220,7 @@ impl GcpSigner { #[instrument(err, skip(digest), fields(digest = %hex::encode(digest)))] async fn sign_digest_inner(&self, digest: &B256) -> Result { let sig = self.sign_digest(digest).await?; - let mut sig = sig_from_digest_bytes_trial_recovery(sig, digest, &self.pubkey); - if let Some(chain_id) = self.chain_id { - sig = sig.with_chain_id(chain_id); - } - Ok(sig) + Ok(sig_from_digest_bytes_trial_recovery(sig, digest, &self.pubkey)) } } @@ -281,7 +277,7 @@ fn sig_from_digest_bytes_trial_recovery( hash: &B256, pubkey: &VerifyingKey, ) -> Signature { - let signature = Signature::from_signature_and_parity(sig, false).unwrap(); + let signature = Signature::from_signature_and_parity(sig, false); if check_candidate(&signature, hash, pubkey) { return signature; } diff --git a/crates/signer-ledger/src/signer.rs b/crates/signer-ledger/src/signer.rs index a373c96d7c8..2709a1be225 100644 --- a/crates/signer-ledger/src/signer.rs +++ b/crates/signer-ledger/src/signer.rs @@ -2,8 +2,10 @@ use crate::types::{DerivationType, LedgerError, INS, P1, P1_FIRST, P2}; use alloy_consensus::SignableTransaction; -use alloy_primitives::{hex, Address, ChainId, B256}; -use alloy_signer::{sign_transaction_with_chain_id, Result, Signature, Signer}; +use alloy_primitives::{ + hex, normalize_v, Address, ChainId, PrimitiveSignature as Signature, SignatureError, B256, +}; +use alloy_signer::{sign_transaction_with_chain_id, Result, Signer}; use async_trait::async_trait; use coins_ledger::{ common::{APDUCommand, APDUData}, @@ -313,7 +315,9 @@ impl LedgerSigner { return Err(LedgerError::ShortResponse { got: data.len(), expected: 65 }); } - let sig = Signature::from_bytes_and_parity(&data[1..], data[0] as u64)?; + let parity = normalize_v(data[0] as u64) + .ok_or(LedgerError::SignatureError(SignatureError::InvalidParity(data[0] as u64)))?; + let sig = Signature::from_bytes_and_parity(&data[1..], parity); debug!(?sig, "Received signature from device"); Ok(sig) } diff --git a/crates/signer-local/src/lib.rs b/crates/signer-local/src/lib.rs index a9a7f3e25a5..f6d171f2b6b 100644 --- a/crates/signer-local/src/lib.rs +++ b/crates/signer-local/src/lib.rs @@ -8,7 +8,7 @@ use alloy_consensus::SignableTransaction; use alloy_network::{TxSigner, TxSignerSync}; -use alloy_primitives::{Address, ChainId, Signature, B256}; +use alloy_primitives::{Address, ChainId, PrimitiveSignature as Signature, B256}; use alloy_signer::{sign_transaction_with_chain_id, Result, Signer, SignerSync}; use async_trait::async_trait; use k256::ecdsa::{self, signature::hazmat::PrehashSigner, RecoveryId}; @@ -118,8 +118,7 @@ impl + Send + Sync> Signer for impl> SignerSync for LocalSigner { #[inline] fn sign_hash_sync(&self, hash: &B256) -> Result { - let (recoverable_sig, recovery_id) = self.credential.sign_prehash(hash.as_ref())?; - Ok(Signature::from_signature_and_parity(recoverable_sig, recovery_id)?) + Ok(self.credential.sign_prehash(hash.as_ref())?.into()) } #[inline] diff --git a/crates/signer-trezor/src/signer.rs b/crates/signer-trezor/src/signer.rs index ba6afbdb34c..7418f4949d9 100644 --- a/crates/signer-trezor/src/signer.rs +++ b/crates/signer-trezor/src/signer.rs @@ -1,7 +1,10 @@ use super::types::{DerivationType, TrezorError}; use alloy_consensus::{SignableTransaction, TxEip1559}; -use alloy_primitives::{hex, Address, ChainId, Parity, TxKind, B256, U256}; -use alloy_signer::{sign_transaction_with_chain_id, Result, Signature, Signer}; +use alloy_primitives::{ + hex, normalize_v, Address, ChainId, PrimitiveSignature as Signature, SignatureError, TxKind, + B256, U256, +}; +use alloy_signer::{sign_transaction_with_chain_id, Result, Signer}; use async_trait::async_trait; use std::fmt; use trezor_client::client::Trezor; @@ -275,8 +278,9 @@ fn address_to_trezor(x: &Address) -> String { fn signature_from_trezor(x: trezor_client::client::Signature) -> Result { let r = U256::from_be_bytes(x.r); let s = U256::from_be_bytes(x.s); - let v = Parity::Eip155(x.v); - Signature::from_rs_and_parity(r, s, v).map_err(Into::into) + let v = + normalize_v(x.v).ok_or(TrezorError::SignatureError(SignatureError::InvalidParity(x.v)))?; + Ok(Signature::new(r, s, v)) } #[cfg(test)] diff --git a/crates/signer/src/lib.rs b/crates/signer/src/lib.rs index 3f5e45ee864..b22f13655b6 100644 --- a/crates/signer/src/lib.rs +++ b/crates/signer/src/lib.rs @@ -27,8 +27,6 @@ macro_rules! sign_transaction_with_chain_id { // sign: lazy Signature, // ) ($signer:expr, $tx:expr, $sign:expr) => {{ - use alloy_consensus::EncodableSignature; - if let Some(chain_id) = $signer.chain_id() { if !$tx.set_chain_id_checked(chain_id) { return Err(alloy_signer::Error::TransactionChainIdMismatch { @@ -39,14 +37,6 @@ macro_rules! sign_transaction_with_chain_id { } } - let mut sig = $sign.map_err(alloy_signer::Error::other)?; - - if $tx.use_eip155() { - if let Some(chain_id) = $signer.chain_id().or_else(|| $tx.chain_id()) { - sig = sig.with_chain_id(chain_id); - } - } - - Ok(sig) + $sign.map_err(alloy_signer::Error::other) }}; } diff --git a/crates/signer/src/signer.rs b/crates/signer/src/signer.rs index bd3ebd657c1..c4c6cae0935 100644 --- a/crates/signer/src/signer.rs +++ b/crates/signer/src/signer.rs @@ -1,5 +1,7 @@ use crate::Result; -use alloy_primitives::{eip191_hash_message, Address, ChainId, Signature, B256}; +use alloy_primitives::{ + eip191_hash_message, Address, ChainId, PrimitiveSignature as Signature, B256, +}; use async_trait::async_trait; use auto_impl::auto_impl;