refactor(tx_wrapper): Use derive(TransactionEnvelope)

This commit is contained in:
sprites0
2025-07-03 04:01:42 +00:00
parent 0bdd9080d1
commit 12d7d5a8b4
5 changed files with 100 additions and 200 deletions

View File

@ -130,7 +130,7 @@ impl FromRecoveredTx<TransactionSigned> for HlTxEnv<TxEnv> {
impl FromTxWithEncoded<TransactionSigned> for HlTxEnv<TxEnv> { impl FromTxWithEncoded<TransactionSigned> for HlTxEnv<TxEnv> {
fn from_encoded_tx(tx: &TransactionSigned, sender: Address, _encoded: Bytes) -> Self { fn from_encoded_tx(tx: &TransactionSigned, sender: Address, _encoded: Bytes) -> Self {
let base = match tx.clone().0.into_typed_transaction() { let base = match tx.clone().into_inner().into_typed_transaction() {
reth_primitives::Transaction::Legacy(tx) => TxEnv::from_recovered_tx(&tx, sender), reth_primitives::Transaction::Legacy(tx) => TxEnv::from_recovered_tx(&tx, sender),
reth_primitives::Transaction::Eip2930(tx) => TxEnv::from_recovered_tx(&tx, sender), reth_primitives::Transaction::Eip2930(tx) => TxEnv::from_recovered_tx(&tx, sender),
reth_primitives::Transaction::Eip1559(tx) => TxEnv::from_recovered_tx(&tx, sender), reth_primitives::Transaction::Eip1559(tx) => TxEnv::from_recovered_tx(&tx, sender),

View File

@ -139,7 +139,7 @@ where
inner: BlockBody { inner: BlockBody {
transactions: transactions transactions: transactions
.into_transactions() .into_transactions()
.map(|tx| TransactionSigned(tx.inner.into_inner().into())) .map(|tx| TransactionSigned::Default(tx.inner.into_inner().into()))
.collect(), .collect(),
ommers: Default::default(), ommers: Default::default(),
withdrawals, withdrawals,

View File

@ -1,18 +1,13 @@
//! HlNodePrimitives::TransactionSigned; it's the same as ethereum transaction type, //! HlNodePrimitives::TransactionSigned; it's the same as ethereum transaction type,
//! except that it supports pseudo signer for system transactions. //! except that it supports pseudo signer for system transactions.
use std::hash::Hasher;
use alloy_consensus::{ use alloy_consensus::{
crypto::RecoveryError, EthereumTxEnvelope, Signed, Transaction as TransactionTrait, TxEip1559, crypto::RecoveryError, error::ValueError, EthereumTxEnvelope, SignableTransaction, Signed,
TxEip2930, TxEip4844, TxEip4844WithSidecar, TxEip7702, TxEnvelope, TxLegacy, TxType, Transaction as TransactionTrait, TransactionEnvelope, TxEip1559, TxEip2930, TxEip4844,
TypedTransaction, TxEip4844WithSidecar, TxEip7702, TxLegacy, TxType, TypedTransaction,
}; };
use alloy_eips::{ use alloy_eips::{eip7594::BlobTransactionSidecarVariant, Encodable2718};
eip2718::Eip2718Result, eip7594::BlobTransactionSidecarVariant, eip7702::SignedAuthorization, use alloy_primitives::{address, Address, TxHash, U256};
Decodable2718, Encodable2718, Typed2718, use alloy_rpc_types::{Transaction, TransactionInfo, TransactionRequest};
};
use alloy_primitives::{address, Address, Bytes, TxHash, TxKind, Uint, B256, U256};
use alloy_rpc_types::AccessList;
use alloy_signer::Signature; use alloy_signer::Signature;
use reth_codecs::alloy::transaction::FromTxCompact; use reth_codecs::alloy::transaction::FromTxCompact;
use reth_db::{ use reth_db::{
@ -24,13 +19,22 @@ use reth_primitives::Recovered;
use reth_primitives_traits::{ use reth_primitives_traits::{
serde_bincode_compat::SerdeBincodeCompat, InMemorySize, SignedTransaction, SignerRecoverable, serde_bincode_compat::SerdeBincodeCompat, InMemorySize, SignedTransaction, SignerRecoverable,
}; };
use revm::context::TxEnv; use reth_rpc_eth_api::{
use serde::{Deserialize, Deserializer, Serialize, Serializer}; transaction::{FromConsensusTx, TryIntoTxEnv},
EthTxEnvError, TryIntoSimTx,
};
use revm::context::{BlockEnv, CfgEnv, TxEnv};
use crate::evm::transaction::HlTxEnv;
type InnerType = alloy_consensus::EthereumTxEnvelope<TxEip4844>; type InnerType = alloy_consensus::EthereumTxEnvelope<TxEip4844>;
#[derive(Debug, Clone, Eq)] #[derive(Debug, Clone, TransactionEnvelope)]
pub struct TransactionSigned(pub InnerType); #[envelope(tx_type_name = HlTxType)]
pub enum TransactionSigned {
#[envelope(flatten)]
Default(InnerType),
}
fn s_to_address(s: U256) -> Address { fn s_to_address(s: U256) -> Address {
if s == U256::ONE { if s == U256::ONE {
@ -46,20 +50,20 @@ impl SignerRecoverable for TransactionSigned {
if self.is_system_transaction() { if self.is_system_transaction() {
return Ok(s_to_address(self.signature().s())); return Ok(s_to_address(self.signature().s()));
} }
self.0.recover_signer() self.inner().recover_signer()
} }
fn recover_signer_unchecked(&self) -> Result<Address, RecoveryError> { fn recover_signer_unchecked(&self) -> Result<Address, RecoveryError> {
if self.is_system_transaction() { if self.is_system_transaction() {
return Ok(s_to_address(self.signature().s())); return Ok(s_to_address(self.signature().s()));
} }
self.0.recover_signer_unchecked() self.inner().recover_signer_unchecked()
} }
} }
impl SignedTransaction for TransactionSigned { impl SignedTransaction for TransactionSigned {
fn tx_hash(&self) -> &TxHash { fn tx_hash(&self) -> &TxHash {
self.0.tx_hash() self.inner().tx_hash()
} }
fn recover_signer_unchecked_with_buf( fn recover_signer_unchecked_with_buf(
@ -69,8 +73,7 @@ impl SignedTransaction for TransactionSigned {
if self.is_system_transaction() { if self.is_system_transaction() {
return Ok(s_to_address(self.signature().s())); return Ok(s_to_address(self.signature().s()));
} }
self.inner().recover_signer_unchecked_with_buf(buf)
self.0.recover_signer_unchecked_with_buf(buf)
} }
} }
@ -78,30 +81,12 @@ impl SignedTransaction for TransactionSigned {
// NOTE: All lines below are just wrappers for the inner type. // NOTE: All lines below are just wrappers for the inner type.
// ------------------------------------------------------------ // ------------------------------------------------------------
impl Serialize for TransactionSigned {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for TransactionSigned {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self(InnerType::deserialize(deserializer)?))
}
}
macro_rules! impl_from_signed { macro_rules! impl_from_signed {
($($tx:ident),*) => { ($($tx:ident),*) => {
$( $(
impl From<Signed<$tx>> for TransactionSigned { impl From<Signed<$tx>> for TransactionSigned {
fn from(value: Signed<$tx>) -> Self { fn from(value: Signed<$tx>) -> Self {
Self(value.into()) Self::Default(value.into())
} }
} }
)* )*
@ -113,139 +98,7 @@ impl_from_signed!(TxLegacy, TxEip2930, TxEip1559, TxEip7702, TypedTransaction);
impl InMemorySize for TransactionSigned { impl InMemorySize for TransactionSigned {
#[inline] #[inline]
fn size(&self) -> usize { fn size(&self) -> usize {
self.0.size() self.inner().size()
}
}
impl alloy_rlp::Encodable for TransactionSigned {
fn encode(&self, out: &mut dyn alloy_rlp::bytes::BufMut) {
self.0.encode(out);
}
fn length(&self) -> usize {
self.0.length()
}
}
impl alloy_rlp::Decodable for TransactionSigned {
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
Ok(Self(TxEnvelope::decode(buf)?.into()))
}
}
impl Encodable2718 for TransactionSigned {
fn type_flag(&self) -> Option<u8> {
self.0.type_flag()
}
fn encode_2718_len(&self) -> usize {
self.0.encode_2718_len()
}
fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) {
self.0.encode_2718(out)
}
}
impl Decodable2718 for TransactionSigned {
fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result<Self> {
Ok(Self(TxEnvelope::typed_decode(ty, buf)?.into()))
}
fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result<Self> {
Ok(Self(TxEnvelope::fallback_decode(buf)?.into()))
}
}
impl Typed2718 for TransactionSigned {
fn ty(&self) -> u8 {
self.0.ty()
}
}
impl PartialEq for TransactionSigned {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl core::hash::Hash for TransactionSigned {
fn hash<H: Hasher>(&self, state: &mut H) {
core::hash::Hash::hash(&self.0, state);
}
}
impl TransactionTrait for TransactionSigned {
fn chain_id(&self) -> Option<u64> {
self.0.chain_id()
}
fn nonce(&self) -> u64 {
self.0.nonce()
}
fn gas_limit(&self) -> u64 {
self.0.gas_limit()
}
fn gas_price(&self) -> Option<u128> {
self.0.gas_price()
}
fn max_fee_per_gas(&self) -> u128 {
self.0.max_fee_per_gas()
}
fn max_priority_fee_per_gas(&self) -> Option<u128> {
self.0.max_priority_fee_per_gas()
}
fn max_fee_per_blob_gas(&self) -> Option<u128> {
self.0.max_fee_per_blob_gas()
}
fn priority_fee_or_price(&self) -> u128 {
self.0.priority_fee_or_price()
}
fn effective_gas_price(&self, base_fee: Option<u64>) -> u128 {
self.0.effective_gas_price(base_fee)
}
fn effective_tip_per_gas(&self, base_fee: u64) -> Option<u128> {
self.0.effective_tip_per_gas(base_fee)
}
fn is_dynamic_fee(&self) -> bool {
self.0.is_dynamic_fee()
}
fn kind(&self) -> TxKind {
self.0.kind()
}
fn is_create(&self) -> bool {
self.0.is_create()
}
fn value(&self) -> Uint<256, 4> {
self.0.value()
}
fn input(&self) -> &Bytes {
self.0.input()
}
fn access_list(&self) -> Option<&AccessList> {
self.0.access_list()
}
fn blob_versioned_hashes(&self) -> Option<&[B256]> {
self.0.blob_versioned_hashes()
}
fn authorization_list(&self) -> Option<&[SignedAuthorization]> {
self.0.authorization_list()
} }
} }
@ -254,23 +107,23 @@ impl reth_codecs::Compact for TransactionSigned {
where where
B: bytes::BufMut + AsMut<[u8]>, B: bytes::BufMut + AsMut<[u8]>,
{ {
self.0.to_compact(buf) self.inner().to_compact(buf)
} }
fn from_compact(buf: &[u8], _len: usize) -> (Self, &[u8]) { fn from_compact(buf: &[u8], _len: usize) -> (Self, &[u8]) {
let (tx, hash) = InnerType::from_compact(buf, _len); let (tx, hash) = InnerType::from_compact(buf, _len);
(Self(tx), hash) (Self::Default(tx), hash)
} }
} }
pub fn convert_recovered(value: Recovered<TransactionSigned>) -> Recovered<InnerType> { pub fn convert_recovered(value: Recovered<TransactionSigned>) -> Recovered<InnerType> {
let (tx, signer) = value.into_parts(); let (tx, signer) = value.into_parts();
Recovered::new_unchecked(tx.0, signer) Recovered::new_unchecked(tx.into_inner(), signer)
} }
impl FromRecoveredTx<TransactionSigned> for TxEnv { impl FromRecoveredTx<TransactionSigned> for TxEnv {
fn from_recovered_tx(tx: &TransactionSigned, sender: Address) -> Self { fn from_recovered_tx(tx: &TransactionSigned, sender: Address) -> Self {
TxEnv::from_recovered_tx(&tx.0, sender) TxEnv::from_recovered_tx(&tx.inner(), sender)
} }
} }
@ -282,27 +135,41 @@ impl FromTxCompact for TransactionSigned {
Self: Sized, Self: Sized,
{ {
let (tx, buf) = InnerType::from_tx_compact(buf, tx_type, signature); let (tx, buf) = InnerType::from_tx_compact(buf, tx_type, signature);
(Self(tx), buf) (Self::Default(tx), buf)
} }
} }
impl reth_codecs::alloy::transaction::Envelope for TransactionSigned { impl reth_codecs::alloy::transaction::Envelope for TransactionSigned {
fn signature(&self) -> &Signature { fn signature(&self) -> &Signature {
self.0.signature() self.inner().signature()
} }
fn tx_type(&self) -> Self::TxType { fn tx_type(&self) -> Self::TxType {
self.0.tx_type() self.inner().tx_type()
} }
} }
impl TransactionSigned { impl TransactionSigned {
pub const fn signature(&self) -> &Signature { #[inline]
self.0.signature() pub fn into_inner(self) -> InnerType {
match self {
Self::Default(tx) => tx,
}
}
#[inline]
pub const fn inner(&self) -> &InnerType {
match self {
Self::Default(tx) => tx,
}
}
pub fn signature(&self) -> &Signature {
self.inner().signature()
} }
pub const fn tx_type(&self) -> TxType { pub const fn tx_type(&self) -> TxType {
self.0.tx_type() self.inner().tx_type()
} }
pub fn is_system_transaction(&self) -> bool { pub fn is_system_transaction(&self) -> bool {
@ -329,7 +196,7 @@ pub type BlockBody = alloy_consensus::BlockBody<TransactionSigned>;
impl From<TransactionSigned> for EthereumTxEnvelope<TxEip4844> { impl From<TransactionSigned> for EthereumTxEnvelope<TxEip4844> {
fn from(value: TransactionSigned) -> Self { fn from(value: TransactionSigned) -> Self {
value.0 value.into_inner()
} }
} }
@ -337,7 +204,7 @@ impl TryFrom<TransactionSigned> for EthereumTxEnvelope<TxEip4844WithSidecar> {
type Error = <InnerType as TryInto<EthereumTxEnvelope<TxEip4844WithSidecar>>>::Error; type Error = <InnerType as TryInto<EthereumTxEnvelope<TxEip4844WithSidecar>>>::Error;
fn try_from(value: TransactionSigned) -> Result<Self, Self::Error> { fn try_from(value: TransactionSigned) -> Result<Self, Self::Error> {
value.0.try_into() value.into_inner().try_into()
} }
} }
@ -349,7 +216,7 @@ impl TryFrom<TransactionSigned>
>>::Error; >>::Error;
fn try_from(value: TransactionSigned) -> Result<Self, Self::Error> { fn try_from(value: TransactionSigned) -> Result<Self, Self::Error> {
value.0.try_into() value.into_inner().try_into()
} }
} }
@ -359,7 +226,7 @@ impl From<EthereumTxEnvelope<TxEip4844WithSidecar<BlobTransactionSidecarVariant>
fn from( fn from(
value: EthereumTxEnvelope<TxEip4844WithSidecar<BlobTransactionSidecarVariant>>, value: EthereumTxEnvelope<TxEip4844WithSidecar<BlobTransactionSidecarVariant>>,
) -> Self { ) -> Self {
Self(value.into()) Self::Default(value.into())
} }
} }
@ -367,23 +234,23 @@ impl Compress for TransactionSigned {
type Compressed = Vec<u8>; type Compressed = Vec<u8>;
fn compress(self) -> Self::Compressed { fn compress(self) -> Self::Compressed {
self.0.compress() self.into_inner().compress()
} }
fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(&self, buf: &mut B) { fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(&self, buf: &mut B) {
self.0.compress_to_buf(buf); self.inner().compress_to_buf(buf);
} }
} }
impl Decompress for TransactionSigned { impl Decompress for TransactionSigned {
fn decompress(value: &[u8]) -> Result<Self, DatabaseError> { fn decompress(value: &[u8]) -> Result<Self, DatabaseError> {
Ok(Self(InnerType::decompress(value)?)) Ok(Self::Default(InnerType::decompress(value)?))
} }
} }
pub fn convert_to_eth_block_body(value: BlockBody) -> alloy_consensus::BlockBody<InnerType> { pub fn convert_to_eth_block_body(value: BlockBody) -> alloy_consensus::BlockBody<InnerType> {
alloy_consensus::BlockBody { alloy_consensus::BlockBody {
transactions: value.transactions.into_iter().map(|tx| tx.0).collect(), transactions: value.transactions.into_iter().map(|tx| tx.into_inner()).collect(),
ommers: value.ommers, ommers: value.ommers,
withdrawals: value.withdrawals, withdrawals: value.withdrawals,
} }
@ -391,8 +258,41 @@ pub fn convert_to_eth_block_body(value: BlockBody) -> alloy_consensus::BlockBody
pub fn convert_to_hl_block_body(value: alloy_consensus::BlockBody<InnerType>) -> BlockBody { pub fn convert_to_hl_block_body(value: alloy_consensus::BlockBody<InnerType>) -> BlockBody {
BlockBody { BlockBody {
transactions: value.transactions.into_iter().map(TransactionSigned).collect(), transactions: value.transactions.into_iter().map(TransactionSigned::Default).collect(),
ommers: value.ommers, ommers: value.ommers,
withdrawals: value.withdrawals, withdrawals: value.withdrawals,
} }
} }
impl TryIntoSimTx<TransactionSigned> for TransactionRequest {
fn try_into_sim_tx(self) -> Result<TransactionSigned, ValueError<Self>> {
let tx = self
.build_typed_tx()
.map_err(|request| ValueError::new(request, "Required fields missing"))?;
// Create an empty signature for the transaction.
let signature = Signature::new(Default::default(), Default::default(), false);
Ok(tx.into_signed(signature).into())
}
}
impl TryIntoTxEnv<HlTxEnv<TxEnv>> for TransactionRequest {
type Err = EthTxEnvError;
fn try_into_tx_env<Spec>(
self,
cfg_env: &CfgEnv<Spec>,
block_env: &BlockEnv,
) -> Result<HlTxEnv<TxEnv>, Self::Err> {
Ok(HlTxEnv::new(self.clone().try_into_tx_env(cfg_env, block_env)?))
}
}
impl FromConsensusTx<TransactionSigned> for Transaction {
type TxInfo = TransactionInfo;
fn from_consensus_tx(tx: TransactionSigned, signer: Address, tx_info: Self::TxInfo) -> Self {
Self::from_transaction(Recovered::new_unchecked(tx.into_inner().into(), signer), tx_info)
}
}

View File

@ -139,7 +139,7 @@ where
inputs inputs
.into_iter() .into_iter()
.map(|(header, transactions)| { .map(|(header, transactions)| {
(header, transactions.into_iter().map(|tx| tx.0).collect()) (header, transactions.into_iter().map(|tx| tx.into_inner()).collect())
}) })
.collect(), .collect(),
)?; )?;

View File

@ -47,19 +47,19 @@ impl TransactionSigned {
fn to_reth_transaction(&self) -> TxSigned { fn to_reth_transaction(&self) -> TxSigned {
match self.transaction.clone() { match self.transaction.clone() {
Transaction::Legacy(tx) => { Transaction::Legacy(tx) => {
TxSigned(RethTxSigned::Legacy(Signed::new_unhashed(tx, self.signature))) TxSigned::Default(RethTxSigned::Legacy(Signed::new_unhashed(tx, self.signature)))
} }
Transaction::Eip2930(tx) => { Transaction::Eip2930(tx) => {
TxSigned(RethTxSigned::Eip2930(Signed::new_unhashed(tx, self.signature))) TxSigned::Default(RethTxSigned::Eip2930(Signed::new_unhashed(tx, self.signature)))
} }
Transaction::Eip1559(tx) => { Transaction::Eip1559(tx) => {
TxSigned(RethTxSigned::Eip1559(Signed::new_unhashed(tx, self.signature))) TxSigned::Default(RethTxSigned::Eip1559(Signed::new_unhashed(tx, self.signature)))
} }
Transaction::Eip4844(tx) => { Transaction::Eip4844(tx) => {
TxSigned(RethTxSigned::Eip4844(Signed::new_unhashed(tx, self.signature))) TxSigned::Default(RethTxSigned::Eip4844(Signed::new_unhashed(tx, self.signature)))
} }
Transaction::Eip7702(tx) => { Transaction::Eip7702(tx) => {
TxSigned(RethTxSigned::Eip7702(Signed::new_unhashed(tx, self.signature))) TxSigned::Default(RethTxSigned::Eip7702(Signed::new_unhashed(tx, self.signature)))
} }
} }
} }
@ -104,7 +104,7 @@ fn system_tx_to_reth_transaction(transaction: &SystemTx, chain_id: u64) -> TxSig
} }
}; };
let signature = Signature::new(U256::from(0x1), s, true); let signature = Signature::new(U256::from(0x1), s, true);
TxSigned(RethTxSigned::Legacy(Signed::new_unhashed(tx.clone(), signature))) TxSigned::Default(RethTxSigned::Legacy(Signed::new_unhashed(tx.clone(), signature)))
} }
} }