Skip to content

Commit

Permalink
Move AnyNetwork related types into their own crates
Browse files Browse the repository at this point in the history
  • Loading branch information
moricho committed Nov 30, 2024
1 parent 67576f9 commit 1e7e4f0
Show file tree
Hide file tree
Showing 22 changed files with 774 additions and 648 deletions.
10 changes: 3 additions & 7 deletions crates/consensus-any/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ alloy-consensus = { workspace = true, features = ["serde"] }
alloy-eips.workspace = true
alloy-primitives.workspace = true
alloy-rlp.workspace = true
alloy-serde = { workspace = true, optional = true }
alloy-serde.workspace = true

# arbitrary
arbitrary = { workspace = true, features = ["derive"], optional = true }

# serde
serde = { workspace = true, features = ["derive"], optional = true }
serde_json.workspace = true

[dev-dependencies]
arbitrary = { workspace = true, features = ["derive"] }
Expand All @@ -38,9 +39,4 @@ arbitrary = { workspace = true, features = ["derive"] }
default = ["std"]
std = ["alloy-eips/std"]
arbitrary = ["std", "dep:arbitrary", "alloy-eips/arbitrary"]
serde = [
"dep:serde",
"alloy-primitives/serde",
"dep:alloy-serde",
"alloy-eips/serde",
]
serde = ["dep:serde", "alloy-primitives/serde", "alloy-eips/serde"]
6 changes: 5 additions & 1 deletion crates/consensus-any/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]

mod block;
pub use block::AnyHeader;

mod receipt;
pub use receipt::AnyReceiptEnvelope;

mod transaction;
pub use transaction::{
AnyTxEnvelope, AnyTxType, AnyTypedTransaction, UnknownTxEnvelope, UnknownTypedTransaction,
};
Original file line number Diff line number Diff line change
@@ -1,207 +1,85 @@
use crate::{UnknownTxEnvelope, UnknownTypedTransaction};
use alloy_consensus::{Transaction as TransactionTrait, TxEnvelope, TypedTransaction};
use core::fmt;

use crate::UnknownTxEnvelope;
use alloy_consensus::{Transaction as TransactionTrait, TxEnvelope, TxType};
use alloy_eips::{
eip2718::{Decodable2718, Encodable2718},
eip2718::{Decodable2718, Eip2718Error, Encodable2718},
eip2930::AccessList,
eip7702::SignedAuthorization,
};
use alloy_primitives::{Bytes, ChainId, B256, U256};
use alloy_rpc_types_eth::{AccessList, TransactionRequest};
use alloy_serde::WithOtherFields;

/// Unsigned transaction type for a catch-all network.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
#[doc(alias = "AnyTypedTx")]
pub enum AnyTypedTransaction {
/// An Ethereum transaction.
Ethereum(TypedTransaction),
/// A transaction with unknown type.
Unknown(UnknownTypedTransaction),
}

impl From<UnknownTypedTransaction> for AnyTypedTransaction {
fn from(value: UnknownTypedTransaction) -> Self {
Self::Unknown(value)
}
}
/// Transaction type for a catch-all network.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[doc(alias = "AnyTransactionType")]
pub struct AnyTxType(pub u8);

impl From<TypedTransaction> for AnyTypedTransaction {
fn from(value: TypedTransaction) -> Self {
Self::Ethereum(value)
impl fmt::Display for AnyTxType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "AnyTxType({})", self.0)
}
}

