From 55db2dcd4b58011900a452ca002aef8f61860fb0 Mon Sep 17 00:00:00 2001 From: Devon Bear Date: Fri, 10 Nov 2023 18:48:53 -0500 Subject: [PATCH] feat(rpc): add blob support for TransactionRequest (#5382) Co-authored-by: Matthias Seitz --- .../rpc-types/src/eth/transaction/request.rs | 66 +++++++++++++++++-- .../rpc-types/src/eth/transaction/typed.rs | 6 +- crates/rpc/rpc/src/eth/api/transactions.rs | 2 +- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/crates/rpc/rpc-types/src/eth/transaction/request.rs b/crates/rpc/rpc-types/src/eth/transaction/request.rs index 7c82db2b55..ebb9dbaf22 100644 --- a/crates/rpc/rpc-types/src/eth/transaction/request.rs +++ b/crates/rpc/rpc-types/src/eth/transaction/request.rs @@ -1,11 +1,11 @@ use crate::eth::transaction::{ typed::{ - EIP1559TransactionRequest, EIP2930TransactionRequest, LegacyTransactionRequest, - TransactionKind, TypedTransactionRequest, + BlobTransactionSidecar, EIP1559TransactionRequest, EIP2930TransactionRequest, + LegacyTransactionRequest, TransactionKind, TypedTransactionRequest, }, AccessList, }; -use alloy_primitives::{Address, Bytes, U128, U256, U64, U8}; +use alloy_primitives::{Address, Bytes, B256, U128, U256, U64, U8}; use serde::{Deserialize, Serialize}; /// Represents _all_ transaction requests received from RPC @@ -37,6 +37,12 @@ pub struct TransactionRequest { /// EIP-2718 type #[serde(rename = "type", skip_serializing_if = "Option::is_none")] pub transaction_type: Option, + /// max fee per blob gas for EIP-4844 transactions + pub max_fee_per_blob_gas: Option, + /// blob versioned hashes for EIP-4844 transactions. + pub blob_versioned_hashes: Option>, + /// sidecar for EIP-4844 transactions + pub sidecar: Option, } // == impl TransactionRequest == @@ -57,11 +63,22 @@ impl TransactionRequest { input: data, nonce, mut access_list, + max_fee_per_blob_gas, + blob_versioned_hashes, + sidecar, .. } = self; - match (gas_price, max_fee_per_gas, access_list.take()) { + match ( + gas_price, + max_fee_per_gas, + access_list.take(), + max_fee_per_blob_gas, + blob_versioned_hashes, + sidecar, + ) { // legacy transaction - (Some(_), None, None) => { + // gas price required + (Some(_), None, None, None, None, None) => { Some(TypedTransactionRequest::Legacy(LegacyTransactionRequest { nonce: nonce.unwrap_or_default(), gas_price: gas_price.unwrap_or_default(), @@ -76,7 +93,8 @@ impl TransactionRequest { })) } // EIP2930 - (_, None, Some(access_list)) => { + // if only accesslist is set, and no eip1599 fees + (_, None, Some(access_list), None, None, None) => { Some(TypedTransactionRequest::EIP2930(EIP2930TransactionRequest { nonce: nonce.unwrap_or_default(), gas_price: gas_price.unwrap_or_default(), @@ -92,7 +110,10 @@ impl TransactionRequest { })) } // EIP1559 - (None, Some(_), access_list) | (None, None, access_list @ None) => { + // if 4844 fields missing + // gas_price, max_fee_per_gas, access_list, max_fee_per_blob_gas, blob_versioned_hashes, + // sidecar, + (None, _, _, None, None, None) => { // Empty fields fall back to the canonical transaction schema. Some(TypedTransactionRequest::EIP1559(EIP1559TransactionRequest { nonce: nonce.unwrap_or_default(), @@ -109,6 +130,37 @@ impl TransactionRequest { access_list: access_list.unwrap_or_default(), })) } + // EIP4884 + // all blob fields required + ( + None, + _, + _, + Some(max_fee_per_blob_gas), + Some(blob_versioned_hashes), + Some(sidecar), + ) => { + // As per the EIP, we follow the same semantics as EIP-1559. + Some(TypedTransactionRequest::EIP4844(crate::EIP4844TransactionRequest { + chain_id: 0, + nonce: nonce.unwrap_or_default(), + max_priority_fee_per_gas: max_priority_fee_per_gas.unwrap_or_default(), + max_fee_per_gas: max_fee_per_gas.unwrap_or_default(), + gas_limit: gas.unwrap_or_default(), + value: value.unwrap_or_default(), + input: data.unwrap_or_default(), + kind: match to { + Some(to) => TransactionKind::Call(to), + None => TransactionKind::Create, + }, + access_list: access_list.unwrap_or_default(), + + // eip-4844 specific. + max_fee_per_blob_gas, + blob_versioned_hashes, + sidecar, + })) + } _ => None, } diff --git a/crates/rpc/rpc-types/src/eth/transaction/typed.rs b/crates/rpc/rpc-types/src/eth/transaction/typed.rs index 6988872e7b..aad6da8e33 100644 --- a/crates/rpc/rpc-types/src/eth/transaction/typed.rs +++ b/crates/rpc/rpc-types/src/eth/transaction/typed.rs @@ -15,12 +15,13 @@ use serde::{Deserialize, Serialize}; /// 1. Legacy (pre-EIP2718) [`LegacyTransactionRequest`] /// 2. EIP2930 (state access lists) [`EIP2930TransactionRequest`] /// 3. EIP1559 [`EIP1559TransactionRequest`] +/// 4. EIP4844 [`EIP4844TransactionRequest`] #[derive(Debug, Clone, Eq, PartialEq)] pub enum TypedTransactionRequest { Legacy(LegacyTransactionRequest), EIP2930(EIP2930TransactionRequest), EIP1559(EIP1559TransactionRequest), - EIP4844(Eip4844TransactionRequest), + EIP4844(EIP4844TransactionRequest), } /// Represents a legacy transaction request @@ -64,7 +65,7 @@ pub struct EIP1559TransactionRequest { /// Represents an EIP-4844 transaction request #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Eip4844TransactionRequest { +pub struct EIP4844TransactionRequest { pub chain_id: u64, pub nonce: U64, pub max_priority_fee_per_gas: U128, @@ -76,7 +77,6 @@ pub struct Eip4844TransactionRequest { pub access_list: AccessList, pub max_fee_per_blob_gas: U128, pub blob_versioned_hashes: Vec, - pub gas_price: U128, pub sidecar: BlobTransactionSidecar, } diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs index d7d21615e2..6c8cd2f852 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc/src/eth/api/transactions.rs @@ -570,7 +570,7 @@ where Some(TypedTransactionRequest::EIP4844(mut m)) => { m.chain_id = chain_id.to(); m.gas_limit = gas_limit; - m.gas_price = gas_price; + m.max_fee_per_gas = max_fee_per_gas; TypedTransactionRequest::EIP4844(m) }