[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] feat: embed TxEnvelope into rpc_types::Transaction #1169

Closed
wants to merge 14 commits into from
2 changes: 2 additions & 0 deletions crates/consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ arbitrary = { workspace = true, features = ["derive"], optional = true }

# serde
serde = { workspace = true, features = ["derive"], optional = true }
serde-value = { version = "0.7", optional = true }

[dev-dependencies]
alloy-primitives = { workspace = true, features = ["arbitrary", "rand"] }
Expand All @@ -53,5 +54,6 @@ serde = [
"dep:serde",
"alloy-primitives/serde",
"dep:alloy-serde",
"dep:serde-value",
"alloy-eips/serde",
]
1 change: 1 addition & 0 deletions crates/consensus/src/signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use alloy_primitives::{Signature, B256};

/// A transaction with a signature and hash seal.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Signed<T, Sig = Signature> {
#[cfg_attr(feature = "serde", serde(flatten))]
Expand Down
4 changes: 2 additions & 2 deletions crates/consensus/src/transaction/eip1559.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct TxEip1559 {
/// this transaction. This is paid up-front, before any
/// computation is done and may not be increased
/// later; formally Tg.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity", rename = "gas"))]
pub gas_limit: u128,
/// A scalar value equal to the maximum
/// amount of gas that should be used in executing
Expand Down Expand Up @@ -302,7 +302,7 @@ impl Transaction for TxEip1559 {
self.value
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
&self.input
}

Expand Down
4 changes: 2 additions & 2 deletions crates/consensus/src/transaction/eip2930.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct TxEip2930 {
/// this transaction. This is paid up-front, before any
/// computation is done and may not be increased
/// later; formally Tg.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity", rename = "gas"))]
pub gas_limit: u128,
/// The 160-bit address of the message call’s recipient or, for a contract creation
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
Expand Down Expand Up @@ -266,7 +266,7 @@ impl Transaction for TxEip2930 {
self.value
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
&self.input
}

Expand Down
12 changes: 6 additions & 6 deletions crates/consensus/src/transaction/eip4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ impl Transaction for TxEip4844Variant {
}
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
match self {
Self::TxEip4844(tx) => tx.input.as_ref(),
Self::TxEip4844WithSidecar(tx) => tx.tx().input.as_ref(),
Self::TxEip4844(tx) => tx.input(),
Self::TxEip4844WithSidecar(tx) => tx.input(),
}
}

Expand Down Expand Up @@ -352,7 +352,7 @@ pub struct TxEip4844 {
/// this transaction. This is paid up-front, before any
/// computation is done and may not be increased
/// later; formally Tg.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity", rename = "gas"))]
pub gas_limit: u128,
/// A scalar value equal to the maximum
/// amount of gas that should be used in executing
Expand Down Expand Up @@ -723,7 +723,7 @@ impl Transaction for TxEip4844 {
self.value
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
&self.input
}

Expand Down Expand Up @@ -996,7 +996,7 @@ impl Transaction for TxEip4844WithSidecar {
self.tx.value()
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
self.tx.input()
}

Expand Down
5 changes: 3 additions & 2 deletions crates/consensus/src/transaction/eip7702.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use alloy_eips::eip7702::{constants::EIP7702_TX_TYPE_ID, SignedAuthorization};

/// A transaction with a priority fee ([EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)).
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(all(any(test, feature = "arbitrary"), feature = "k256"), derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
#[doc(alias = "Eip7702Transaction", alias = "TransactionEip7702", alias = "Eip7702Tx")]
Expand All @@ -25,7 +26,7 @@ pub struct TxEip7702 {
/// this transaction. This is paid up-front, before any
/// computation is done and may not be increased
/// later; formally Tg.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity", rename = "gas"))]
pub gas_limit: u128,
/// A scalar value equal to the maximum
/// amount of gas that should be used in executing
Expand Down Expand Up @@ -325,7 +326,7 @@ impl Transaction for TxEip7702 {
self.value
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
&self.input
}

Expand Down
104 changes: 100 additions & 4 deletions crates/consensus/src/transaction/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use alloy_eips::{
eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718},
eip2930::AccessList,
};
use alloy_primitives::{TxKind, B256};
use alloy_primitives::{Bytes, TxKind, B256};
use alloy_rlp::{Decodable, Encodable, Header};

use crate::transaction::eip4844::{TxEip4844, TxEip4844Variant, TxEip4844WithSidecar};
Expand Down Expand Up @@ -57,7 +57,7 @@ impl fmt::Display for TxType {
#[cfg(any(test, feature = "arbitrary"))]
impl<'a> arbitrary::Arbitrary<'a> for TxType {
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
Ok(u.int_in_range(0u8..=3)?.try_into().unwrap())
Ok(u.int_in_range(0u8..=4)?.try_into().unwrap())
}
}

Expand All @@ -76,6 +76,27 @@ impl TryFrom<u8> for TxType {
}
}

#[cfg(feature = "serde")]
impl serde::Serialize for TxType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
alloy_primitives::U8::from(u8::from(*self)).serialize(serializer)
}
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for TxType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let val = Option::<alloy_primitives::U8>::deserialize(deserializer)?.unwrap_or_default();
Self::try_from(val.to::<u8>()).map_err(serde::de::Error::custom)
}
}

