mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-09 15:28:01 -05:00
refactor(examples): Use TransactionEnvelope macro from alloy for CustomTransaction in the custom-node example (#17057)
This commit is contained in:
@@ -257,28 +257,6 @@ impl TransactionEnv for CustomTxEnv {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRecoveredTx<CustomTransaction> for PaymentTxEnv {
|
||||
fn from_recovered_tx(tx: &CustomTransaction, sender: Address) -> Self {
|
||||
PaymentTxEnv(match tx {
|
||||
CustomTransaction::BuiltIn(tx) => {
|
||||
OpTransaction::<TxEnv>::from_recovered_tx(tx, sender).base
|
||||
}
|
||||
CustomTransaction::Other(tx) => TxEnv::from_recovered_tx(tx, sender),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FromTxWithEncoded<CustomTransaction> for PaymentTxEnv {
|
||||
fn from_encoded_tx(tx: &CustomTransaction, sender: Address, encoded: Bytes) -> Self {
|
||||
PaymentTxEnv(match tx {
|
||||
CustomTransaction::BuiltIn(tx) => {
|
||||
OpTransaction::<TxEnv>::from_encoded_tx(tx, sender, encoded).base
|
||||
}
|
||||
CustomTransaction::Other(tx) => TxEnv::from_encoded_tx(tx, sender, encoded),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRecoveredTx<TxPayment> for TxEnv {
|
||||
fn from_recovered_tx(tx: &TxPayment, caller: Address) -> Self {
|
||||
let TxPayment {
|
||||
@@ -317,6 +295,12 @@ impl FromTxWithEncoded<CustomTransactionEnvelope> for TxEnv {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromTxWithEncoded<TxPayment> for TxEnv {
|
||||
fn from_encoded_tx(tx: &TxPayment, sender: Address, _encoded: Bytes) -> Self {
|
||||
Self::from_recovered_tx(tx, sender)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRecoveredTx<OpTxEnvelope> for CustomTxEnv {
|
||||
fn from_recovered_tx(tx: &OpTxEnvelope, sender: Address) -> Self {
|
||||
Self::Op(OpTransaction::from_recovered_tx(tx, sender))
|
||||
@@ -332,8 +316,8 @@ impl FromTxWithEncoded<OpTxEnvelope> for CustomTxEnv {
|
||||
impl FromRecoveredTx<CustomTransaction> for CustomTxEnv {
|
||||
fn from_recovered_tx(tx: &CustomTransaction, sender: Address) -> Self {
|
||||
match tx {
|
||||
CustomTransaction::BuiltIn(tx) => Self::from_recovered_tx(tx, sender),
|
||||
CustomTransaction::Other(tx) => {
|
||||
CustomTransaction::Op(tx) => Self::from_recovered_tx(tx, sender),
|
||||
CustomTransaction::Payment(tx) => {
|
||||
Self::Payment(PaymentTxEnv(TxEnv::from_recovered_tx(tx, sender)))
|
||||
}
|
||||
}
|
||||
@@ -343,8 +327,8 @@ impl FromRecoveredTx<CustomTransaction> for CustomTxEnv {
|
||||
impl FromTxWithEncoded<CustomTransaction> for CustomTxEnv {
|
||||
fn from_encoded_tx(tx: &CustomTransaction, sender: Address, encoded: Bytes) -> Self {
|
||||
match tx {
|
||||
CustomTransaction::BuiltIn(tx) => Self::from_encoded_tx(tx, sender, encoded),
|
||||
CustomTransaction::Other(tx) => {
|
||||
CustomTransaction::Op(tx) => Self::from_encoded_tx(tx, sender, encoded),
|
||||
CustomTransaction::Payment(tx) => {
|
||||
Self::Payment(PaymentTxEnv(TxEnv::from_encoded_tx(tx, sender, encoded)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +43,11 @@ where
|
||||
f: impl FnOnce(&ExecutionResult<<Self::Evm as Evm>::HaltReason>) -> CommitChanges,
|
||||
) -> Result<Option<u64>, BlockExecutionError> {
|
||||
match tx.tx() {
|
||||
CustomTransaction::BuiltIn(op_tx) => {
|
||||
self.inner.execute_transaction_with_commit_condition(
|
||||
Recovered::new_unchecked(op_tx, *tx.signer()),
|
||||
f,
|
||||
)
|
||||
}
|
||||
CustomTransaction::Other(..) => todo!(),
|
||||
CustomTransaction::Op(op_tx) => self.inner.execute_transaction_with_commit_condition(
|
||||
Recovered::new_unchecked(op_tx, *tx.signer()),
|
||||
f,
|
||||
),
|
||||
CustomTransaction::Payment(..) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
use crate::primitives::CustomTransactionEnvelope;
|
||||
use crate::primitives::{CustomTransaction, CustomTransactionEnvelope};
|
||||
use alloy_consensus::error::ValueError;
|
||||
use op_alloy_consensus::OpPooledTransaction;
|
||||
use reth_ethereum::primitives::Extended;
|
||||
|
||||
pub type CustomPooledTransaction = Extended<OpPooledTransaction, CustomTransactionEnvelope>;
|
||||
|
||||
impl From<CustomPooledTransaction> for CustomTransaction {
|
||||
fn from(tx: CustomPooledTransaction) -> Self {
|
||||
match tx {
|
||||
CustomPooledTransaction::BuiltIn(tx) => Self::Op(tx.into()),
|
||||
CustomPooledTransaction::Other(tx) => Self::Payment(tx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<CustomTransaction> for CustomPooledTransaction {
|
||||
type Error = ValueError<CustomTransaction>;
|
||||
|
||||
fn try_from(tx: CustomTransaction) -> Result<Self, Self::Error> {
|
||||
match tx {
|
||||
CustomTransaction::Op(op) => Ok(Self::BuiltIn(
|
||||
OpPooledTransaction::try_from(op).map_err(|op| op.map(CustomTransaction::Op))?,
|
||||
)),
|
||||
CustomTransaction::Payment(payment) => Ok(Self::Other(payment)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
use super::{TxPayment, TxTypeCustom};
|
||||
use super::TxPayment;
|
||||
use alloy_consensus::{
|
||||
crypto::{
|
||||
secp256k1::{recover_signer, recover_signer_unchecked},
|
||||
RecoveryError,
|
||||
},
|
||||
transaction::SignerRecoverable,
|
||||
SignableTransaction, Signed, Transaction,
|
||||
SignableTransaction, Signed, Transaction, TransactionEnvelope,
|
||||
};
|
||||
use alloy_eips::{eip2718::Eip2718Result, Decodable2718, Encodable2718, Typed2718};
|
||||
use alloy_primitives::{keccak256, Sealed, Signature, TxHash};
|
||||
use alloy_eips::{
|
||||
eip2718::{Eip2718Result, IsTyped2718},
|
||||
Decodable2718, Encodable2718, Typed2718,
|
||||
};
|
||||
use alloy_primitives::{bytes::Buf, keccak256, Sealed, Signature, TxHash, B256};
|
||||
use alloy_rlp::{BufMut, Decodable, Encodable, Result as RlpResult};
|
||||
use op_alloy_consensus::{OpTxEnvelope, TxDeposit};
|
||||
use reth_codecs::{
|
||||
@@ -16,19 +19,21 @@ use reth_codecs::{
|
||||
Compact,
|
||||
};
|
||||
use reth_ethereum::primitives::{serde_bincode_compat::RlpBincode, InMemorySize};
|
||||
use reth_op::{
|
||||
primitives::{Extended, SignedTransaction},
|
||||
OpTransaction,
|
||||
};
|
||||
use reth_op::{primitives::SignedTransaction, OpTransaction};
|
||||
use revm_primitives::{Address, Bytes};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An [`OpTxEnvelope`] that is [`Extended`] by one more variant of [`CustomTransactionEnvelope`].
|
||||
pub type CustomTransaction = ExtendedOpTxEnvelope<CustomTransactionEnvelope>;
|
||||
|
||||
/// A [`SignedTransaction`] implementation that combines the [`OpTxEnvelope`] and another
|
||||
/// transaction type.
|
||||
pub type ExtendedOpTxEnvelope<T> = Extended<OpTxEnvelope, T>;
|
||||
/// Either [`OpTxEnvelope`] or [`CustomTransactionEnvelope`].
|
||||
#[derive(Debug, Clone, TransactionEnvelope)]
|
||||
#[envelope(tx_type_name = TxTypeCustom)]
|
||||
pub enum CustomTransaction {
|
||||
/// A regular Optimism transaction as defined by [`OpTxEnvelope`].
|
||||
#[envelope(flatten)]
|
||||
Op(OpTxEnvelope),
|
||||
/// A [`TxPayment`] tagged with type 0x7E.
|
||||
#[envelope(ty = 42)]
|
||||
Payment(CustomTransactionEnvelope),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
|
||||
pub struct CustomTransactionEnvelope {
|
||||
@@ -98,7 +103,7 @@ impl Transaction for CustomTransactionEnvelope {
|
||||
self.inner.tx().access_list()
|
||||
}
|
||||
|
||||
fn blob_versioned_hashes(&self) -> Option<&[revm_primitives::B256]> {
|
||||
fn blob_versioned_hashes(&self) -> Option<&[B256]> {
|
||||
self.inner.tx().blob_versioned_hashes()
|
||||
}
|
||||
|
||||
@@ -199,6 +204,7 @@ impl ToTxCompact for CustomTransactionEnvelope {
|
||||
}
|
||||
|
||||
impl RlpBincode for CustomTransactionEnvelope {}
|
||||
impl RlpBincode for CustomTransaction {}
|
||||
|
||||
impl reth_codecs::alloy::transaction::Envelope for CustomTransactionEnvelope {
|
||||
fn signature(&self) -> &Signature {
|
||||
@@ -206,14 +212,14 @@ impl reth_codecs::alloy::transaction::Envelope for CustomTransactionEnvelope {
|
||||
}
|
||||
|
||||
fn tx_type(&self) -> Self::TxType {
|
||||
TxTypeCustom::Custom
|
||||
TxTypeCustom::Payment
|
||||
}
|
||||
}
|
||||
|
||||
impl Compact for CustomTransactionEnvelope {
|
||||
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||
where
|
||||
B: alloy_rlp::bytes::BufMut + AsMut<[u8]>,
|
||||
B: BufMut + AsMut<[u8]>,
|
||||
{
|
||||
self.inner.tx().to_compact(buf)
|
||||
}
|
||||
@@ -226,6 +232,31 @@ impl Compact for CustomTransactionEnvelope {
|
||||
}
|
||||
}
|
||||
|
||||
impl reth_codecs::Compact for CustomTransaction {
|
||||
fn to_compact<Buf>(&self, buf: &mut Buf) -> usize
|
||||
where
|
||||
Buf: BufMut + AsMut<[u8]>,
|
||||
{
|
||||
buf.put_u8(self.ty());
|
||||
match self {
|
||||
Self::Op(tx) => tx.to_compact(buf),
|
||||
Self::Payment(tx) => tx.to_compact(buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||
let type_byte = buf.get_u8();
|
||||
|
||||
if <OpTxEnvelope as IsTyped2718>::is_type(type_byte) {
|
||||
let (tx, remaining) = OpTxEnvelope::from_compact(buf, len);
|
||||
return (Self::Op(tx), remaining);
|
||||
}
|
||||
|
||||
let (tx, remaining) = CustomTransactionEnvelope::from_compact(buf, len);
|
||||
(Self::Payment(tx), remaining)
|
||||
}
|
||||
}
|
||||
|
||||
impl OpTransaction for CustomTransactionEnvelope {
|
||||
fn is_deposit(&self) -> bool {
|
||||
false
|
||||
@@ -235,3 +266,67 @@ impl OpTransaction for CustomTransactionEnvelope {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl OpTransaction for CustomTransaction {
|
||||
fn is_deposit(&self) -> bool {
|
||||
match self {
|
||||
CustomTransaction::Op(op) => op.is_deposit(),
|
||||
CustomTransaction::Payment(payment) => payment.is_deposit(),
|
||||
}
|
||||
}
|
||||
|
||||
fn as_deposit(&self) -> Option<&Sealed<TxDeposit>> {
|
||||
match self {
|
||||
CustomTransaction::Op(op) => op.as_deposit(),
|
||||
CustomTransaction::Payment(payment) => payment.as_deposit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SignerRecoverable for CustomTransaction {
|
||||
fn recover_signer(&self) -> Result<Address, RecoveryError> {
|
||||
match self {
|
||||
CustomTransaction::Op(tx) => SignerRecoverable::recover_signer(tx),
|
||||
CustomTransaction::Payment(tx) => SignerRecoverable::recover_signer(tx),
|
||||
}
|
||||
}
|
||||
|
||||
fn recover_signer_unchecked(&self) -> Result<Address, RecoveryError> {
|
||||
match self {
|
||||
CustomTransaction::Op(tx) => SignerRecoverable::recover_signer_unchecked(tx),
|
||||
CustomTransaction::Payment(tx) => SignerRecoverable::recover_signer_unchecked(tx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SignedTransaction for CustomTransaction {
|
||||
fn recover_signer_unchecked_with_buf(
|
||||
&self,
|
||||
buf: &mut Vec<u8>,
|
||||
) -> Result<Address, RecoveryError> {
|
||||
match self {
|
||||
CustomTransaction::Op(tx) => {
|
||||
SignedTransaction::recover_signer_unchecked_with_buf(tx, buf)
|
||||
}
|
||||
CustomTransaction::Payment(tx) => {
|
||||
SignedTransaction::recover_signer_unchecked_with_buf(tx, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tx_hash(&self) -> &B256 {
|
||||
match self {
|
||||
CustomTransaction::Op(tx) => SignedTransaction::tx_hash(tx),
|
||||
CustomTransaction::Payment(tx) => SignedTransaction::tx_hash(tx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InMemorySize for CustomTransaction {
|
||||
fn size(&self) -> usize {
|
||||
match self {
|
||||
CustomTransaction::Op(tx) => InMemorySize::size(tx),
|
||||
CustomTransaction::Payment(tx) => InMemorySize::size(tx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::primitives::{TxTypeCustom, TRANSFER_TX_TYPE_ID};
|
||||
use crate::primitives::PAYMENT_TX_TYPE_ID;
|
||||
use alloy_consensus::{
|
||||
transaction::{RlpEcdsaDecodableTx, RlpEcdsaEncodableTx},
|
||||
SignableTransaction, Transaction,
|
||||
@@ -71,8 +71,8 @@ pub struct TxPayment {
|
||||
impl TxPayment {
|
||||
/// Get the transaction type
|
||||
#[doc(alias = "transaction_type")]
|
||||
pub const fn tx_type() -> TxTypeCustom {
|
||||
TxTypeCustom::Custom
|
||||
pub const fn tx_type() -> super::tx::TxTypeCustom {
|
||||
super::tx::TxTypeCustom::Payment
|
||||
}
|
||||
|
||||
/// Calculates a heuristic for the in-memory size of the [TxPayment]
|
||||
@@ -115,7 +115,7 @@ impl RlpEcdsaEncodableTx for TxPayment {
|
||||
}
|
||||
|
||||
impl RlpEcdsaDecodableTx for TxPayment {
|
||||
const DEFAULT_TX_TYPE: u8 = { Self::tx_type() as u8 };
|
||||
const DEFAULT_TX_TYPE: u8 = { PAYMENT_TX_TYPE_ID };
|
||||
|
||||
/// Decodes the inner [TxPayment] fields from RLP bytes.
|
||||
///
|
||||
@@ -244,7 +244,7 @@ impl Transaction for TxPayment {
|
||||
|
||||
impl Typed2718 for TxPayment {
|
||||
fn ty(&self) -> u8 {
|
||||
TRANSFER_TX_TYPE_ID
|
||||
PAYMENT_TX_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ impl SignableTransaction<Signature> for TxPayment {
|
||||
}
|
||||
|
||||
fn encode_for_signing(&self, out: &mut dyn alloy_rlp::BufMut) {
|
||||
out.put_u8(Self::tx_type() as u8);
|
||||
out.put_u8(Self::tx_type().ty());
|
||||
self.encode(out)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
use crate::primitives::TxTypeCustom;
|
||||
use alloy_primitives::bytes::{Buf, BufMut};
|
||||
use reth_codecs::{txtype::COMPACT_EXTENDED_IDENTIFIER_FLAG, Compact};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const TRANSFER_TX_TYPE_ID: u8 = 42;
|
||||
|
||||
/// An enum for the custom transaction type(s)
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
|
||||
pub enum TxTypeCustom {
|
||||
Custom = TRANSFER_TX_TYPE_ID,
|
||||
}
|
||||
|
||||
impl From<TxTypeCustom> for u8 {
|
||||
fn from(value: TxTypeCustom) -> Self {
|
||||
value as Self
|
||||
}
|
||||
}
|
||||
pub const PAYMENT_TX_TYPE_ID: u8 = 42;
|
||||
|
||||
impl Compact for TxTypeCustom {
|
||||
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||
@@ -23,26 +10,27 @@ impl Compact for TxTypeCustom {
|
||||
B: BufMut + AsMut<[u8]>,
|
||||
{
|
||||
match self {
|
||||
Self::Custom => {
|
||||
buf.put_u8(TRANSFER_TX_TYPE_ID);
|
||||
Self::Op(ty) => ty.to_compact(buf),
|
||||
Self::Payment => {
|
||||
buf.put_u8(PAYMENT_TX_TYPE_ID);
|
||||
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
|
||||
(
|
||||
match identifier {
|
||||
COMPACT_EXTENDED_IDENTIFIER_FLAG => {
|
||||
match identifier {
|
||||
COMPACT_EXTENDED_IDENTIFIER_FLAG => (
|
||||
{
|
||||
let extended_identifier = buf.get_u8();
|
||||
match extended_identifier {
|
||||
TRANSFER_TX_TYPE_ID => Self::Custom,
|
||||
PAYMENT_TX_TYPE_ID => Self::Payment,
|
||||
_ => panic!("Unsupported TxType identifier: {extended_identifier}"),
|
||||
}
|
||||
}
|
||||
_ => panic!("Unknown identifier for TxType: {identifier}"),
|
||||
},
|
||||
buf,
|
||||
)
|
||||
},
|
||||
buf,
|
||||
),
|
||||
v => Self::from_compact(buf, v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user