fix: handle Deposit in TryFrom<AnyRpcTransaction> (#14614)

Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
This commit is contained in:
Arsenii Kulikov
2025-02-20 18:59:54 +04:00
committed by GitHub
parent 0500069772
commit 8d51c608ce
5 changed files with 62 additions and 18 deletions

View File

@ -12,7 +12,7 @@ workflows:
# Check that `A` activates the features of `B`. # Check that `A` activates the features of `B`.
"propagate-feature", "propagate-feature",
# These are the features to check: # 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. # 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", "--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. # Ignore the case that `A` it outside of the workspace. Otherwise it will report errors in external dependencies that we have no influence on.

3
Cargo.lock generated
View File

@ -5608,8 +5608,10 @@ checksum = "621e69964165285ce750bf7ba961707e26c31df9f0b25652d6219dcee1f7f5b5"
dependencies = [ dependencies = [
"alloy-consensus", "alloy-consensus",
"alloy-eips", "alloy-eips",
"alloy-network",
"alloy-primitives", "alloy-primitives",
"alloy-rlp", "alloy-rlp",
"alloy-rpc-types-eth",
"alloy-serde", "alloy-serde",
"arbitrary", "arbitrary",
"derive_more 1.0.0", "derive_more 1.0.0",
@ -8739,6 +8741,7 @@ dependencies = [
"rstest", "rstest",
"secp256k1 0.30.0", "secp256k1 0.30.0",
"serde", "serde",
"serde_json",
] ]
[[package]] [[package]]

View File

@ -46,13 +46,14 @@ arbitrary = { workspace = true, features = ["derive"], optional = true }
proptest = { workspace = true, optional = true } proptest = { workspace = true, optional = true }
[dev-dependencies] [dev-dependencies]
proptest-arbitrary-interop.workspace = true
reth-codecs = { workspace = true, features = ["test-utils", "op"] }
rstest.workspace = true
arbitrary.workspace = true arbitrary.workspace = true
secp256k1 = { workspace = true, features = ["rand"] } proptest-arbitrary-interop.workspace = true
proptest.workspace = true proptest.workspace = true
rand.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] [features]
default = ["std"] default = ["std"]
@ -73,8 +74,9 @@ std = [
"alloy-rpc-types-eth?/std", "alloy-rpc-types-eth?/std",
"alloy-serde?/std", "alloy-serde?/std",
"revm-context/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 = [ reth-codec = [
"dep:reth-codecs", "dep:reth-codecs",
"std", "std",

View File

@ -1,22 +1,19 @@
//! Common conversions from alloy types. //! Common conversions from alloy types.
use crate::OpTransactionSigned; use crate::OpTransactionSigned;
use alloc::string::ToString;
use alloy_consensus::TxEnvelope; use alloy_consensus::TxEnvelope;
use alloy_network::{AnyRpcTransaction, AnyTxEnvelope}; 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 alloy_serde::WithOtherFields;
use op_alloy_consensus::OpTypedTransaction; use op_alloy_consensus::{OpTypedTransaction, TxDeposit};
impl TryFrom<AnyRpcTransaction> for OpTransactionSigned { impl TryFrom<AnyRpcTransaction> for OpTransactionSigned {
type Error = alloy_rpc_types_eth::ConversionError; type Error = ConversionError;
fn try_from(tx: AnyRpcTransaction) -> Result<Self, Self::Error> { fn try_from(tx: AnyRpcTransaction) -> Result<Self, Self::Error> {
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 inner {
let (transaction, signature, hash) = match tx.inner {
AnyTxEnvelope::Ethereum(TxEnvelope::Legacy(tx)) => { AnyTxEnvelope::Ethereum(TxEnvelope::Legacy(tx)) => {
let (tx, signature, hash) = tx.into_parts(); let (tx, signature, hash) = tx.into_parts();
(OpTypedTransaction::Legacy(tx), signature, hash) (OpTypedTransaction::Legacy(tx), signature, hash)
@ -33,10 +30,17 @@ impl TryFrom<AnyRpcTransaction> for OpTransactionSigned {
let (tx, signature, hash) = tx.into_parts(); let (tx, signature, hash) = tx.into_parts();
(OpTypedTransaction::Eip7702(tx), signature, hash) (OpTypedTransaction::Eip7702(tx), signature, hash)
} }
_ => { AnyTxEnvelope::Unknown(mut tx) => {
// TODO: support tx deposit: <https://github.com/alloy-rs/op-alloy/pull/427> // Re-insert `from` field which was consumed by outer `Transaction`.
return Err(ConversionError::Custom("unknown transaction type".to_string())) // Ref hack in op-alloy <https://github.com/alloy-rs/op-alloy/blob/7d50b698631dd73f8d20f9f60ee78cd0597dc278/crates/rpc-types/src/transaction.rs#L236-L237>
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)) Ok(Self::new(transaction, signature, hash))
@ -51,3 +55,36 @@ where
value.inner.into() 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();
}
}

View File

@ -72,7 +72,9 @@ test-utils = [
full = ["consensus", "evm", "node", "provider", "rpc", "trie"] 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"] consensus = ["dep:reth-consensus", "dep:reth-consensus-common", "dep:reth-optimism-consensus"]
evm = ["dep:reth-evm", "dep:reth-optimism-evm"] evm = ["dep:reth-evm", "dep:reth-optimism-evm"]
node-api = ["dep:reth-node-api"] node-api = ["dep:reth-node-api"]