From 8d51c608ce9c27f18411928fc3b1d61252bf9f1a Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 20 Feb 2025 18:59:54 +0400 Subject: [PATCH] fix: handle `Deposit` in `TryFrom` (#14614) Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> --- .config/zepter.yaml | 2 +- Cargo.lock | 3 + crates/optimism/primitives/Cargo.toml | 12 ++-- .../optimism/primitives/src/alloy_compat.rs | 59 +++++++++++++++---- crates/optimism/reth/Cargo.toml | 4 +- 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/.config/zepter.yaml b/.config/zepter.yaml index 4ad896e16..2438d92ad 100644 --- a/.config/zepter.yaml +++ b/.config/zepter.yaml @@ -12,7 +12,7 @@ workflows: # Check that `A` activates the features of `B`. "propagate-feature", # These are the features to check: - "--features=std,op,dev,asm-keccak,jemalloc,jemalloc-prof,tracy-allocator,serde-bincode-compat,serde,test-utils,arbitrary,bench", + "--features=std,op,dev,asm-keccak,jemalloc,jemalloc-prof,tracy-allocator,serde-bincode-compat,serde,test-utils,arbitrary,bench,alloy-compat", # Do not try to add a new section into `[features]` of `A` only because `B` expose that feature. There are edge-cases where this is still needed, but we can add them manually. "--left-side-feature-missing=ignore", # Ignore the case that `A` it outside of the workspace. Otherwise it will report errors in external dependencies that we have no influence on. diff --git a/Cargo.lock b/Cargo.lock index 28913a716..a1848988d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5608,8 +5608,10 @@ checksum = "621e69964165285ce750bf7ba961707e26c31df9f0b25652d6219dcee1f7f5b5" dependencies = [ "alloy-consensus", "alloy-eips", + "alloy-network", "alloy-primitives", "alloy-rlp", + "alloy-rpc-types-eth", "alloy-serde", "arbitrary", "derive_more 1.0.0", @@ -8739,6 +8741,7 @@ dependencies = [ "rstest", "secp256k1 0.30.0", "serde", + "serde_json", ] [[package]] diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index 3f33436f4..04b2b60d4 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -46,13 +46,14 @@ arbitrary = { workspace = true, features = ["derive"], optional = true } proptest = { workspace = true, optional = true } [dev-dependencies] -proptest-arbitrary-interop.workspace = true -reth-codecs = { workspace = true, features = ["test-utils", "op"] } -rstest.workspace = true arbitrary.workspace = true -secp256k1 = { workspace = true, features = ["rand"] } +proptest-arbitrary-interop.workspace = true proptest.workspace = true rand.workspace = true +reth-codecs = { workspace = true, features = ["test-utils", "op"] } +rstest.workspace = true +secp256k1 = { workspace = true, features = ["rand"] } +serde_json.workspace = true [features] default = ["std"] @@ -73,8 +74,9 @@ std = [ "alloy-rpc-types-eth?/std", "alloy-serde?/std", "revm-context/std", + "serde_json/std", ] -alloy-compat = ["dep:alloy-network", "dep:alloy-serde", "dep:alloy-rpc-types-eth"] +alloy-compat = ["dep:alloy-network", "dep:alloy-serde", "dep:alloy-rpc-types-eth", "op-alloy-consensus/alloy-compat"] reth-codec = [ "dep:reth-codecs", "std", diff --git a/crates/optimism/primitives/src/alloy_compat.rs b/crates/optimism/primitives/src/alloy_compat.rs index cd96479f8..39897c9e3 100644 --- a/crates/optimism/primitives/src/alloy_compat.rs +++ b/crates/optimism/primitives/src/alloy_compat.rs @@ -1,22 +1,19 @@ //! Common conversions from alloy types. use crate::OpTransactionSigned; -use alloc::string::ToString; use alloy_consensus::TxEnvelope; use alloy_network::{AnyRpcTransaction, AnyTxEnvelope}; -use alloy_rpc_types_eth::Transaction as AlloyRpcTransaction; +use alloy_rpc_types_eth::{ConversionError, Transaction as AlloyRpcTransaction}; use alloy_serde::WithOtherFields; -use op_alloy_consensus::OpTypedTransaction; +use op_alloy_consensus::{OpTypedTransaction, TxDeposit}; impl TryFrom for OpTransactionSigned { - type Error = alloy_rpc_types_eth::ConversionError; + type Error = ConversionError; fn try_from(tx: AnyRpcTransaction) -> Result { - use alloy_rpc_types_eth::ConversionError; + let WithOtherFields { inner: AlloyRpcTransaction { inner, from, .. }, other: _ } = tx; - let WithOtherFields { inner: tx, other: _ } = tx; - - let (transaction, signature, hash) = match tx.inner { + let (transaction, signature, hash) = match inner { AnyTxEnvelope::Ethereum(TxEnvelope::Legacy(tx)) => { let (tx, signature, hash) = tx.into_parts(); (OpTypedTransaction::Legacy(tx), signature, hash) @@ -33,10 +30,17 @@ impl TryFrom for OpTransactionSigned { let (tx, signature, hash) = tx.into_parts(); (OpTypedTransaction::Eip7702(tx), signature, hash) } - _ => { - // TODO: support tx deposit: - return Err(ConversionError::Custom("unknown transaction type".to_string())) + AnyTxEnvelope::Unknown(mut tx) => { + // Re-insert `from` field which was consumed by outer `Transaction`. + // Ref hack in op-alloy + tx.inner + .fields + .insert_value("from".to_string(), from) + .map_err(|err| ConversionError::Custom(err.to_string()))?; + let hash = tx.hash; + (OpTypedTransaction::Deposit(tx.try_into()?), TxDeposit::signature(), hash) } + _ => return Err(ConversionError::Custom("unknown transaction type".to_string())), }; Ok(Self::new(transaction, signature, hash)) @@ -51,3 +55,36 @@ where value.inner.into() } } + +#[cfg(test)] +mod tests { + use alloy_network::AnyRpcTransaction; + + use crate::OpTransactionSigned; + + #[test] + fn test_tx_deposit() { + let json = r#"{ + "hash": "0x3f44a72b1faf70be7295183f1f30cfb51ede92d7c44441ca80c9437a6a22e5a5", + "type": "0x7e", + "depositReceiptVersion": "0x1", + "gas": "0x77f2e", + "gasPrice": "0x0", + "input": "0xd764ad0b000100000000000000000000000000000000000000000000000000000005dacf0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c3500000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c41635f5fd000000000000000000000000212241ad6a6a0a7553c4290f7bc517c1041df0be000000000000000000000000d153f571d0a5a07133114bfe623d4d71e03ea5d70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000018307837333735373036353732363237323639363436373635000000000000000000000000000000000000000000000000000000000000000000000000", + "mint": "0x1c6bf52634000", + "nonce": "0x5dacf", + "r": "0x0", + "s": "0x0", + "sourceHash": "0x26eb0df3ebdb8eb11892a336b798948ec846c28200862a67aa32cfd57ca7da4f", + "to": "0x4200000000000000000000000000000000000007", + "v": "0x0", + "value": "0x1c6bf52634000", + "blockHash": "0x0d7f8b9def6f5d3ba2cbeee2e31e730da81e2c474fa8c3c9e8d0e6b96e37d182", + "blockNumber": "0x1966297", + "transactionIndex": "0x1", + "from": "0x977f82a600a1414e583f7f13623f1ac5d58b1c0b" + }"#; + let tx: AnyRpcTransaction = serde_json::from_str(json).unwrap(); + OpTransactionSigned::try_from(tx).unwrap(); + } +} diff --git a/crates/optimism/reth/Cargo.toml b/crates/optimism/reth/Cargo.toml index e3437d85e..883fdb921 100644 --- a/crates/optimism/reth/Cargo.toml +++ b/crates/optimism/reth/Cargo.toml @@ -72,7 +72,9 @@ test-utils = [ full = ["consensus", "evm", "node", "provider", "rpc", "trie"] -alloy-compat = [] +alloy-compat = [ + "reth-optimism-primitives/alloy-compat", +] consensus = ["dep:reth-consensus", "dep:reth-consensus-common", "dep:reth-optimism-consensus"] evm = ["dep:reth-evm", "dep:reth-optimism-evm"] node-api = ["dep:reth-node-api"]