chore: add alloy-compat for signature and transaction (#8197)

This commit is contained in:
Vid Kersic
2024-05-15 09:00:17 +02:00
committed by GitHub
parent 2e2c8e1d63
commit aa5c52b944
2 changed files with 64 additions and 39 deletions

View File

@ -1,8 +1,8 @@
//! Common conversions from alloy types.
use crate::{
Block, Header, Transaction, TransactionSigned, TxEip1559, TxEip2930, TxEip4844, TxLegacy,
TxType,
transaction::extract_chain_id, Block, Header, Signature, Transaction, TransactionSigned,
TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844, TxLegacy, TxType,
};
use alloy_primitives::TxKind;
use alloy_rlp::Error as RlpError;
@ -115,7 +115,7 @@ impl TryFrom<alloy_rpc_types::Transaction> for Transaction {
return Err(ConversionError::Eip2718Error(
RlpError::Custom("EIP-1559 fields are present in a legacy transaction")
.into(),
))
));
}
Ok(Transaction::Legacy(TxLegacy {
chain_id: tx.chain_id,
@ -199,3 +199,64 @@ impl TryFrom<alloy_rpc_types::Transaction> for Transaction {
}
}
}
impl TryFrom<alloy_rpc_types::Transaction> for TransactionSigned {
type Error = alloy_rpc_types::ConversionError;
fn try_from(tx: alloy_rpc_types::Transaction) -> Result<Self, Self::Error> {
use alloy_rpc_types::ConversionError;
let signature = tx.signature.ok_or(ConversionError::MissingSignature)?;
let transaction: Transaction = tx.try_into()?;
Ok(TransactionSigned::from_transaction_and_signature(
transaction.clone(),
Signature {
r: signature.r,
s: signature.s,
odd_y_parity: if let Some(y_parity) = signature.y_parity {
y_parity.0
} else {
match transaction.tx_type() {
// If the transaction type is Legacy, adjust the v component of the
// signature according to the Ethereum specification
TxType::Legacy => {
extract_chain_id(signature.v.to())
.map_err(|_| ConversionError::InvalidSignature)?
.0
}
_ => !signature.v.is_zero(),
}
},
},
))
}
}
impl TryFrom<alloy_rpc_types::Transaction> for TransactionSignedEcRecovered {
type Error = alloy_rpc_types::ConversionError;
fn try_from(tx: alloy_rpc_types::Transaction) -> Result<Self, Self::Error> {
use alloy_rpc_types::ConversionError;
let transaction: TransactionSigned = tx.try_into()?;
transaction.try_into_ecrecovered().map_err(|_| ConversionError::InvalidSignature)
}
}
impl TryFrom<alloy_rpc_types::Signature> for Signature {
type Error = alloy_rpc_types::ConversionError;
fn try_from(signature: alloy_rpc_types::Signature) -> Result<Self, Self::Error> {
use alloy_rpc_types::ConversionError;
let odd_y_parity = if let Some(y_parity) = signature.y_parity {
y_parity.0
} else {
extract_chain_id(signature.v.to()).map_err(|_| ConversionError::InvalidSignature)?.0
};
Ok(Self { r: signature.r, s: signature.s, odd_y_parity })
}
}

View File

@ -1615,42 +1615,6 @@ impl IntoRecoveredTransaction for TransactionSignedEcRecovered {
}
}
#[cfg(feature = "alloy-compat")]
impl TryFrom<alloy_rpc_types::Transaction> for TransactionSignedEcRecovered {
type Error = alloy_rpc_types::ConversionError;
fn try_from(tx: alloy_rpc_types::Transaction) -> Result<Self, Self::Error> {
use alloy_rpc_types::ConversionError;
let signature = tx.signature.ok_or(ConversionError::MissingSignature)?;
let transaction: Transaction = tx.try_into()?;
TransactionSigned::from_transaction_and_signature(
transaction.clone(),
Signature {
r: signature.r,
s: signature.s,
odd_y_parity: if let Some(y_parity) = signature.y_parity {
y_parity.0
} else {
match transaction.tx_type() {
// If the transaction type is Legacy, adjust the v component of the
// signature according to the Ethereum specification
TxType::Legacy => {
extract_chain_id(signature.v.to())
.map_err(|_| ConversionError::InvalidSignature)?
.0
}
_ => !signature.v.is_zero(),
}
},
},
)
.try_into_ecrecovered()
.map_err(|_| ConversionError::InvalidSignature)
}
}
#[cfg(test)]
mod tests {
use crate::{