mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore(sdk): improve usability tx primitive traits (#12437)
This commit is contained in:
@ -27,7 +27,7 @@ pub use receipt::{FullReceipt, Receipt};
|
|||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
pub use transaction::{
|
pub use transaction::{
|
||||||
signed::{FullSignedTx, SignedTransaction},
|
signed::{FullSignedTx, SignedTransaction},
|
||||||
FullTransaction, Transaction,
|
FullTransaction, Transaction, TransactionExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod integer_list;
|
mod integer_list;
|
||||||
@ -80,3 +80,15 @@ pub use size::InMemorySize;
|
|||||||
/// Node traits
|
/// Node traits
|
||||||
pub mod node;
|
pub mod node;
|
||||||
pub use node::{FullNodePrimitives, NodePrimitives};
|
pub use node::{FullNodePrimitives, NodePrimitives};
|
||||||
|
|
||||||
|
/// Helper trait that requires arbitrary implementation if the feature is enabled.
|
||||||
|
#[cfg(any(feature = "test-utils", feature = "arbitrary"))]
|
||||||
|
pub trait MaybeArbitrary: for<'a> arbitrary::Arbitrary<'a> {}
|
||||||
|
/// Helper trait that requires arbitrary implementation if the feature is enabled.
|
||||||
|
#[cfg(not(any(feature = "test-utils", feature = "arbitrary")))]
|
||||||
|
pub trait MaybeArbitrary {}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "test-utils", feature = "arbitrary"))]
|
||||||
|
impl<T> MaybeArbitrary for T where T: for<'a> arbitrary::Arbitrary<'a> {}
|
||||||
|
#[cfg(not(any(feature = "test-utils", feature = "arbitrary")))]
|
||||||
|
impl<T> MaybeArbitrary for T {}
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
//! Transaction abstraction
|
//! Transaction abstraction
|
||||||
|
|
||||||
use core::{fmt, hash::Hash};
|
|
||||||
|
|
||||||
use alloy_primitives::{TxKind, B256};
|
|
||||||
|
|
||||||
use reth_codecs::Compact;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::InMemorySize;
|
|
||||||
|
|
||||||
pub mod signed;
|
pub mod signed;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
use core::{fmt, hash::Hash};
|
||||||
|
|
||||||
|
use alloy_primitives::B256;
|
||||||
|
use reth_codecs::Compact;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{InMemorySize, MaybeArbitrary, TxType};
|
||||||
|
|
||||||
|
/// Helper trait that unifies all behaviour required by transaction to support full node operations.
|
||||||
|
pub trait FullTransaction: Transaction + Compact {}
|
||||||
|
|
||||||
|
impl<T> FullTransaction for T where T: Transaction + Compact {}
|
||||||
|
|
||||||
/// Abstraction of a transaction.
|
/// Abstraction of a transaction.
|
||||||
pub trait Transaction:
|
pub trait Transaction:
|
||||||
Send
|
Send
|
||||||
@ -24,41 +27,42 @@ pub trait Transaction:
|
|||||||
+ PartialEq
|
+ PartialEq
|
||||||
+ Hash
|
+ Hash
|
||||||
+ Serialize
|
+ Serialize
|
||||||
+ alloy_rlp::Encodable
|
|
||||||
+ alloy_rlp::Decodable
|
|
||||||
+ for<'de> Deserialize<'de>
|
+ for<'de> Deserialize<'de>
|
||||||
+ alloy_consensus::Transaction
|
+ TransactionExt
|
||||||
+ InMemorySize
|
+ InMemorySize
|
||||||
+ MaybeArbitrary
|
+ MaybeArbitrary
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Transaction for T where
|
||||||
|
T: Send
|
||||||
|
+ Sync
|
||||||
|
+ Unpin
|
||||||
|
+ Clone
|
||||||
|
+ Default
|
||||||
|
+ fmt::Debug
|
||||||
|
+ Eq
|
||||||
|
+ PartialEq
|
||||||
|
+ Hash
|
||||||
|
+ Serialize
|
||||||
|
+ for<'de> Deserialize<'de>
|
||||||
|
+ TransactionExt
|
||||||
|
+ InMemorySize
|
||||||
|
+ MaybeArbitrary
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extension trait of [`alloy_consensus::Transaction`].
|
||||||
|
pub trait TransactionExt: alloy_consensus::Transaction {
|
||||||
|
/// Transaction envelope type ID.
|
||||||
|
type Type: TxType;
|
||||||
|
|
||||||
/// Heavy operation that return signature hash over rlp encoded transaction.
|
/// Heavy operation that return signature hash over rlp encoded transaction.
|
||||||
/// It is only for signature signing or signer recovery.
|
/// It is only for signature signing or signer recovery.
|
||||||
fn signature_hash(&self) -> B256;
|
fn signature_hash(&self) -> B256;
|
||||||
|
|
||||||
/// Gets the transaction's [`TxKind`], which is the address of the recipient or
|
/// Returns the transaction type.
|
||||||
/// [`TxKind::Create`] if the transaction is a contract creation.
|
fn tx_type(&self) -> Self::Type {
|
||||||
fn kind(&self) -> TxKind;
|
Self::Type::try_from(self.ty()).expect("should decode tx type id")
|
||||||
|
}
|
||||||
/// Returns true if the tx supports dynamic fees
|
|
||||||
fn is_dynamic_fee(&self) -> bool;
|
|
||||||
|
|
||||||
/// Returns the effective gas price for the given base fee.
|
|
||||||
fn effective_gas_price(&self, base_fee: Option<u64>) -> u128;
|
|
||||||
|
|
||||||
/// This encodes the transaction _without_ the signature, and is only suitable for creating a
|
|
||||||
/// hash intended for signing.
|
|
||||||
fn encode_without_signature(&self, out: &mut dyn bytes::BufMut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "arbitrary"))]
|
|
||||||
/// Helper trait that requires arbitrary implementation if the feature is enabled.
|
|
||||||
pub trait MaybeArbitrary {}
|
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
|
||||||
/// Helper trait that requires arbitrary implementation if the feature is enabled.
|
|
||||||
pub trait MaybeArbitrary: for<'a> arbitrary::Arbitrary<'a> {}
|
|
||||||
|
|
||||||
/// Helper trait that unifies all behaviour required by transaction to support full node operations.
|
|
||||||
pub trait FullTransaction: Transaction + Compact {}
|
|
||||||
|
|
||||||
impl<T> FullTransaction for T where T: Transaction + Compact {}
|
|
||||||
|
|||||||
@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
use alloc::fmt;
|
use alloc::fmt;
|
||||||
use core::hash::Hash;
|
use core::hash::Hash;
|
||||||
use reth_codecs::Compact;
|
|
||||||
|
|
||||||
use alloy_consensus::Transaction;
|
|
||||||
use alloy_eips::eip2718::{Decodable2718, Encodable2718};
|
use alloy_eips::eip2718::{Decodable2718, Encodable2718};
|
||||||
use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, TxHash, B256};
|
use alloy_primitives::{keccak256, Address, PrimitiveSignature, TxHash, B256};
|
||||||
|
use reth_codecs::Compact;
|
||||||
use revm_primitives::TxEnv;
|
use revm_primitives::TxEnv;
|
||||||
|
|
||||||
/// Helper trait that unifies all behaviour required by block to support full node operations.
|
use crate::{transaction::TransactionExt, FullTransaction, MaybeArbitrary, Transaction};
|
||||||
pub trait FullSignedTx: SignedTransaction<Transaction: Compact> + Compact {}
|
|
||||||
|
|
||||||
impl<T> FullSignedTx for T where T: SignedTransaction<Transaction: Compact> + Compact {}
|
/// Helper trait that unifies all behaviour required by block to support full node operations.
|
||||||
|
pub trait FullSignedTx: SignedTransaction<Transaction: FullTransaction> + Compact {}
|
||||||
|
|
||||||
|
impl<T> FullSignedTx for T where T: SignedTransaction<Transaction: FullTransaction> + Compact {}
|
||||||
|
|
||||||
/// A signed transaction.
|
/// A signed transaction.
|
||||||
pub trait SignedTransaction:
|
pub trait SignedTransaction:
|
||||||
@ -31,6 +32,8 @@ pub trait SignedTransaction:
|
|||||||
+ alloy_rlp::Decodable
|
+ alloy_rlp::Decodable
|
||||||
+ Encodable2718
|
+ Encodable2718
|
||||||
+ Decodable2718
|
+ Decodable2718
|
||||||
|
+ TransactionExt
|
||||||
|
+ MaybeArbitrary
|
||||||
{
|
{
|
||||||
/// Transaction type that is signed.
|
/// Transaction type that is signed.
|
||||||
type Transaction: Transaction;
|
type Transaction: Transaction;
|
||||||
@ -42,7 +45,7 @@ pub trait SignedTransaction:
|
|||||||
fn transaction(&self) -> &Self::Transaction;
|
fn transaction(&self) -> &Self::Transaction;
|
||||||
|
|
||||||
/// Returns reference to signature.
|
/// Returns reference to signature.
|
||||||
fn signature(&self) -> &Signature;
|
fn signature(&self) -> &PrimitiveSignature;
|
||||||
|
|
||||||
/// Recover signer from signature and hash.
|
/// Recover signer from signature and hash.
|
||||||
///
|
///
|
||||||
@ -65,8 +68,10 @@ pub trait SignedTransaction:
|
|||||||
/// Create a new signed transaction from a transaction and its signature.
|
/// Create a new signed transaction from a transaction and its signature.
|
||||||
///
|
///
|
||||||
/// This will also calculate the transaction hash using its encoding.
|
/// This will also calculate the transaction hash using its encoding.
|
||||||
fn from_transaction_and_signature(transaction: Self::Transaction, signature: Signature)
|
fn from_transaction_and_signature(
|
||||||
-> Self;
|
transaction: Self::Transaction,
|
||||||
|
signature: PrimitiveSignature,
|
||||||
|
) -> Self;
|
||||||
|
|
||||||
/// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with
|
/// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with
|
||||||
/// tx type.
|
/// tx type.
|
||||||
@ -77,3 +82,11 @@ pub trait SignedTransaction:
|
|||||||
/// Fills [`TxEnv`] with an [`Address`] and transaction.
|
/// Fills [`TxEnv`] with an [`Address`] and transaction.
|
||||||
fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address);
|
fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: SignedTransaction> TransactionExt for T {
|
||||||
|
type Type = <T::Transaction as TransactionExt>::Type;
|
||||||
|
|
||||||
|
fn signature_hash(&self) -> B256 {
|
||||||
|
self.transaction().signature_hash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use alloy_eips::eip2718::Eip2718Error;
|
|
||||||
use alloy_primitives::{U64, U8};
|
use alloy_primitives::{U64, U8};
|
||||||
use alloy_rlp::{Decodable, Encodable};
|
|
||||||
use reth_codecs::Compact;
|
use reth_codecs::Compact;
|
||||||
|
|
||||||
/// Helper trait that unifies all behaviour required by transaction type ID to support full node
|
/// Helper trait that unifies all behaviour required by transaction type ID to support full node
|
||||||
@ -26,11 +24,11 @@ pub trait TxType:
|
|||||||
+ PartialEq<u8>
|
+ PartialEq<u8>
|
||||||
+ Into<u8>
|
+ Into<u8>
|
||||||
+ Into<U8>
|
+ Into<U8>
|
||||||
+ TryFrom<u8, Error = Eip2718Error>
|
+ TryFrom<u8, Error: fmt::Debug>
|
||||||
+ TryFrom<u64>
|
+ TryFrom<u64, Error: fmt::Debug>
|
||||||
+ TryFrom<U64>
|
+ TryFrom<U64>
|
||||||
+ Encodable
|
+ alloy_rlp::Encodable
|
||||||
+ Decodable
|
+ alloy_rlp::Decodable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +46,10 @@ impl<T> TxType for T where
|
|||||||
+ PartialEq<u8>
|
+ PartialEq<u8>
|
||||||
+ Into<u8>
|
+ Into<u8>
|
||||||
+ Into<U8>
|
+ Into<U8>
|
||||||
+ TryFrom<u8, Error = Eip2718Error>
|
+ TryFrom<u8, Error: fmt::Debug>
|
||||||
+ TryFrom<u64>
|
+ TryFrom<u64, Error: fmt::Debug>
|
||||||
+ TryFrom<U64>
|
+ TryFrom<U64>
|
||||||
+ Encodable
|
+ alloy_rlp::Encodable
|
||||||
+ Decodable
|
+ alloy_rlp::Decodable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,6 +150,7 @@ test-utils = [
|
|||||||
"reth-chainspec/test-utils",
|
"reth-chainspec/test-utils",
|
||||||
"reth-codecs?/test-utils",
|
"reth-codecs?/test-utils",
|
||||||
"reth-trie-common/test-utils",
|
"reth-trie-common/test-utils",
|
||||||
|
"arbitrary",
|
||||||
]
|
]
|
||||||
serde-bincode-compat = [
|
serde-bincode-compat = [
|
||||||
"alloy-consensus/serde-bincode-compat",
|
"alloy-consensus/serde-bincode-compat",
|
||||||
|
|||||||
@ -68,7 +68,7 @@ use tx_type::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use reth_primitives_traits::SignedTransaction;
|
use reth_primitives_traits::{transaction::TransactionExt, SignedTransaction};
|
||||||
use revm_primitives::{AuthorizationList, TxEnv};
|
use revm_primitives::{AuthorizationList, TxEnv};
|
||||||
|
|
||||||
/// Either a transaction hash or number.
|
/// Either a transaction hash or number.
|
||||||
@ -846,6 +846,22 @@ impl alloy_consensus::Transaction for Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TransactionExt for Transaction {
|
||||||
|
type Type = TxType;
|
||||||
|
|
||||||
|
fn signature_hash(&self) -> B256 {
|
||||||
|
match self {
|
||||||
|
Self::Legacy(tx) => tx.signature_hash(),
|
||||||
|
Self::Eip2930(tx) => tx.signature_hash(),
|
||||||
|
Self::Eip1559(tx) => tx.signature_hash(),
|
||||||
|
Self::Eip4844(tx) => tx.signature_hash(),
|
||||||
|
Self::Eip7702(tx) => tx.signature_hash(),
|
||||||
|
#[cfg(feature = "optimism")]
|
||||||
|
_ => todo!("use op type for op"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Signed transaction without its Hash. Used type for inserting into the DB.
|
/// Signed transaction without its Hash. Used type for inserting into the DB.
|
||||||
///
|
///
|
||||||
/// This can by converted to [`TransactionSigned`] by calling [`TransactionSignedNoHash::hash`].
|
/// This can by converted to [`TransactionSigned`] by calling [`TransactionSignedNoHash::hash`].
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use alloy_consensus::constants::{
|
|||||||
};
|
};
|
||||||
use alloy_primitives::{U64, U8};
|
use alloy_primitives::{U64, U8};
|
||||||
use alloy_rlp::{Decodable, Encodable};
|
use alloy_rlp::{Decodable, Encodable};
|
||||||
|
use derive_more::Display;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Identifier parameter for legacy transaction
|
/// Identifier parameter for legacy transaction
|
||||||
@ -36,24 +37,42 @@ pub const DEPOSIT_TX_TYPE_ID: u8 = 126;
|
|||||||
///
|
///
|
||||||
/// Other required changes when adding a new type can be seen on [PR#3953](https://github.com/paradigmxyz/reth/pull/3953/files).
|
/// Other required changes when adding a new type can be seen on [PR#3953](https://github.com/paradigmxyz/reth/pull/3953/files).
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize, Hash,
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
Default,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
Hash,
|
||||||
|
Display,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
||||||
#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
|
#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
|
||||||
|
#[display("tx type: {_variant}")]
|
||||||
pub enum TxType {
|
pub enum TxType {
|
||||||
/// Legacy transaction pre EIP-2929
|
/// Legacy transaction pre EIP-2929
|
||||||
#[default]
|
#[default]
|
||||||
|
#[display("legacy (0)")]
|
||||||
Legacy = 0_isize,
|
Legacy = 0_isize,
|
||||||
/// AccessList transaction
|
/// AccessList transaction
|
||||||
|
#[display("eip2930 (1)")]
|
||||||
Eip2930 = 1_isize,
|
Eip2930 = 1_isize,
|
||||||
/// Transaction with Priority fee
|
/// Transaction with Priority fee
|
||||||
|
#[display("eip1559 (2)")]
|
||||||
Eip1559 = 2_isize,
|
Eip1559 = 2_isize,
|
||||||
/// Shard Blob Transactions - EIP-4844
|
/// Shard Blob Transactions - EIP-4844
|
||||||
|
#[display("eip4844 (3)")]
|
||||||
Eip4844 = 3_isize,
|
Eip4844 = 3_isize,
|
||||||
/// EOA Contract Code Transactions - EIP-7702
|
/// EOA Contract Code Transactions - EIP-7702
|
||||||
|
#[display("eip7702 (4)")]
|
||||||
Eip7702 = 4_isize,
|
Eip7702 = 4_isize,
|
||||||
/// Optimism Deposit transaction.
|
/// Optimism Deposit transaction.
|
||||||
#[cfg(feature = "optimism")]
|
#[cfg(feature = "optimism")]
|
||||||
|
#[display("deposit (126)")]
|
||||||
Deposit = 126_isize,
|
Deposit = 126_isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user