feat: impl Encodable2718 and Decodable2718 for PooledTransactionsElement (#11482)

This commit is contained in:
Arsenii Kulikov
2024-10-08 18:33:31 +04:00
committed by GitHub
parent c61ae1371b
commit e18b0bab90
11 changed files with 150 additions and 279 deletions

1
Cargo.lock generated
View File

@ -7146,6 +7146,7 @@ dependencies = [
name = "reth-eth-wire"
version = "1.0.8"
dependencies = [
"alloy-eips",
"alloy-primitives",
"alloy-rlp",
"arbitrary",

View File

@ -194,7 +194,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
)
.expect("should not fail to convert blob tx if it is already eip4844");
let pooled = PooledTransactionsElement::BlobTransaction(tx);
let encoded_length = pooled.length_without_header();
let encoded_length = pooled.encode_2718_len();
// insert the blob into the store
blob_store.insert(transaction.hash, sidecar)?;

View File

@ -62,6 +62,7 @@ proptest.workspace = true
proptest-arbitrary-interop.workspace = true
async-stream.workspace = true
serde.workspace = true
alloy-eips.workspace = true
[features]
arbitrary = [

View File

@ -1,5 +1,6 @@
//! Decoding tests for [`PooledTransactions`]
use alloy_eips::eip2718::Decodable2718;
use alloy_primitives::hex;
use alloy_rlp::{Decodable, Encodable};
use reth_eth_wire::{EthVersion, PooledTransactions, ProtocolMessage};
@ -72,5 +73,5 @@ fn decode_blob_rpc_transaction() {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/rpc_blob_transaction");
let data = fs::read_to_string(network_data_path).expect("Unable to read file");
let hex_data = hex::decode(data.trim()).unwrap();
let _txs = PooledTransactionsElement::decode_enveloped(&mut hex_data.as_ref()).unwrap();
let _txs = PooledTransactionsElement::decode_2718(&mut hex_data.as_ref()).unwrap();
}

View File

@ -10,14 +10,13 @@ use crate::{
BlobTransaction, BlobTransactionSidecar, Signature, Transaction, TransactionSigned,
TransactionSignedEcRecovered, EIP4844_TX_TYPE_ID,
};
use alloc::vec::Vec;
use alloy_consensus::{
transaction::{TxEip1559, TxEip2930, TxEip4844, TxLegacy},
SignableTransaction, TxEip4844WithSidecar,
};
use alloy_eips::eip2718::{Decodable2718, Eip2718Error};
use alloy_primitives::{Address, Bytes, TxHash, B256};
use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE};
use alloy_eips::eip2718::{Decodable2718, Eip2718Result, Encodable2718};
use alloy_primitives::{Address, TxHash, B256};
use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header};
use bytes::Buf;
use derive_more::{AsRef, Deref};
use serde::{Deserialize, Serialize};
@ -183,101 +182,6 @@ impl PooledTransactionsElement {
}
}
/// Decodes the "raw" format of transaction (e.g. `eth_sendRawTransaction`).
///
/// This should be used for `eth_sendRawTransaction`, for any transaction type. Blob
/// transactions **must** include the blob sidecar as part of the raw encoding.
///
/// This method can not be used for decoding the `transactions` field of `engine_newPayload`,
/// because EIP-4844 transactions for that method do not include the blob sidecar. The blobs
/// are supplied in an argument separate from the payload.
///
/// A raw transaction is either a legacy transaction or EIP-2718 typed transaction, with a
/// special case for EIP-4844 transactions.
///
/// For legacy transactions, the format is encoded as: `rlp(tx)`. This format will start with a
/// RLP list header.
///
/// For EIP-2718 typed transactions, the format is encoded as the type of the transaction
/// followed by the rlp of the transaction: `type || rlp(tx)`.
///
/// For EIP-4844 transactions, the format includes a blob sidecar (the blobs, commitments, and
/// proofs) after the transaction:
/// `type || rlp([tx_payload_body, blobs, commitments, proofs])`
///
/// Where `tx_payload_body` is encoded as a RLP list:
/// `[chain_id, nonce, max_priority_fee_per_gas, ..., y_parity, r, s]`
pub fn decode_enveloped(data: &mut &[u8]) -> alloy_rlp::Result<Self> {
if data.is_empty() {
return Err(RlpError::InputTooShort)
}
// Check if the tx is a list - tx types are less than EMPTY_LIST_CODE (0xc0)
if data[0] >= EMPTY_LIST_CODE {
// decode as legacy transaction
let (transaction, hash, signature) =
TransactionSigned::decode_rlp_legacy_transaction_tuple(data)?;
Ok(Self::Legacy { transaction, signature, hash })
} else {
// decode the type byte, only decode BlobTransaction if it is a 4844 transaction
let tx_type = *data.first().ok_or(RlpError::InputTooShort)?;
// First, we advance the buffer past the type byte
data.advance(1);
if tx_type == EIP4844_TX_TYPE_ID {
// Recall that the blob transaction response `TransactionPayload` is encoded like
// this: `rlp([tx_payload_body, blobs, commitments, proofs])`
//
// Note that `tx_payload_body` is a list:
// `[chain_id, nonce, max_priority_fee_per_gas, ..., y_parity, r, s]`
//
// This makes the full encoding:
// `tx_type (0x03) || rlp([[chain_id, nonce, ...], blobs, commitments, proofs])`
// Now, we decode the inner blob transaction:
// `rlp([[chain_id, nonce, ...], blobs, commitments, proofs])`
let blob_tx = BlobTransaction::decode_inner(data)?;
Ok(Self::BlobTransaction(blob_tx))
} else {
let typed_tx =
TransactionSigned::typed_decode(tx_type, data).map_err(|err| match err {
Eip2718Error::RlpError(err) => err,
_ => RlpError::Custom("failed to decode EIP-2718 transaction"),
})?;
// because we checked the tx type, we can be sure that the transaction is not a
// blob transaction or legacy
match typed_tx.transaction {
Transaction::Legacy(_) => Err(RlpError::Custom(
"legacy transactions should not be a result of EIP-2718 decoding",
)),
Transaction::Eip4844(_) => Err(RlpError::Custom(
"EIP-4844 transactions can only be decoded with transaction type 0x03",
)),
Transaction::Eip2930(tx) => Ok(Self::Eip2930 {
transaction: tx,
signature: typed_tx.signature,
hash: typed_tx.hash,
}),
Transaction::Eip1559(tx) => Ok(Self::Eip1559 {
transaction: tx,
signature: typed_tx.signature,
hash: typed_tx.hash,
}),
Transaction::Eip7702(tx) => {Ok(Self::Eip7702 {
transaction: tx,
signature: typed_tx.signature,
hash: typed_tx.hash,
})},
#[cfg(feature = "optimism")]
Transaction::Deposit(_) => Err(RlpError::Custom("Optimism deposit transaction cannot be decoded to PooledTransactionsElement"))
}
}
}
}
/// Create [`TransactionSignedEcRecovered`] by converting this transaction into
/// [`TransactionSigned`] and [`Address`] of the signer.
pub fn into_ecrecovered_transaction(self, signer: Address) -> TransactionSignedEcRecovered {
@ -309,83 +213,6 @@ impl PooledTransactionsElement {
}
}
/// Returns the length without an RLP header - this is used for eth/68 sizes.
pub fn length_without_header(&self) -> usize {
match self {
Self::Legacy { transaction, signature, .. } => {
// method computes the payload len with a RLP header
transaction.encoded_len_with_signature(&with_eip155_parity(
signature,
transaction.chain_id,
))
}
Self::Eip2930 { transaction, signature, .. } => {
// method computes the payload len without a RLP header
transaction.encoded_len_with_signature(signature, false)
}
Self::Eip1559 { transaction, signature, .. } => {
// method computes the payload len without a RLP header
transaction.encoded_len_with_signature(signature, false)
}
Self::Eip7702 { transaction, signature, .. } => {
// method computes the payload len without a RLP header
transaction.encoded_len_with_signature(signature, false)
}
Self::BlobTransaction(blob_tx) => {
// the encoding does not use a header, so we set `with_header` to false
blob_tx.payload_len_with_type(false)
}
}
}
/// Returns the enveloped encoded transactions.
///
/// See also [`alloy_eips::eip2718::Encodable2718::encoded_2718`]
pub fn envelope_encoded(&self) -> Bytes {
let mut buf = Vec::new();
self.encode_enveloped(&mut buf);
buf.into()
}
/// Encodes the transaction into the "raw" format (e.g. `eth_sendRawTransaction`).
/// This format is also referred to as "binary" encoding.
///
/// For legacy transactions, it encodes the RLP of the transaction into the buffer:
/// `rlp(tx-data)`
/// For EIP-2718 typed it encodes the type of the transaction followed by the rlp of the
/// transaction: `tx-type || rlp(tx-data)`
pub fn encode_enveloped(&self, out: &mut dyn bytes::BufMut) {
// The encoding of `tx-data` depends on the transaction type. Refer to these docs for more
// information on the exact format:
// - Legacy: TxLegacy::encode_with_signature
// - EIP-2930: TxEip2930::encode_with_signature
// - EIP-1559: TxEip1559::encode_with_signature
// - EIP-4844: BlobTransaction::encode_with_type_inner
// - EIP-7702: TxEip7702::encode_with_signature
match self {
Self::Legacy { transaction, signature, .. } => transaction
.encode_with_signature_fields(
&with_eip155_parity(signature, transaction.chain_id),
out,
),
Self::Eip2930 { transaction, signature, .. } => {
transaction.encode_with_signature(signature, out, false)
}
Self::Eip1559 { transaction, signature, .. } => {
transaction.encode_with_signature(signature, out, false)
}
Self::Eip7702 { transaction, signature, .. } => {
transaction.encode_with_signature(signature, out, false)
}
Self::BlobTransaction(blob_tx) => {
// The inner encoding is used with `with_header` set to true, making the final
// encoding:
// `tx_type || rlp([transaction_payload_body, blobs, commitments, proofs]))`
blob_tx.encode_with_type_inner(out, false);
}
}
}
/// Returns true if the transaction is an EIP-4844 transaction.
#[inline]
pub const fn is_eip4844(&self) -> bool {
@ -481,73 +308,25 @@ impl PooledTransactionsElement {
}
impl Encodable for PooledTransactionsElement {
/// Encodes an enveloped post EIP-4844 [`PooledTransactionsElement`].
/// This encodes the transaction _with_ the signature, and an rlp header.
///
/// For legacy transactions, this encodes the transaction as `rlp(tx-data)`.
/// For legacy transactions, it encodes the transaction data:
/// `rlp(tx-data)`
///
/// For EIP-2718 transactions, this encodes the transaction as `rlp(tx_type || rlp(tx-data)))`,
/// ___including__ the RLP-header for the entire transaction.
/// For EIP-2718 typed transactions, it encodes the transaction type followed by the rlp of the
/// transaction:
/// `rlp(tx-type || rlp(tx-data))`
fn encode(&self, out: &mut dyn bytes::BufMut) {
// The encoding of `tx-data` depends on the transaction type. Refer to these docs for more
// information on the exact format:
// - Legacy: TxLegacy::encode_with_signature
// - EIP-2930: TxEip2930::encode_with_signature
// - EIP-1559: TxEip1559::encode_with_signature
// - EIP-4844: BlobTransaction::encode_with_type_inner
// - EIP-7702: TxEip7702::encode_with_signature
match self {
Self::Legacy { transaction, signature, .. } => transaction
.encode_with_signature_fields(
&with_eip155_parity(signature, transaction.chain_id),
out,
),
Self::Eip2930 { transaction, signature, .. } => {
// encodes with string header
transaction.encode_with_signature(signature, out, true)
}
Self::Eip1559 { transaction, signature, .. } => {
// encodes with string header
transaction.encode_with_signature(signature, out, true)
}
Self::Eip7702 { transaction, signature, .. } => {
// encodes with string header
transaction.encode_with_signature(signature, out, true)
}
Self::BlobTransaction(blob_tx) => {
// The inner encoding is used with `with_header` set to true, making the final
// encoding:
// `rlp(tx_type || rlp([transaction_payload_body, blobs, commitments, proofs]))`
blob_tx.encode_with_type_inner(out, true);
}
}
self.network_encode(out);
}
fn length(&self) -> usize {
match self {
Self::Legacy { transaction, signature, .. } => {
// method computes the payload len with a RLP header
transaction.encoded_len_with_signature(&with_eip155_parity(
signature,
transaction.chain_id,
))
}
Self::Eip2930 { transaction, signature, .. } => {
// method computes the payload len with a RLP header
transaction.encoded_len_with_signature(signature, true)
}
Self::Eip1559 { transaction, signature, .. } => {
// method computes the payload len with a RLP header
transaction.encoded_len_with_signature(signature, true)
}
Self::Eip7702 { transaction, signature, .. } => {
// method computes the payload len with a RLP header
transaction.encoded_len_with_signature(signature, true)
}
Self::BlobTransaction(blob_tx) => {
// the encoding uses a header, so we set `with_header` to true
blob_tx.payload_len_with_type(true)
}
let mut payload_length = self.encode_2718_len();
if !self.is_legacy() {
payload_length += Header { list: false, payload_length }.length();
}
payload_length
}
}
@ -581,23 +360,110 @@ impl Decodable for PooledTransactionsElement {
// Check if the tx is a list
if header.list {
// decode as legacy transaction
let (transaction, hash, signature) =
TransactionSigned::decode_rlp_legacy_transaction_tuple(&mut original_encoding)?;
let tx = Self::fallback_decode(&mut original_encoding)?;
// advance the buffer by however long the legacy transaction decoding advanced the
// buffer
*buf = original_encoding;
Ok(Self::Legacy { transaction, signature, hash })
Ok(tx)
} else {
// decode the type byte, only decode BlobTransaction if it is a 4844 transaction
let tx_type = *buf.first().ok_or(RlpError::InputTooShort)?;
let remaining_len = buf.len();
// Aadvance the buffer past the type byte
// Advance the buffer past the type byte
buf.advance(1);
if tx_type == EIP4844_TX_TYPE_ID {
let tx = Self::typed_decode(tx_type, buf).map_err(RlpError::from)?;
// check that the bytes consumed match the payload length
let bytes_consumed = remaining_len - buf.len();
if bytes_consumed != header.payload_length {
return Err(RlpError::UnexpectedLength)
}
Ok(tx)
}
}
}
impl Encodable2718 for PooledTransactionsElement {
fn type_flag(&self) -> Option<u8> {
match self {
Self::Legacy { .. } => None,
Self::Eip2930 { .. } => Some(0x01),
Self::Eip1559 { .. } => Some(0x02),
Self::BlobTransaction { .. } => Some(0x03),
Self::Eip7702 { .. } => Some(0x04),
}
}
fn encode_2718_len(&self) -> usize {
match self {
Self::Legacy { transaction, signature, .. } => {
// method computes the payload len with a RLP header
transaction.encoded_len_with_signature(&with_eip155_parity(
signature,
transaction.chain_id,
))
}
Self::Eip2930 { transaction, signature, .. } => {
// method computes the payload len without a RLP header
transaction.encoded_len_with_signature(signature, false)
}
Self::Eip1559 { transaction, signature, .. } => {
// method computes the payload len without a RLP header
transaction.encoded_len_with_signature(signature, false)
}
Self::Eip7702 { transaction, signature, .. } => {
// method computes the payload len without a RLP header
transaction.encoded_len_with_signature(signature, false)
}
Self::BlobTransaction(blob_tx) => {
// the encoding does not use a header, so we set `with_header` to false
blob_tx.payload_len_with_type(false)
}
}
}
fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) {
// The encoding of `tx-data` depends on the transaction type. Refer to these docs for more
// information on the exact format:
// - Legacy: TxLegacy::encode_with_signature
// - EIP-2930: TxEip2930::encode_with_signature
// - EIP-1559: TxEip1559::encode_with_signature
// - EIP-4844: BlobTransaction::encode_with_type_inner
// - EIP-7702: TxEip7702::encode_with_signature
match self {
Self::Legacy { transaction, signature, .. } => transaction
.encode_with_signature_fields(
&with_eip155_parity(signature, transaction.chain_id),
out,
),
Self::Eip2930 { transaction, signature, .. } => {
transaction.encode_with_signature(signature, out, false)
}
Self::Eip1559 { transaction, signature, .. } => {
transaction.encode_with_signature(signature, out, false)
}
Self::Eip7702 { transaction, signature, .. } => {
transaction.encode_with_signature(signature, out, false)
}
Self::BlobTransaction(blob_tx) => {
// The inner encoding is used with `with_header` set to true, making the final
// encoding:
// `tx_type || rlp([transaction_payload_body, blobs, commitments, proofs]))`
blob_tx.encode_with_type_inner(out, false);
}
}
}
}
impl Decodable2718 for PooledTransactionsElement {
fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result<Self> {
match ty {
EIP4844_TX_TYPE_ID => {
// Recall that the blob transaction response `TransactionPayload` is encoded like
// this: `rlp([tx_payload_body, blobs, commitments, proofs])`
//
@ -607,36 +473,23 @@ impl Decodable for PooledTransactionsElement {
// This makes the full encoding:
// `tx_type (0x03) || rlp([[chain_id, nonce, ...], blobs, commitments, proofs])`
// Decode the inner blob transaction:
// Now, we decode the inner blob transaction:
// `rlp([[chain_id, nonce, ...], blobs, commitments, proofs])`
let blob_tx = BlobTransaction::decode_inner(buf)?;
// check that the bytes consumed match the payload length
let bytes_consumed = remaining_len - buf.len();
if bytes_consumed != header.payload_length {
return Err(RlpError::UnexpectedLength)
}
Ok(Self::BlobTransaction(blob_tx))
} else {
let typed_tx =
TransactionSigned::typed_decode(tx_type, buf).map_err(RlpError::from)?;
}
tx_type => {
let typed_tx = TransactionSigned::typed_decode(tx_type, buf)?;
// check that the bytes consumed match the payload length
let bytes_consumed = remaining_len - buf.len();
if bytes_consumed != header.payload_length {
return Err(RlpError::UnexpectedLength)
}
// because we checked the tx type, we can be sure that the transaction is not a
// blob transaction or legacy
match typed_tx.transaction {
Transaction::Legacy(_) => Err(RlpError::Custom(
"legacy transactions should not be a result of EIP-2718 decoding",
)),
"legacy transactions should not be a result of typed decoding",
).into()),
// because we checked the tx type, we can be sure that the transaction is not a
// blob transaction
Transaction::Eip4844(_) => Err(RlpError::Custom(
"EIP-4844 transactions can only be decoded with transaction type 0x03",
)),
).into()),
Transaction::Eip2930(tx) => Ok(Self::Eip2930 {
transaction: tx,
signature: typed_tx.signature,
@ -653,11 +506,19 @@ impl Decodable for PooledTransactionsElement {
hash: typed_tx.hash,
}),
#[cfg(feature = "optimism")]
Transaction::Deposit(_) => Err(RlpError::Custom("Optimism deposit transaction cannot be decoded to PooledTransactionsElement"))
Transaction::Deposit(_) => Err(RlpError::Custom("Optimism deposit transaction cannot be decoded to PooledTransactionsElement").into())
}
}
}
}
fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result<Self> {
// decode as legacy transaction
let (transaction, hash, signature) =
TransactionSigned::decode_rlp_legacy_transaction_tuple(buf)?;
Ok(Self::Legacy { transaction, signature, hash })
}
}
impl TryFrom<TransactionSigned> for PooledTransactionsElement {
@ -773,6 +634,7 @@ mod tests {
use super::*;
use alloy_primitives::{address, hex};
use assert_matches::assert_matches;
use bytes::Bytes;
#[test]
fn invalid_legacy_pooled_decoding_input_too_short() {
@ -804,7 +666,7 @@ mod tests {
// this is a legacy tx so we can attempt the same test with decode_enveloped
let input_rlp = &mut &hex_data[..];
let res = PooledTransactionsElement::decode_enveloped(input_rlp);
let res = PooledTransactionsElement::decode_2718(input_rlp);
assert!(
res.is_err(),
@ -820,7 +682,7 @@ mod tests {
let data = hex!("02f903d382426882ba09832dc6c0848674742682ed9694714b6a4ea9b94a8a7d9fd362ed72630688c8898c80b90364492d24749189822d8512430d3f3ff7a2ede675ac08265c08e2c56ff6fdaa66dae1cdbe4a5d1d7809f3e99272d067364e597542ac0c369d69e22a6399c3e9bee5da4b07e3f3fdc34c32c3d88aa2268785f3e3f8086df0934b10ef92cfffc2e7f3d90f5e83302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000546e00000000000000000000000000000000000000000000000000000000000e4e1c00000000000000000000000000000000000000000000000000000000065d6750c00000000000000000000000000000000000000000000000000000000000f288000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cf600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000f1628e56fa6d8c50e5b984a58c0df14de31c7b857ce7ba499945b99252976a93d06dcda6776fc42167fbe71cb59f978f5ef5b12577a90b132d14d9c6efa528076f0161d7bf03643cfc5490ec5084f4a041db7f06c50bd97efa08907ba79ddcac8b890f24d12d8db31abbaaf18985d54f400449ee0559a4452afe53de5853ce090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a01428023fc54a27544abc421d5d017b9a7c5936ad501cbdecd0d9d12d04c1a033a0753104bbf1c87634d6ff3f0ffa0982710612306003eb022363b57994bdef445a"
);
let res = PooledTransactionsElement::decode_enveloped(&mut &data[..]).unwrap();
let res = PooledTransactionsElement::decode_2718(&mut &data[..]).unwrap();
assert_eq!(
res.into_transaction().to(),
Some(address!("714b6a4ea9b94a8a7d9fd362ed72630688c8898c"))
@ -854,7 +716,7 @@ mod tests {
assert!(input_rlp.is_empty());
// we can also decode_enveloped
let res = PooledTransactionsElement::decode_enveloped(&mut &data[..]);
let res = PooledTransactionsElement::decode_2718(&mut &data[..]);
assert_matches!(res, Ok(_tx));
}
}

View File

@ -283,7 +283,10 @@ pub fn generate_blob_sidecar(blobs: Vec<c_kzg::Blob>) -> BlobTransactionSidecar
mod tests {
use super::*;
use crate::{kzg::Blob, PooledTransactionsElement};
use alloy_eips::eip4844::Bytes48;
use alloy_eips::{
eip2718::{Decodable2718, Encodable2718},
eip4844::Bytes48,
};
use alloy_primitives::hex;
use alloy_rlp::Encodable;
use std::{fs, path::PathBuf, str::FromStr};
@ -435,15 +438,15 @@ mod tests {
let entry = entry.unwrap();
let content = fs::read_to_string(entry.path()).unwrap();
let raw = hex::decode(content.trim()).unwrap();
let tx = PooledTransactionsElement::decode_enveloped(&mut raw.as_ref())
let tx = PooledTransactionsElement::decode_2718(&mut raw.as_ref())
.map_err(|err| {
panic!("Failed to decode transaction: {:?} {:?}", err, entry.path());
})
.unwrap();
// We want to test only EIP-4844 transactions
assert!(tx.is_eip4844());
let encoded = tx.envelope_encoded();
assert_eq!(encoded.as_ref(), &raw[..], "{:?}", entry.path());
let encoded = tx.encoded_2718();
assert_eq!(encoded.as_slice(), &raw[..], "{:?}", entry.path());
}
}
}

View File

@ -97,7 +97,7 @@ pub trait EthTransactions: LoadTransaction {
async move {
// Note: this is mostly used to fetch pooled transactions so we check the pool first
if let Some(tx) =
self.pool().get_pooled_transaction_element(hash).map(|tx| tx.envelope_encoded())
self.pool().get_pooled_transaction_element(hash).map(|tx| tx.encoded_2718().into())
{
return Ok(Some(tx))
}

View File

@ -1,5 +1,6 @@
//! Commonly used code snippets
use alloy_eips::eip2718::Decodable2718;
use alloy_primitives::Bytes;
use reth_primitives::{PooledTransactionsElement, PooledTransactionsElementEcRecovered};
use std::future::Future;
@ -8,13 +9,13 @@ use super::{EthApiError, EthResult};
/// Recovers a [`PooledTransactionsElementEcRecovered`] from an enveloped encoded byte stream.
///
/// See [`PooledTransactionsElement::decode_enveloped`]
/// See [`Decodable2718::decode_2718`]
pub fn recover_raw_transaction(data: Bytes) -> EthResult<PooledTransactionsElementEcRecovered> {
if data.is_empty() {
return Err(EthApiError::EmptyRawTransactionData)
}
let transaction = PooledTransactionsElement::decode_enveloped(&mut data.as_ref())
let transaction = PooledTransactionsElement::decode_2718(&mut data.as_ref())
.map_err(|_| EthApiError::FailedToDecodeSignedTransaction)?;
transaction.try_into_ecrecovered().or(Err(EthApiError::InvalidTransactionSignature))

View File

@ -676,6 +676,7 @@ mod tests {
blobstore::InMemoryBlobStore, validate::EthTransactionValidatorBuilder,
CoinbaseTipOrdering, EthPooledTransaction, Pool, TransactionOrigin,
};
use alloy_eips::eip2718::Decodable2718;
use alloy_primitives::{hex, U256};
use reth_chainspec::MAINNET;
use reth_fs_util as fs;
@ -699,7 +700,7 @@ mod tests {
let temp_dir = tempfile::tempdir().unwrap();
let transactions_path = temp_dir.path().join(FILENAME).with_extension(EXTENSION);
let tx_bytes = hex!("02f87201830655c2808505ef61f08482565f94388c818ca8b9251b393131c08a736a67ccb192978801049e39c4b5b1f580c001a01764ace353514e8abdfb92446de356b260e3c1225b73fc4c8876a6258d12a129a04f02294aa61ca7676061cd99f29275491218b4754b46a0248e5e42bc5091f507");
let tx = PooledTransactionsElement::decode_enveloped(&mut &tx_bytes[..]).unwrap();
let tx = PooledTransactionsElement::decode_2718(&mut &tx_bytes[..]).unwrap();
let provider = MockEthProvider::default();
let transaction: EthPooledTransaction = tx.try_into_ecrecovered().unwrap().into();
let tx_to_cmp = transaction.clone();

View File

@ -1051,7 +1051,7 @@ impl EthPooledTransaction {
/// Conversion from the network transaction type to the pool transaction type.
impl From<PooledTransactionsElementEcRecovered> for EthPooledTransaction {
fn from(tx: PooledTransactionsElementEcRecovered) -> Self {
let encoded_length = tx.length_without_header();
let encoded_length = tx.encode_2718_len();
let (tx, signer) = tx.into_components();
match tx {
PooledTransactionsElement::BlobTransaction(tx) => {

File diff suppressed because one or more lines are too long