From 234d258ce75de9be410ad0b4cb316caf5c3436c7 Mon Sep 17 00:00:00 2001 From: Abner Zheng Date: Sat, 13 Apr 2024 01:05:12 +0800 Subject: [PATCH] feat: impl TryFrom for Transaction (#7551) --- Cargo.lock | 35 ++++----- Cargo.toml | 24 +++--- crates/primitives/src/transaction/mod.rs | 97 ++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ce28f6856..55deaa145f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,7 +146,7 @@ dependencies = [ [[package]] name = "alloy-consensus" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-eips", "alloy-primitives", @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "alloy-eips" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -196,7 +196,7 @@ dependencies = [ [[package]] name = "alloy-genesis" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-primitives", "alloy-serde", @@ -218,18 +218,19 @@ dependencies = [ [[package]] name = "alloy-json-rpc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-primitives", "serde", "serde_json", "thiserror", + "tracing", ] [[package]] name = "alloy-network" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -245,7 +246,7 @@ dependencies = [ [[package]] name = "alloy-node-bindings" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -287,7 +288,7 @@ dependencies = [ [[package]] name = "alloy-provider" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -337,7 +338,7 @@ dependencies = [ [[package]] name = "alloy-rpc-client" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -357,7 +358,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -379,7 +380,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -397,7 +398,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -409,7 +410,7 @@ dependencies = [ [[package]] name = "alloy-serde" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-primitives", "serde", @@ -419,7 +420,7 @@ dependencies = [ [[package]] name = "alloy-signer" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-primitives", "async-trait", @@ -432,7 +433,7 @@ dependencies = [ [[package]] name = "alloy-signer-wallet" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-consensus", "alloy-network", @@ -507,7 +508,7 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-json-rpc", "base64 0.22.0", @@ -525,7 +526,7 @@ dependencies = [ [[package]] name = "alloy-transport-http" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=987b393#987b3936f78c067baedcf811620975d3a4a26443" +source = "git+https://github.com/alloy-rs/alloy?rev=7629f79#7629f79e3ffb6abd0be901a06deed2ab9f695e4e" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -7536,7 +7537,7 @@ dependencies = [ [[package]] name = "revm-inspectors" version = "0.1.0" -source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=21f8f3d#21f8f3d266b05d1084e06f0c5331f2f1f4ed0905" +source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=413b892#413b892dd936d117c52d47ba07d195b09a7f1216" dependencies = [ "alloy-primitives", "alloy-rpc-types", diff --git a/Cargo.toml b/Cargo.toml index df9416813f..cc9fbe489c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -267,7 +267,7 @@ revm = { version = "8.0.0", features = [ revm-primitives = { version = "3.1.0", features = [ "std", ], default-features = false } -revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "21f8f3d" } +revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "413b892" } # eth alloy-chains = "0.1.15" @@ -276,19 +276,19 @@ alloy-dyn-abi = "0.7.0" alloy-sol-types = "0.7.0" alloy-rlp = "0.3.4" alloy-trie = "0.3.1" -alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false, features = [ +alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79", default-features = false, features = [ "reqwest", ] } -alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } -alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "987b393" } +alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } +alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "7629f79" } # misc aquamarine = "0.5" diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index a08f7775f2..2d3d664b21 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -2,6 +2,7 @@ use crate::compression::{TRANSACTION_COMPRESSOR, TRANSACTION_DECOMPRESSOR}; use crate::{keccak256, Address, BlockHashOrNumber, Bytes, TxHash, B256, U256}; +use alloy_eips::eip2718::Eip2718Error; use alloy_rlp::{ Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE, }; @@ -10,6 +11,7 @@ use derive_more::{AsRef, Deref}; use once_cell::sync::Lazy; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_codecs::{add_arbitrary_tests, derive_arbitrary, Compact}; +use reth_rpc_types::ConversionError; use serde::{Deserialize, Serialize}; use std::mem; @@ -612,6 +614,101 @@ impl From for Transaction { } } +impl TryFrom for Transaction { + type Error = ConversionError; + + fn try_from(tx: reth_rpc_types::Transaction) -> Result { + match tx.transaction_type { + None | Some(0) => { + // legacy + if tx.max_fee_per_gas.is_some() || tx.max_priority_fee_per_gas.is_some() { + return Err(ConversionError::Eip2718Error( + RlpError::Custom("EIP-1559 fields are present in a legacy transaction") + .into(), + )) + } + Ok(Transaction::Legacy(TxLegacy { + chain_id: tx.chain_id, + nonce: tx.nonce, + gas_price: tx.gas_price.ok_or(ConversionError::MissingGasPrice)?, + gas_limit: tx + .gas + .try_into() + .map_err(|_| ConversionError::Eip2718Error(RlpError::Overflow.into()))?, + to: tx.to.map_or(TransactionKind::Create, TransactionKind::Call), + value: tx.value, + input: tx.input, + })) + } + Some(1u8) => { + // eip2930 + Ok(Transaction::Eip2930(TxEip2930 { + chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, + nonce: tx.nonce, + gas_limit: tx + .gas + .try_into() + .map_err(|_| ConversionError::Eip2718Error(RlpError::Overflow.into()))?, + to: tx.to.map_or(TransactionKind::Create, TransactionKind::Call), + value: tx.value, + input: tx.input, + access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?.into(), + gas_price: tx.gas_price.ok_or(ConversionError::MissingGasPrice)?, + })) + } + Some(2u8) => { + // EIP-1559 + Ok(Transaction::Eip1559(TxEip1559 { + chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, + nonce: tx.nonce, + max_priority_fee_per_gas: tx + .max_priority_fee_per_gas + .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, + 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()))?, + to: tx.to.map_or(TransactionKind::Create, TransactionKind::Call), + value: tx.value, + access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?.into(), + input: tx.input, + })) + } + Some(3u8) => { + // EIP-4844 + Ok(Transaction::Eip4844(TxEip4844 { + chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, + nonce: tx.nonce, + max_priority_fee_per_gas: tx + .max_priority_fee_per_gas + .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, + 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()))?, + to: tx.to.map_or(TransactionKind::Create, TransactionKind::Call), + value: tx.value, + access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?.into(), + input: tx.input, + blob_versioned_hashes: tx + .blob_versioned_hashes + .ok_or(ConversionError::MissingBlobVersionedHashes)?, + max_fee_per_blob_gas: tx + .max_fee_per_blob_gas + .ok_or(ConversionError::MissingMaxFeePerBlobGas)?, + })) + } + Some(tx_type) => Err(Eip2718Error::UnexpectedType(tx_type).into()), + } + } +} + impl Compact for Transaction { // Serializes the TxType to the buffer if necessary, returning 2 bits of the type as an // identifier instead of the length.