/// The Ethereum [EIP-2718] Transaction Envelope.
///
/// # Note:
Expand All @@ -88,8 +109,9 @@ impl TryFrom<u8> for TxType {
///
/// [EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "serde", serde(tag = "type"))]
#[cfg_attr(all(any(test, feature = "arbitrary"), feature = "k256"), derive(arbitrary::Arbitrary))]
#[doc(alias = "TransactionEnvelope")]
#[non_exhaustive]
pub enum TxEnvelope {
Expand Down Expand Up @@ -478,7 +500,7 @@ impl Transaction for TxEnvelope {
}
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
match self {
Self::Legacy(tx) => tx.tx().input(),
Self::Eip2930(tx) => tx.tx().input(),
Expand Down Expand Up @@ -559,6 +581,70 @@ impl Transaction for TxEnvelope {
}
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for TxEnvelope {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
use serde_value::{Value, ValueDeserializer};
struct Visitor;

#[cfg(not(feature = "std"))]
use alloc::collections::BTreeMap;
#[cfg(feature = "std")]
use std::collections::BTreeMap;

impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = (TxType, Value);

fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str("transaction envelope")
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut tx_type = None;
let mut content: BTreeMap<Value, Value> = BTreeMap::new();
while let Some((key, value)) = map.next_entry()? {
match key {
Value::String(key) if key == "type" => {
tx_type = Some(TxType::deserialize(ValueDeserializer::new(value))?);
}
_ => {
content.insert(key, value);
}
}
}

Ok((tx_type.unwrap_or(TxType::Legacy), Value::Map(content)))
}
}

let (tx_type, content) = deserializer.deserialize_map(Visitor)?;
let deserializer = ValueDeserializer::new(content);

match tx_type {
TxType::Legacy => Signed::<TxLegacy>::deserialize(deserializer).map(TxEnvelope::Legacy),
TxType::Eip2930 => {
Signed::<TxEip2930>::deserialize(deserializer).map(TxEnvelope::Eip2930)
}
TxType::Eip1559 => {
Signed::<TxEip1559>::deserialize(deserializer).map(TxEnvelope::Eip1559)
}
TxType::Eip4844 => {
Signed::<TxEip4844Variant>::deserialize(deserializer).map(TxEnvelope::Eip4844)
}
TxType::Eip7702 => {
Signed::<TxEip7702>::deserialize(deserializer).map(TxEnvelope::Eip7702)
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -987,6 +1073,16 @@ mod tests {
test_serde_roundtrip(tx);
}

#[test]
#[cfg(feature = "serde")]
fn test_deser_no_tag() {
let serialized = r#"{"nonce":"0x0","gasPrice":"0x0","gas":"0x0","value":"0x0","input":"0x","r":"0x840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565","s":"0x25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1","yParity":"0x0","hash":"0xdb92c47d1ee601a818ac3bd1517c55fe46a869327f6c11837e003a32f25f71fe"}"#;
let deserialized: TxEnvelope = serde_json::from_str(serialized).unwrap();
let expected =
TxLegacy { ..Default::default() }.into_signed(Signature::test_signature()).into();
assert_eq!(deserialized, expected);
}

#[test]
#[cfg(feature = "serde")]
fn test_serde_roundtrip_eip7702() {
Expand Down
4 changes: 2 additions & 2 deletions crates/consensus/src/transaction/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub struct TxLegacy {
/// this transaction. This is paid up-front, before any
/// computation is done and may not be increased
/// later; formally Tg.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity", rename = "gas"))]
pub gas_limit: u128,
/// The 160-bit address of the message call’s recipient or, for a contract creation
/// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
Expand Down Expand Up @@ -244,7 +244,7 @@ impl Transaction for TxLegacy {
self.value
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
&self.input
}

Expand Down
4 changes: 2 additions & 2 deletions crates/consensus/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::Signed;
use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization};
use alloy_primitives::{keccak256, ChainId, TxKind, B256, U256};
use alloy_primitives::{keccak256, Bytes, ChainId, TxKind, B256, U256};
use core::any;

#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -109,7 +109,7 @@ pub trait Transaction: any::Any + Send + Sync + 'static {
fn value(&self) -> U256;

/// Get `data`.
fn input(&self) -> &[u8];
fn input(&self) -> &Bytes;

/// Returns the transaction type
fn ty(&self) -> u8;
Expand Down
4 changes: 2 additions & 2 deletions crates/consensus/src/transaction/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use alloc::vec::Vec;

use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization};
use alloy_primitives::{ChainId, TxKind, B256};
use alloy_primitives::{Bytes, ChainId, TxKind, B256};

use crate::{
transaction::eip4844::{TxEip4844, TxEip4844Variant, TxEip4844WithSidecar},
Expand Down Expand Up @@ -239,7 +239,7 @@ impl Transaction for TypedTransaction {
}
}

fn input(&self) -> &[u8] {
fn input(&self) -> &Bytes {
match self {
Self::Legacy(tx) => tx.input(),
Self::Eip2930(tx) => tx.input(),
Expand Down
16 changes: 9 additions & 7 deletions crates/contract/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ mod tests {
use alloy_provider::{
layers::AnvilProvider, Provider, ProviderBuilder, RootProvider, WalletProvider,
};
use alloy_rpc_types_eth::AccessListItem;
use alloy_rpc_types_eth::{AccessListItem, TxEnvelope};
use alloy_sol_types::sol;
use alloy_transport_http::Http;
use reqwest::Client;
Expand Down Expand Up @@ -769,20 +769,22 @@ mod tests {
.await
.expect("Could not get the receipt");
let transaction_hash = receipt.transaction_hash;
let transaction = provider
let TxEnvelope::Eip1559(transaction) = provider
.get_transaction_by_hash(transaction_hash)
.await
.expect("failed to fetch tx")
.expect("tx not included");
.expect("tx not included")
.tx
else {
panic!("tx not EIP-1559")
};
assert_eq!(
transaction.max_fee_per_gas.expect("max_fee_per_gas of the transaction should be set"),
transaction.tx().max_fee_per_gas,
max_fee_per_gas.to(),
"max_fee_per_gas of the transaction should be set to the right value"
);
assert_eq!(
transaction
.max_priority_fee_per_gas
.expect("max_priority_fee_per_gas of the transaction should be set"),
transaction.tx().max_priority_fee_per_gas,
max_priority_fee_per_gas.to(),
"max_priority_fee_per_gas of the transaction should be set to the right value"
)
Expand Down
2 changes: 1 addition & 1 deletion crates/network/src/any/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl Network for AnyNetwork {

type TransactionRequest = WithOtherFields<TransactionRequest>;

type TransactionResponse = WithOtherFields<Transaction>;
type TransactionResponse = WithOtherFields<Transaction<alloy_rpc_types_eth::AnyTxEnvelope>>;

type ReceiptResponse = AnyTransactionReceipt;

Expand Down
Loading
Loading