feat: add extract_chain_id method (#7921)

This commit is contained in:
Darshan Kathiriya
2024-04-29 15:48:05 -04:00
committed by GitHub
parent 55017ef028
commit 0819780027
2 changed files with 25 additions and 21 deletions

View File

@ -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(),
}

View File

@ -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};