moonbeam
moonbeam copied to clipboard
Any way to to capture the tracing logs in wrapped dispatch call
We found such an issue that you'll get the following result if the Ethereum::transact
call is wrapped in another dispatch call.
{
"jsonrpc": "2.0",
"error": {
"code": -32603,
"message": "DispatchError: Other(\"\")"
},
"id": 1
}
An example like this: https://pangolin.subscan.io/extrinsic/3680094-2
After the investment, I've found the root cause to be the filter below, we only match the Call::Ethereum
, but it's actually the bridgepangoromessages::Receive_messages_delivery_proof
in the example case.
fn trace_transaction(
extrinsics: Vec<<Block as BlockT>::Extrinsic>,
traced_transaction: &EthereumTransaction,
) -> Result<(), sp_runtime::DispatchError> {
#[cfg(feature = "evm-tracing")]
{
use moonbeam_evm_tracer::tracer::EvmTracer;
// Apply the a subset of extrinsics: all the substrate-specific or ethereum
// transactions that preceded the requested transaction.
for ext in extrinsics.into_iter() {
let _ = match &ext.0.function {
Call::Ethereum(transact { transaction }) => {
if transaction == traced_transaction {
EvmTracer::new().trace(|| Executive::apply_extrinsic(ext));
return Ok(());
} else {
Executive::apply_extrinsic(ext)
}
}
_ => Executive::apply_extrinsic(ext), // goes into this branch
};
}
Err(sp_runtime::DispatchError::Other(
"Failed to find Ethereum transaction among the extrinsics.",
))
}
#[cfg(not(feature = "evm-tracing"))]
Err(sp_runtime::DispatchError::Other(
"Missing `evm-tracing` compile time feature flag.",
))
}
It would be great if we could find the extrinsic hash based on the ethereum transaction hash so that we could filter by that. But after some searching, I find we did not store that information in frontier db.
@tgmichel @nanocryk Any suggestion about this?
Can we add another runtime function named trace_extrinsic(xx)
, like trace_transaction(xx)
above to support tracing a specific extrinsic?
Any feedback about this?
Can you provide the exact RPC call you made to get this output?
On Moonbeam you shouldn't be able to make an EVM execution outside of an Ethereum transaction or XCM (only on Moonbase, we need to add tracing support for it).
Having an RPC to get the Substrate hash from the Ethereum hash could be useful in general however.
@nanocryk
Can you provide the exact RPC call you made to get this output?
-
curl http://g4.pangolin-p2p.darwinia.network:9933 -H "Content-Type:application/json;charset=utf-8" -d '{ "jsonrpc":"2.0", "id":1, "method":"debug_traceTransaction", "params": ["0xf4526d1a118315aa561a810025336c191c425e342bfe176891dd45f961b8323a", {"disableStorage": true, "disableMemory": true, "disableStack": true}]}' | jq
-
Receive_messages_delivery_proof
call comes from one of our bridger pallets here https://github.com/darwinia-network/darwinia-messages-substrate/blob/main/modules/messages/src/lib.rs#L508-L512, which might contains an encodedEthereum::transact(xxx)
call constructed in the source chain. It'll be relaid to the target chain and execute.
Can we add another runtime function named
trace_extrinsic(xx)
, liketrace_transaction(xx)
above to support tracing a specific extrinsic?
This way seems easier but might break the RPC compatibility with Ethereum because the extrinsic concept only exists in the substrate chain. I am not sure how your team thinks about this. If it's Okay, I can raise a pr to do it.
Having an RPC to get the Substrate hash from the Ethereum hash could be useful in general however.
In this way, we need to store the ethereum_hash => extrinsic_hash
in frontier DB after the sender submits the tx to the pool, for the older transactions, we might need some special treatment.
Well this is not part of our chain. But you should be able to match this extrinsic in your chain runtime API, find if the ethereum transaction matches, and if it does wrap it inside EvmTracer::new().trace
.
Since the dispatch call represents a storage proof, it's hard to parse out at the runtime side.