impl From<AnyTxEnvelope> for AnyTypedTransaction {
fn from(value: AnyTxEnvelope) -> Self {
match value {
AnyTxEnvelope::Ethereum(tx) => Self::Ethereum(tx.into()),
AnyTxEnvelope::Unknown(UnknownTxEnvelope { inner, .. }) => inner.into(),
}
}
}
impl TryFrom<u8> for AnyTxType {
type Error = Eip2718Error;

impl From<AnyTypedTransaction> for WithOtherFields<TransactionRequest> {
fn from(value: AnyTypedTransaction) -> Self {
match value {
AnyTypedTransaction::Ethereum(tx) => Self::new(tx.into()),
AnyTypedTransaction::Unknown(UnknownTypedTransaction { ty, mut fields, .. }) => {
fields.insert("type".to_string(), serde_json::Value::Number(ty.0.into()));
Self { inner: Default::default(), other: fields }
}
}
fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(Self(value))
}
}

impl From<AnyTxEnvelope> for WithOtherFields<TransactionRequest> {
fn from(value: AnyTxEnvelope) -> Self {
AnyTypedTransaction::from(value).into()
impl From<&AnyTxType> for u8 {
fn from(value: &AnyTxType) -> Self {
value.0
}
}

impl TransactionTrait for AnyTypedTransaction {
#[inline]
fn chain_id(&self) -> Option<ChainId> {
match self {
Self::Ethereum(inner) => inner.chain_id(),
Self::Unknown(inner) => inner.chain_id(),
}
}

#[inline]
fn nonce(&self) -> u64 {
match self {
Self::Ethereum(inner) => inner.nonce(),
Self::Unknown(inner) => inner.nonce(),
}
}

#[inline]
fn gas_limit(&self) -> u64 {
match self {
Self::Ethereum(inner) => inner.gas_limit(),
Self::Unknown(inner) => inner.gas_limit(),
}
}

#[inline]
fn gas_price(&self) -> Option<u128> {
match self {
Self::Ethereum(inner) => inner.gas_price(),
Self::Unknown(inner) => inner.gas_price(),
}
}

#[inline]
fn max_fee_per_gas(&self) -> u128 {
match self {
Self::Ethereum(inner) => inner.max_fee_per_gas(),
Self::Unknown(inner) => inner.max_fee_per_gas(),
}
}

#[inline]
fn max_priority_fee_per_gas(&self) -> Option<u128> {
match self {
Self::Ethereum(inner) => inner.max_priority_fee_per_gas(),
Self::Unknown(inner) => inner.max_priority_fee_per_gas(),
}
}

#[inline]
fn max_fee_per_blob_gas(&self) -> Option<u128> {
match self {
Self::Ethereum(inner) => inner.max_fee_per_blob_gas(),
Self::Unknown(inner) => inner.max_fee_per_blob_gas(),
}
}

#[inline]
fn priority_fee_or_price(&self) -> u128 {
self.max_priority_fee_per_gas().or_else(|| self.gas_price()).unwrap_or_default()
}

fn effective_gas_price(&self, base_fee: Option<u64>) -> u128 {
match self {
Self::Ethereum(inner) => inner.effective_gas_price(base_fee),
Self::Unknown(inner) => inner.effective_gas_price(base_fee),
}
}

#[inline]
fn is_dynamic_fee(&self) -> bool {
match self {
Self::Ethereum(inner) => inner.is_dynamic_fee(),
Self::Unknown(inner) => inner.is_dynamic_fee(),
}
}

fn kind(&self) -> alloy_primitives::TxKind {
match self {
Self::Ethereum(inner) => inner.kind(),
Self::Unknown(inner) => inner.kind(),
}
}

#[inline]
fn is_create(&self) -> bool {
match self {
Self::Ethereum(inner) => inner.is_create(),
Self::Unknown(inner) => inner.is_create(),
}
impl From<AnyTxType> for u8 {
fn from(value: AnyTxType) -> Self {
value.0
}
}

#[inline]
fn value(&self) -> U256 {
match self {
Self::Ethereum(inner) => inner.value(),
Self::Unknown(inner) => inner.value(),
}
}

#[inline]
fn input(&self) -> &Bytes {
match self {
Self::Ethereum(inner) => inner.input(),
Self::Unknown(inner) => inner.input(),
}
#[cfg(feature = "serde")]
impl serde::Serialize for AnyTxType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use alloy_primitives::U8;
U8::from(self.0).serialize(serializer)
}
}

#[inline]
fn ty(&self) -> u8 {
match self {
Self::Ethereum(inner) => inner.ty(),
Self::Unknown(inner) => inner.ty(),
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for AnyTxType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use alloy_primitives::U8;
U8::deserialize(deserializer).map(|t| Self(t.to::<u8>()))
}
}

#[inline]
fn access_list(&self) -> Option<&AccessList> {
match self {
Self::Ethereum(inner) => inner.access_list(),
Self::Unknown(inner) => inner.access_list(),
}
}
impl TryFrom<AnyTxType> for TxType {
type Error = Eip2718Error;

#[inline]
fn blob_versioned_hashes(&self) -> Option<&[B256]> {
match self {
Self::Ethereum(inner) => inner.blob_versioned_hashes(),
Self::Unknown(inner) => inner.blob_versioned_hashes(),
}
fn try_from(value: AnyTxType) -> Result<Self, Self::Error> {
value.0.try_into()
}
}

#[inline]
fn authorization_list(&self) -> Option<&[SignedAuthorization]> {
match self {
Self::Ethereum(inner) => inner.authorization_list(),
Self::Unknown(inner) => inner.authorization_list(),
}
impl From<TxType> for AnyTxType {
fn from(value: TxType) -> Self {
Self(value as u8)
}
}

/// Transaction envelope for a catch-all network.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(untagged))]
#[doc(alias = "AnyTransactionEnvelope")]
pub enum AnyTxEnvelope {
/// An Ethereum transaction.
Expand Down Expand Up @@ -396,3 +274,14 @@ impl TransactionTrait for AnyTxEnvelope {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_serde_anytype() {
let ty = AnyTxType(126);
assert_eq!(serde_json::to_string(&ty).unwrap(), "\"0x7e\"");
}
}
8 changes: 8 additions & 0 deletions crates/consensus-any/src/transaction/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mod envelope;
pub use envelope::{AnyTxEnvelope, AnyTxType};

mod typed;
pub use typed::AnyTypedTransaction;

mod unknown;
pub use unknown::{UnknownTxEnvelope, UnknownTypedTransaction};
Loading

0 comments on commit 1e7e4f0

Please sign in to comment.