-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Concept of Diagnostic Runtimes #2082
Comments
I would like to have ability to run this diagnostic runtime natively so it is possible to use debugger to debug it. It will be even better if there is a way to run the contracts natively as well. |
@emostov once we
we basically achieve the same thing through CLI in try-runtime. |
@kianenigma @xlc @pepyakin I wonder if we can condense this issue down into some concrete feature requests for try-runtime and try-runtime-cli? I see potentially:
|
(1) will be useful. |
is there any reason not to implicitly enable this when building with |
This issue #1790 made me to come up with an idea of a diagnostic runtime.
To recap: In contracts we have the lack of debuggability problem. In the best case, if the top-level contract fails you get the execution failure error. In the worst case, because contract failures don't cascade by default (i.e. if a leaf contract call fails it doesn't propagate to the root call) you don't get anything. There are even no way to log a message.
The simplest way of solving it is by adding some little features such as posting an event every time a contract generates an error, or e.g. add a special function that logs message that is available only for a testnet.
The problem with a testnet only debugging capabilities that they are no use for the production nets. Mixing debugging code into the runtime is also not the best idea either, because it adds overhead, possibly pessimizes the normal path, increases binary size and enlarges security surface.
It seems to me that a better solution would be to provide this functionality off chain.
Enter diagnostic runtime.
Imagine we had:
state_call
, but that takes one extra parameter: a file path to a wasm runtime to use to execute.Having this, we could add a special path (behind a cfg feature) in the contract module logic which output a trace information.
This, for example, can be done exclusively on the runtime level without touching the substrate host. Here are a few ideas:
ext_begin_fn
function in the prologue and a call to anext_end_fn
in the epilogue of each function. With this we can construct stack traces inside of contracts in the case of errors.ext_print
to the contract runtime. In the normal path it just doesn't do anything (i.e. don't even charge for gas for reading the code), but if the diagnostic feature is enabled the function reads the given buffer and records it in the trace. I think @Robbepop could be interested in this one.After the execution we can assemble this as a trace and spew it out somehow, which could be decoded by tools (or alternatively, we could use human-readable format) or block explorers.
This setup gives us sheer number of possibilities for diagnostics without burdening the substrate host APIs. There is a caveat though: diagnostic runtimes likely would want to be state-compatible (i.e. produce the same state root) with the on-chain runtime just for the sake of being exchangable (i.e. for doing
execute_block
) and that might be tricky in one cases and limiting in other. However, this is not a hard requirement.I think it might be possible that this mechanism could be used outside of the contracts module. For instance, we could use this use mechanism for running quick experiments with on-chain data, quickly testing new versions of runtimes at the development time or before an upgrade.
The text was updated successfully, but these errors were encountered: