mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add extract_chain_id method (#7921)
This commit is contained in:
committed by
GitHub
parent
55017ef028
commit
0819780027
@ -32,7 +32,7 @@ pub use sidecar::generate_blob_sidecar;
|
||||
#[cfg(feature = "c-kzg")]
|
||||
pub use sidecar::{BlobTransaction, BlobTransactionSidecar, BlobTransactionValidationError};
|
||||
|
||||
pub use signature::Signature;
|
||||
pub use signature::{extract_chain_id, Signature};
|
||||
pub use tx_type::{
|
||||
TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID,
|
||||
};
|
||||
@ -1740,18 +1740,9 @@ impl TryFrom<reth_rpc_types::Transaction> for TransactionSignedEcRecovered {
|
||||
// If the transaction type is Legacy, adjust the v component of the
|
||||
// signature according to the Ethereum specification
|
||||
TxType::Legacy => {
|
||||
// Calculate the new v value based on the EIP-155 formula:
|
||||
// v = {0,1} + CHAIN_ID * 2 + 35
|
||||
!(signature.v -
|
||||
U256::from(if let Some(chain_id) = transaction.chain_id() {
|
||||
// If CHAIN_ID is available, calculate the new v value
|
||||
// accordingly
|
||||
chain_id.saturating_mul(2).saturating_add(35)
|
||||
} else {
|
||||
// If CHAIN_ID is not available, set v = {0,1} + 27
|
||||
27
|
||||
}))
|
||||
.is_zero()
|
||||
extract_chain_id(signature.v.to())
|
||||
.map_err(|_| ConversionError::InvalidSignature)?
|
||||
.0
|
||||
}
|
||||
_ => !signature.v.is_zero(),
|
||||
}
|
||||
|
||||
@ -114,16 +114,11 @@ impl Signature {
|
||||
if v == 0 && r.is_zero() && s.is_zero() {
|
||||
return Ok((Self { r, s, odd_y_parity: false }, None))
|
||||
}
|
||||
return Err(RlpError::Custom("invalid Ethereum signature (V is not 27 or 28)"))
|
||||
}
|
||||
let odd_y_parity = v == 28;
|
||||
Ok((Self { r, s, odd_y_parity }, None))
|
||||
} else {
|
||||
// EIP-155: v = {0, 1} + CHAIN_ID * 2 + 35
|
||||
let odd_y_parity = ((v - 35) % 2) != 0;
|
||||
let chain_id = (v - 35) >> 1;
|
||||
Ok((Self { r, s, odd_y_parity }, Some(chain_id)))
|
||||
}
|
||||
|
||||
let (odd_y_parity, chain_id) = extract_chain_id(v)?;
|
||||
Ok((Self { r, s, odd_y_parity }, chain_id))
|
||||
}
|
||||
|
||||
/// Output the length of the signature without the length of the RLP header
|
||||
@ -201,6 +196,24 @@ impl Signature {
|
||||
}
|
||||
}
|
||||
|
||||
/// Outputs (odd_y_parity, chain_id) from the `v` value.
|
||||
/// This doesn't check validity of the `v` value for optimism.
|
||||
#[inline]
|
||||
pub fn extract_chain_id(v: u64) -> alloy_rlp::Result<(bool, Option<u64>)> {
|
||||
if v < 35 {
|
||||
// non-EIP-155 legacy scheme, v = 27 for even y-parity, v = 28 for odd y-parity
|
||||
if v != 27 && v != 28 {
|
||||
return Err(RlpError::Custom("invalid Ethereum signature (V is not 27 or 28)"))
|
||||
}
|
||||
Ok((v == 28, None))
|
||||
} else {
|
||||
// EIP-155: v = {0, 1} + CHAIN_ID * 2 + 35
|
||||
let odd_y_parity = ((v - 35) % 2) != 0;
|
||||
let chain_id = (v - 35) >> 1;
|
||||
Ok((odd_y_parity, Some(chain_id)))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{transaction::signature::SECP256K1N_HALF, Address, Signature, B256, U256};
|
||||
|
||||
Reference in New Issue
Block a user