From 2e032b023dfd68554d2fe21d459fe6a9f34abedf Mon Sep 17 00:00:00 2001 From: Abner Zheng Date: Tue, 26 Mar 2024 19:40:53 +0800 Subject: [PATCH] Implement `ots_getInternalOperations` (#7332) --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/rpc/rpc-builder/tests/it/http.rs | 4 +-- crates/rpc/rpc/src/otterscan.rs | 34 ++++++++++++++++++++++--- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 426e0fd46da2b..a65142d15b18a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6837,7 +6837,7 @@ dependencies = [ [[package]] name = "revm-inspectors" version = "0.1.0" -source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=2b48b65#2b48b65f3880803f51883948c319012da09ecba7" +source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=b3082f3#b3082f3deca76e721ac72cee4a6857b4ff88e684" dependencies = [ "alloy-primitives", "alloy-rpc-trace-types", diff --git a/Cargo.toml b/Cargo.toml index 5dccab02541a0..cf779f25c0875 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,7 +192,7 @@ reth-trie = { path = "crates/trie" } # revm revm = { version = "7.2.0", features = ["std", "secp256k1"], default-features = false } revm-primitives = { version = "3.1.0", features = ["std"], default-features = false } -revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "2b48b65" } +revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "b3082f3" } # eth alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] } diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index 0f68d019861fb..bb0ccef9b4302 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -297,9 +297,7 @@ where OtterscanClient::get_api_level(client).await.unwrap(); - assert!(is_unimplemented( - OtterscanClient::get_internal_operations(client, tx_hash).await.err().unwrap() - )); + OtterscanClient::get_internal_operations(client, tx_hash).await.unwrap(); OtterscanClient::get_transaction_error(client, tx_hash).await.unwrap(); diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index 509822656ce51..206c1b6f6df40 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -2,13 +2,14 @@ use alloy_primitives::Bytes; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use revm::inspectors::NoOpInspector; +use revm_inspectors::transfer::{TransferInspector, TransferKind}; use revm_primitives::ExecutionResult; use reth_primitives::{Address, BlockId, BlockNumberOrTag, TxHash, B256}; use reth_rpc_api::{EthApiServer, OtterscanServer}; use reth_rpc_types::{ - BlockDetails, BlockTransactions, ContractCreator, InternalOperation, OtsBlockTransactions, - OtsTransactionReceipt, TraceEntry, Transaction, TransactionsWithReceipts, + BlockDetails, BlockTransactions, ContractCreator, InternalOperation, OperationType, + OtsBlockTransactions, OtsTransactionReceipt, TraceEntry, Transaction, TransactionsWithReceipts, }; use crate::{eth::EthTransactions, result::internal_rpc_err}; @@ -44,8 +45,33 @@ where } /// Handler for `ots_getInternalOperations` - async fn get_internal_operations(&self, _tx_hash: TxHash) -> RpcResult> { - Err(internal_rpc_err("unimplemented")) + async fn get_internal_operations(&self, tx_hash: TxHash) -> RpcResult> { + let internal_operations = self + .eth + .spawn_trace_transaction_in_block_with_inspector( + tx_hash, + TransferInspector::new(false), + |_tx_info, inspector, _, _| Ok(inspector.into_transfers()), + ) + .await? + .map(|transfer_operations| { + transfer_operations + .iter() + .map(|op| InternalOperation { + from: op.from, + to: op.to, + value: op.value, + r#type: match op.kind { + TransferKind::Call => OperationType::OpTransfer, + TransferKind::Create => OperationType::OpCreate, + TransferKind::Create2 => OperationType::OpCreate2, + TransferKind::SelfDestruct => OperationType::OpSelfDestruct, + }, + }) + .collect::>() + }) + .unwrap_or_default(); + Ok(internal_operations) } /// Handler for `ots_getTransactionError`