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

eip4844: use alloy TxEip4844 #10624

Merged
merged 22 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion crates/consensus/common/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,6 @@ mod tests {
max_priority_fee_per_gas: 0x28f000fff,
max_fee_per_blob_gas: 0x7,
gas_limit: 10,
placeholder: Some(()),
to: Address::default(),
value: U256::from(3_u64),
input: Bytes::from(vec![1, 2]),
Expand Down
2 changes: 1 addition & 1 deletion crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ arbitrary = [
"reth-codec",
]
secp256k1 = ["dep:secp256k1"]
c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg", "dep:tempfile", "alloy-eips/kzg"]
c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg", "dep:tempfile", "alloy-eips/kzg", "alloy-consensus/kzg"]
optimism = [
"reth-chainspec/optimism",
"reth-ethereum-forks/optimism",
Expand Down
6 changes: 1 addition & 5 deletions crates/primitives/src/alloy_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,7 @@ impl TryFrom<WithOtherFields<alloy_rpc_types::Transaction>> for Transaction {
max_fee_per_gas: tx
.max_fee_per_gas
.ok_or(ConversionError::MissingMaxFeePerGas)?,
gas_limit: tx
.gas
.try_into()
.map_err(|_| ConversionError::Eip2718Error(RlpError::Overflow.into()))?,
placeholder: tx.to.map(drop),
gas_limit: tx.gas,
to: tx.to.unwrap_or_default(),
value: tx.value,
access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?,
Expand Down
2 changes: 1 addition & 1 deletion crates/primitives/src/transaction/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl FillTxEnv for TransactionSigned {
tx_env.authorization_list = None;
}
Transaction::Eip4844(tx) => {
tx_env.gas_limit = tx.gas_limit;
tx_env.gas_limit = tx.gas_limit as u64;
tx_env.gas_price = U256::from(tx.max_fee_per_gas);
tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas));
tx_env.transact_to = TxKind::Call(tx.to);
Expand Down
325 changes: 1 addition & 324 deletions crates/primitives/src/transaction/eip4844.rs

Large diffs are not rendered by default.

38 changes: 23 additions & 15 deletions crates/primitives/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,12 @@ impl<'a> arbitrary::Arbitrary<'a> for Transaction {
tx.gas_limit = (tx.gas_limit as u64).into();
Self::Eip1559(tx)
}
TxType::Eip4844 => Self::Eip4844(TxEip4844::arbitrary(u)?),
TxType::Eip4844 => {
let mut tx = TxEip4844::arbitrary(u)?;
tx.gas_limit = (tx.gas_limit as u64).into();
Self::Eip4844(tx)
}

TxType::Eip7702 => Self::Eip7702(TxEip7702::arbitrary(u)?),
#[cfg(feature = "optimism")]
TxType::Deposit => Self::Deposit(TxDeposit::arbitrary(u)?),
Expand Down Expand Up @@ -238,7 +243,7 @@ impl Transaction {
Self::Legacy(_) => TxType::Legacy,
Self::Eip2930(_) => TxType::Eip2930,
Self::Eip1559(_) => TxType::Eip1559,
Self::Eip4844(blob_tx) => blob_tx.tx_type(),
Self::Eip4844(_) => TxType::Eip4844,
Self::Eip7702(set_code_tx) => set_code_tx.tx_type(),
#[cfg(feature = "optimism")]
Self::Deposit(deposit_tx) => deposit_tx.tx_type(),
Expand Down Expand Up @@ -302,7 +307,7 @@ impl Transaction {
match self {
Self::Legacy(TxLegacy { gas_limit, .. }) => *gas_limit as u64,
Self::Eip1559(TxEip1559 { gas_limit, .. }) => *gas_limit as u64,
Self::Eip4844(TxEip4844 { gas_limit, .. }) |
Self::Eip4844(TxEip4844 { gas_limit, .. }) => *gas_limit as u64,
Self::Eip7702(TxEip7702 { gas_limit, .. }) => *gas_limit,
Self::Eip2930(TxEip2930 { gas_limit, .. }) => *gas_limit as u64,
#[cfg(feature = "optimism")]
Expand Down Expand Up @@ -536,7 +541,11 @@ impl Transaction {
out,
with_header,
),
Self::Eip4844(blob_tx) => blob_tx.encode_with_signature(signature, out, with_header),
Self::Eip4844(blob_tx) => blob_tx.encode_with_signature(
&signature.as_signature_with_boolean_parity(),
out,
with_header,
),
Self::Eip7702(set_code_tx) => {
set_code_tx.encode_with_signature(signature, out, with_header)
}
Expand All @@ -551,7 +560,7 @@ impl Transaction {
Self::Legacy(tx) => tx.gas_limit = gas_limit.into(),
Self::Eip2930(tx) => tx.gas_limit = gas_limit.into(),
Self::Eip1559(tx) => tx.gas_limit = gas_limit.into(),
Self::Eip4844(tx) => tx.gas_limit = gas_limit,
Self::Eip4844(tx) => tx.gas_limit = gas_limit.into(),
Self::Eip7702(tx) => tx.gas_limit = gas_limit,
#[cfg(feature = "optimism")]
Self::Deposit(tx) => tx.gas_limit = gas_limit,
Expand Down Expand Up @@ -1219,7 +1228,10 @@ impl TransactionSigned {
&self.signature.as_signature_with_boolean_parity(),
true,
),
Transaction::Eip4844(blob_tx) => blob_tx.payload_len_with_signature(&self.signature),
Transaction::Eip4844(blob_tx) => blob_tx.encoded_len_with_signature(
&self.signature.as_signature_with_boolean_parity(),
true,
),
Transaction::Eip7702(set_code_tx) => {
set_code_tx.payload_len_with_signature(&self.signature)
}
Expand Down Expand Up @@ -1348,7 +1360,7 @@ impl TransactionSigned {
let transaction = match tx_type {
TxType::Eip2930 => Transaction::Eip2930(TxEip2930::decode_fields(data)?),
TxType::Eip1559 => Transaction::Eip1559(TxEip1559::decode_fields(data)?),
TxType::Eip4844 => Transaction::Eip4844(TxEip4844::decode_inner(data)?),
TxType::Eip4844 => Transaction::Eip4844(TxEip4844::decode_fields(data)?),
TxType::Eip7702 => Transaction::Eip7702(TxEip7702::decode_inner(data)?),
#[cfg(feature = "optimism")]
TxType::Deposit => Transaction::Deposit(TxDeposit::decode_inner(data)?),
Expand Down Expand Up @@ -1427,9 +1439,10 @@ impl TransactionSigned {
&self.signature.as_signature_with_boolean_parity(),
false,
),
Transaction::Eip4844(blob_tx) => {
blob_tx.payload_len_with_signature_without_header(&self.signature)
}
Transaction::Eip4844(blob_tx) => blob_tx.encoded_len_with_signature(
&self.signature.as_signature_with_boolean_parity(),
false,
),
Transaction::Eip7702(set_code_tx) => {
set_code_tx.payload_len_with_signature_without_header(&self.signature)
}
Expand Down Expand Up @@ -1533,11 +1546,6 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned {
transaction.set_chain_id(chain_id % (u64::MAX / 2 - 36));
}

if let Transaction::Eip4844(ref mut tx_eip_4844) = transaction {
tx_eip_4844.placeholder =
if tx_eip_4844.to == Address::default() { None } else { Some(()) };
}

#[cfg(feature = "optimism")]
// Both `Some(0)` and `None` values are encoded as empty string byte. This introduces
// ambiguity in roundtrip tests. Patch the mint value of deposit transaction here, so that
Expand Down
20 changes: 12 additions & 8 deletions crates/primitives/src/transaction/pooled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
TransactionSigned, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844, TxHash,
TxLegacy, B256, EIP4844_TX_TYPE_ID,
};
use alloy_consensus::SignableTransaction;
use alloy_consensus::{SignableTransaction, TxEip4844WithSidecar};
use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE};
use bytes::Buf;
use derive_more::{AsRef, Deref};
Expand Down Expand Up @@ -102,7 +102,11 @@ impl PooledTransactionsElement {
// If the transaction is an EIP-4844 transaction...
TransactionSigned { transaction: Transaction::Eip4844(tx), signature, hash } => {
// Construct a `PooledTransactionsElement::BlobTransaction` with provided sidecar.
Self::BlobTransaction(BlobTransaction { transaction: tx, signature, hash, sidecar })
Self::BlobTransaction(BlobTransaction {
signature,
hash,
transaction: TxEip4844WithSidecar { tx, sidecar },
})
}
// If the transaction is not EIP-4844, return an error with the original
// transaction.
Expand Down Expand Up @@ -151,7 +155,7 @@ impl PooledTransactionsElement {
Self::Eip2930 { transaction, .. } => transaction.nonce,
Self::Eip1559 { transaction, .. } => transaction.nonce,
Self::Eip7702 { transaction, .. } => transaction.nonce,
Self::BlobTransaction(blob_tx) => blob_tx.transaction.nonce,
Self::BlobTransaction(blob_tx) => blob_tx.transaction.tx.nonce,
}
}

Expand Down Expand Up @@ -416,7 +420,7 @@ impl PooledTransactionsElement {
/// Returns the [`TxEip4844`] variant if the transaction is an EIP-4844 transaction.
pub const fn as_eip4844(&self) -> Option<&TxEip4844> {
match self {
Self::BlobTransaction(tx) => Some(&tx.transaction),
Self::BlobTransaction(tx) => Some(&tx.transaction.tx),
_ => None,
}
}
Expand Down Expand Up @@ -445,7 +449,7 @@ impl PooledTransactionsElement {
/// This is also commonly referred to as the "Blob Gas Fee Cap" (`BlobGasFeeCap`).
pub const fn max_fee_per_blob_gas(&self) -> Option<u128> {
match self {
Self::BlobTransaction(tx) => Some(tx.transaction.max_fee_per_blob_gas),
Self::BlobTransaction(tx) => Some(tx.transaction.tx.max_fee_per_blob_gas),
_ => None,
}
}
Expand All @@ -459,7 +463,7 @@ impl PooledTransactionsElement {
Self::Legacy { .. } | Self::Eip2930 { .. } => None,
Self::Eip1559 { transaction, .. } => Some(transaction.max_priority_fee_per_gas),
Self::Eip7702 { transaction, .. } => Some(transaction.max_priority_fee_per_gas),
Self::BlobTransaction(tx) => Some(tx.transaction.max_priority_fee_per_gas),
Self::BlobTransaction(tx) => Some(tx.transaction.tx.max_priority_fee_per_gas),
}
}

Expand All @@ -472,7 +476,7 @@ impl PooledTransactionsElement {
Self::Eip2930 { transaction, .. } => transaction.gas_price,
Self::Eip1559 { transaction, .. } => transaction.max_fee_per_gas,
Self::Eip7702 { transaction, .. } => transaction.max_fee_per_gas,
Self::BlobTransaction(tx) => tx.transaction.max_fee_per_gas,
Self::BlobTransaction(tx) => tx.transaction.tx.max_fee_per_gas,
}
}
}
Expand Down Expand Up @@ -691,7 +695,7 @@ impl<'a> arbitrary::Arbitrary<'a> for PooledTransactionsElement {
match Self::try_from(tx_signed) {
Ok(Self::BlobTransaction(mut tx)) => {
// Successfully converted to a BlobTransaction, now generate a sidecar.
tx.sidecar = crate::BlobTransactionSidecar::arbitrary(u)?;
tx.transaction.sidecar = crate::BlobTransactionSidecar::arbitrary(u)?;
Ok(Self::BlobTransaction(tx))
}
Ok(tx) => Ok(tx), // Successfully converted, but not a BlobTransaction.
Expand Down
68 changes: 24 additions & 44 deletions crates/primitives/src/transaction/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
use crate::{
keccak256, Signature, Transaction, TransactionSigned, TxEip4844, TxHash, EIP4844_TX_TYPE_ID,
};
use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header};
use alloy_consensus::TxEip4844WithSidecar;
use alloy_rlp::{Decodable, Error as RlpError, Header};
use serde::{Deserialize, Serialize};

#[doc(inline)]
Expand All @@ -24,12 +25,10 @@ use alloc::vec::Vec;
pub struct BlobTransaction {
/// The transaction hash.
pub hash: TxHash,
/// The transaction payload.
pub transaction: TxEip4844,
/// The transaction signature.
pub signature: Signature,
/// The transaction's blob sidecar.
pub sidecar: BlobTransactionSidecar,
/// The transaction payload with the sidecar.
pub transaction: TxEip4844WithSidecar,
}

impl BlobTransaction {
Expand All @@ -43,7 +42,11 @@ impl BlobTransaction {
) -> Result<Self, (TransactionSigned, BlobTransactionSidecar)> {
let TransactionSigned { transaction, signature, hash } = tx;
match transaction {
Transaction::Eip4844(transaction) => Ok(Self { hash, transaction, signature, sidecar }),
Transaction::Eip4844(transaction) => Ok(Self {
hash,
transaction: TxEip4844WithSidecar { tx: transaction, sidecar },
signature,
}),
transaction => {
let tx = TransactionSigned { transaction, signature, hash };
Err((tx, sidecar))
Expand All @@ -59,19 +62,19 @@ impl BlobTransaction {
&self,
proof_settings: &c_kzg::KzgSettings,
) -> Result<(), BlobTransactionValidationError> {
self.transaction.validate_blob(&self.sidecar, proof_settings)
self.transaction.validate_blob(proof_settings)
}

/// Splits the [`BlobTransaction`] into its [`TransactionSigned`] and [`BlobTransactionSidecar`]
/// components.
pub fn into_parts(self) -> (TransactionSigned, BlobTransactionSidecar) {
let transaction = TransactionSigned {
transaction: Transaction::Eip4844(self.transaction),
transaction: Transaction::Eip4844(self.transaction.tx),
hash: self.hash,
signature: self.signature,
};

(transaction, self.sidecar)
(transaction, self.transaction.sidecar)
}

/// Encodes the [`BlobTransaction`] fields as RLP, with a tx type. If `with_header` is `false`,
Expand Down Expand Up @@ -111,36 +114,8 @@ impl BlobTransaction {
/// Note: this should be used only when implementing other RLP encoding methods, and does not
/// represent the full RLP encoding of the blob transaction.
pub(crate) fn encode_inner(&self, out: &mut dyn bytes::BufMut) {
// First we construct both required list headers.
//
// The `transaction_payload_body` length is the length of the fields, plus the length of
// its list header.
let tx_header = Header {
list: true,
payload_length: self.transaction.fields_len() + self.signature.payload_len(),
};

let tx_length = tx_header.length() + tx_header.payload_length;

// The payload length is the length of the `tranascation_payload_body` list, plus the
// length of the blobs, commitments, and proofs.
let payload_length = tx_length + self.sidecar.fields_len();

// First we use the payload len to construct the first list header
let blob_tx_header = Header { list: true, payload_length };

// Encode the blob tx header first
blob_tx_header.encode(out);

// Encode the inner tx list header, then its fields
tx_header.encode(out);
self.transaction.encode_fields(out);

// Encode the signature
self.signature.encode(out);

// Encode the blobs, commitments, and proofs
self.sidecar.encode(out);
self.transaction
.encode_with_signature_fields(&self.signature.as_signature_with_boolean_parity(), out);
}

/// Outputs the length of the RLP encoding of the blob transaction, including the tx type byte,
Expand Down Expand Up @@ -181,14 +156,14 @@ impl BlobTransaction {
// its list header.
let tx_header = Header {
list: true,
payload_length: self.transaction.fields_len() + self.signature.payload_len(),
payload_length: self.transaction.tx.fields_len() + self.signature.payload_len(),
};

let tx_length = tx_header.length() + tx_header.payload_length;

// The payload length is the length of the `tranascation_payload_body` list, plus the
// length of the blobs, commitments, and proofs.
let payload_length = tx_length + self.sidecar.fields_len();
let payload_length = tx_length + self.transaction.sidecar.fields_len();

// We use the calculated payload len to construct the first list header, which encompasses
// everything in the tx - the length of the second, inner list header is part of
Expand Down Expand Up @@ -234,7 +209,7 @@ impl BlobTransaction {
let inner_remaining_len = data.len();

// inner transaction
let transaction = TxEip4844::decode_inner(data)?;
let transaction = TxEip4844::decode(data)?;

// signature
let signature = Signature::decode(data)?;
Expand Down Expand Up @@ -265,7 +240,11 @@ impl BlobTransaction {
// Instead, we use `encode_with_signature`, which RLP encodes the transaction with a
// signature for hashing without a header. We then hash the result.
let mut buf = Vec::new();
transaction.encode_with_signature(&signature, &mut buf, false);
transaction.encode_with_signature(
&signature.as_signature_with_boolean_parity(),
&mut buf,
false,
);
let hash = keccak256(&buf);

// the outer header is for the entire transaction, so we check the length here
Expand All @@ -274,7 +253,7 @@ impl BlobTransaction {
return Err(RlpError::UnexpectedLength)
}

Ok(Self { transaction, hash, signature, sidecar })
Ok(Self { transaction: TxEip4844WithSidecar { tx: transaction, sidecar }, hash, signature })
}
}

Expand Down Expand Up @@ -311,6 +290,7 @@ mod tests {
use super::*;
use crate::{hex, kzg::Blob};
use alloy_eips::eip4844::Bytes48;
use alloy_rlp::Encodable;
use std::{fs, path::PathBuf, str::FromStr};

#[test]
Expand Down
1 change: 0 additions & 1 deletion crates/rpc/rpc-types-compat/src/transaction/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ pub fn to_primitive_transaction(
gas_limit: tx.gas_limit.to(),
max_fee_per_gas: tx.max_fee_per_gas.to(),
max_priority_fee_per_gas: tx.max_priority_fee_per_gas.to(),
placeholder: Some(()),
to: tx.to,
value: tx.value,
access_list: tx.access_list,
Expand Down
2 changes: 1 addition & 1 deletion crates/rpc/rpc/src/eth/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ where
.iter()
.filter_map(|(tx, _)| {
if let PooledTransactionsElement::BlobTransaction(tx) = tx {
Some(tx.transaction.blob_gas())
Some(tx.transaction.tx.blob_gas())
} else {
None
}
Expand Down
Loading
Loading