moonbeam icon indicating copy to clipboard operation
moonbeam copied to clipboard

Any way to to capture the tracing logs in wrapped dispatch call

Open boundless-forest opened this issue 2 years ago • 8 comments

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

image

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?

boundless-forest avatar Aug 16 '22 07:08 boundless-forest

Can we add another runtime function named trace_extrinsic(xx), like trace_transaction(xx) above to support tracing a specific extrinsic?

boundless-forest avatar Aug 19 '22 08:08 boundless-forest

Any feedback about this?

boundless-forest avatar Aug 29 '22 09:08 boundless-forest

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 avatar Aug 29 '22 09:08 nanocryk

@nanocryk

Can you provide the exact RPC call you made to get this output?

  1. 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
  2. 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 encoded Ethereum::transact(xxx) call constructed in the source chain. It'll be relaid to the target chain and execute.

boundless-forest avatar Aug 29 '22 10:08 boundless-forest

Can we add another runtime function named trace_extrinsic(xx), like trace_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.

boundless-forest avatar Aug 29 '22 10:08 boundless-forest

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.

boundless-forest avatar Aug 29 '22 10:08 boundless-forest

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.

nanocryk avatar Sep 01 '22 10:09 nanocryk

Since the dispatch call represents a storage proof, it's hard to parse out at the runtime side.

boundless-forest avatar Sep 08 '22 08:09 boundless-forest