RPC to trace execution of specified block (#7780)

* Add filter reload handle

* add RPC, move logging module from cli to tracing

* remove dup fn

* working example

* Update client/rpc-api/src/system/mod.rs

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* Prefer "set" to "reload"

* Re-enable the commented out features of the logger

* Remove duplicate code

* cleanup

* unneeded lvar

* Bump to latest patch release

* Add new CLI option to disable log filter reloading,

Move profiling CLI options to SharedParams

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Applied suggestions from reviews

* Fix calls to init_logger()

* Handle errors when parsing logging directives

* Deny `system_setLogFilter` RPC by default

* One more time

* Don't ignore parse errors for log directives set via CLI or RPC

* Improve docs

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/cli/src/config.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* fix merge errors

* include default directives with system_setLogFilter RPC,

implement system_rawSetLogFilter RPC to exclude defaults

* docs etc...

* update test

* refactor: rename fn

* Add a test for system_set_log_filter – NOTE: the code should likely change to return an error when bad directives are passed

* Update client/cli/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Address review grumbles

* Add doc note on panicking behaviour

* print all invalid directives before panic

* change RPCs to: addLogFilter and resetLogFilter

* make CLI log directives default

* add comments

* restore previous behaviour to panic when hard-coded directives are invalid

* change/refactor directive parsing

* fix line width

* add test for log filter reloading

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* finish up suggestions from code review

* improve test

* change expect message

* change fn name

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* add docs, remove unused fn

* propagate Err on invalid log directive

* Update tracing-subscriber version

* Improve docs for `disable_log_reloading` CLI param

* WIP implementation: RPC and trace capturing

* WIP

* fix incorrect number of digest items

* return errors

* add From impl for Values, rename structs

* fixes

* implement option to choose targets for traces

* rename fn

* fix EnvFilter and add root span

* fix root span

* add docs, remove unnecessary traits

* fix regression on parent_id introduced in a9c73113a8

* fix line width

* remove unused

* include block hash, parent hash & targets in response

* move types from sp-tracing into sp-rpc

move block and parent hash into root of BlockTrace

* switch from log::trace to tracing::trace in state-machine

* use unsigned integer type to represent Ext::id in traces

* ensure id is unique by implementing Subscriber

tracing_subscriber::FmtSubscriber does not guarantee
unique ids

* indentation

* fix typo

* update types

* add sp_io::storage events

* Change response format

- update types
- record distinct timestamps
- sort spans by first entered

* convert to HexDisplay, refactor

* Sort out fallout from merge

* Update client/rpc-api/src/state/mod.rs

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Exit early unless the node runs with --rpc-methods=Unsafe

* Better error handling

* Use wasm-timer

* revert trace alteration in `state-machine` and remove events in `sp_io::storage`

Resolve in follow-up PR

* Review feedback: less collects

* Without Arcs

* Fix span exit

* typo

* cleanup

* Add a few debug messages to tracing module

* Structure traces state-machine/ext; Dispatchable extrinsics spans not working

* Correctly encode Option storage values

* Remove test field for Put and Get

* Try out some changes to dispatch macro

* Add various log messages in dispatch

* Add span dispatch span to new proc macro

* Remove debug messages in dispatch

* Trivial clean up

* Structure remaining state-machine traces (ChangesRoot*)

* Removed unnesecary tracing targets

* Remove log

* New cargo.lock post merge

* Add logging for wasm_overrides

* remove temp logs

* remove temp logs

* remove unused dep

* remove temp logs

* add logging to wasm_overrides

* add logging to state_tracing

* add logging for spans to substrate (includes timings)

* Skip serializing some event fields; Remove most storage traces

* Bring back all ext.rs traces

* Do not skip bool values in events

* Skip serializing span values

* Serialize span values; remove some trace events in ext

* Remove more trace events

* Delete commented out traces

* Remove all unused traces

* Add event filtering

* Fix typo

* wip - change response types to be more efficient

missing import

type

* Serialize struct fields as camelCase

* Add back in event filtering

* Remove name field from event

* Sort spans by time entered

* Sort spans in ASCending order

* Add storage keys target param to rpc

* Limit payload size; improve hash fields; include storage keys

- cleanup event_key_filter
- better block hash representation
- limit payload size
- cleanup based on andrews comments

* Error when serialized payload is to big

* Import MAX_PAYLOAD from rpc-servers

* Clean up ext.rs

* Misc. cleaning and comments

* Strict ordering span Id; no span sort; adjust for rpc base payload

* Add RPC docs to rpc-api/src/state/mod

* Make params bullet points

* Update primitives/rpc/src/tracing.rs

* Put all tracing logic within trace

* Remove attr.record in new_span

* Add back value record in new_span

* restore result collection in ext

* Revert "Add back value record in new_span"

This reverts commit baf1a735f23e5eef1bf6264adfabb788910fa661.

* 🤦

* more 🤦

* Update docs; Try fix line width issues

* Improve docs

* Improve docs

* Remove default key filters + add key recs to docs

* Try restore old traces

* Add back doc comment

* Clean up newlines in ext.rs

* More new line remova;
l

* Use FxHashMap

* Try use EnvFilter directives for event filtering

* Remove directive, filter events by fields

* Use trace metadata correctly

* Try EnvFilter directive with all default targets

* Revert "Try EnvFilter directive with all default targets"

This reverts commit 4cc6ebc721d207c3b846444174f89d45038525ac.

* Clean up clippy warning

* Incorporate Niklas feedback

* Update trace/log macro calls to have better syntx

* Use Ordering::Relaxed

* Improve patch and filter doc comment

* Clean up `BlockSubscriber::new`

* Try optimize `BlockSubscriber::enabled`

* Apply suggestions from code review

Co-authored-by: David <dvdplm@gmail.com>

* Apply suggestions from code review

Co-authored-by: David <dvdplm@gmail.com>

* Use contains_key

* use heuristic for payload size

* Add error tupe for client::tracing::block

* Minor tweaks

* Make a note about `--features with-tracing`

* Add CURL example to RPC docs

* Link to substrate-archibe wasm

* Trivial doc clean up based on David feedback

* Explicit result type name

* Respect line length

* Use the error

* Don't print timings when spans close

* Fix failing sc-rpc-api

* Update  sp-tracing inner-line doc

* Update client/tracing/src/block/mod.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/service/src/client/call_executor.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/service/src/client/call_executor.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/tracing/src/block/mod.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/tracing/src/block/mod.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Address some review grumbles

* Update primitives/state-machine/src/ext.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Use result_encoded structure fields in ext.rs

* Use value key for ext put

* Add notes about tracing key names matter

Co-authored-by: Matt <mattrutherford@users.noreply.github.com>
Co-authored-by: David <dvdplm@gmail.com>
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: emostov <32168567+emostov@users.noreply.github.com>
This commit is contained in:
mattrutherford
2021-05-05 08:44:36 +01:00
committed by GitHub
parent 37ea3958d9
commit 6e8957b095
25 changed files with 803 additions and 66 deletions
+114
View File
@@ -136,4 +136,118 @@ pub trait StateApi<Hash> {
fn unsubscribe_storage(
&self, metadata: Option<Self::Metadata>, id: SubscriptionId
) -> RpcResult<bool>;
/// The `state_traceBlock` RPC provides a way to trace the re-execution of a single
/// block, collecting Spans and Events from both the client and the relevant WASM runtime.
/// The Spans and Events are conceptually equivalent to those from the [Tracing][1] crate.
///
/// The structure of the traces follows that of the block execution pipeline, so meaningful
/// interpretation of the traces requires an understanding of the Substrate chain's block
/// execution.
///
/// [Link to conceptual map of trace structure for Polkadot and Kusama block execution.][2]
///
/// [1]: https://crates.io/crates/tracing
/// [2]: https://docs.google.com/drawings/d/1vZoJo9jaXlz0LmrdTOgHck9_1LsfuQPRmTr-5g1tOis/edit?usp=sharing
///
/// ## Node requirements
///
/// - Fully synced archive node (i.e. a node that is not actively doing a "major" sync).
/// - [Tracing enabled WASM runtimes](#creating-tracing-enabled-wasm-runtimes) for all runtime versions
/// for which tracing is desired.
///
/// ## Node recommendations
///
/// - Use fast SSD disk storage.
/// - Run node flags to increase DB read speed (i.e. `--state-cache-size`, `--db-cache`).
///
/// ## Creating tracing enabled WASM runtimes
///
/// - Checkout commit of chain version to compile with WASM traces
/// - [diener][1] can help to peg commit of substrate to what the chain expects.
/// - Navigate to the `runtime` folder/package of the chain
/// - Add feature `with-tracing = ["frame-executive/with-tracing", "sp-io/with-tracing"]`
/// under `[features]` to the `runtime` packages' `Cargo.toml`.
/// - Compile the runtime with `cargo build --release --features with-tracing`
/// - Tracing-enabled WASM runtime should be found in `./target/release/wbuild/{{chain}}-runtime`
/// and be called something like `{{your_chain}}_runtime.compact.wasm`. This can be
/// renamed/modified however you like, as long as it retains the `.wasm` extension.
/// - Run the node with the wasm blob overrides by placing them in a folder with all your runtimes,
/// and passing the path of this folder to your chain, e.g.:
/// - `./target/release/polkadot --wasm-runtime-overrides /home/user/my-custom-wasm-runtimes`
///
/// You can also find some pre-built tracing enabled wasm runtimes in [substrate-archive][2]
///
/// [Source.][3]
///
/// [1]: https://crates.io/crates/diener
/// [2]: https://github.com/paritytech/substrate-archive/tree/master/wasm-tracing
/// [3]: https://github.com/paritytech/substrate-archive/wiki
///
/// ## RPC Usage
///
/// The RPC allows for two filtering mechanisms: tracing targets and storage key prefixes.
/// The filtering of spans and events takes place after they are all collected; so while filters
/// do not reduce time for actual block re-execution, they reduce the response payload size.
///
/// Note: storage events primarily come from _primitives/state-machine/src/ext.rs_.
/// The default filters can be overridden, see the [params section](#params) for details.
///
/// ### `curl` example
///
/// ```text
/// curl \
/// -H "Content-Type: application/json" \
/// -d '{"id":1, "jsonrpc":"2.0", "method": "state_traceBlock", \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264"]}' \
/// http://localhost:9933/
/// ```
///
/// ### Params
///
/// - `block_hash` (param index 0): Hash of the block to trace.
/// - `targets` (param index 1): String of comma separated (no spaces) targets. Specified
/// targets match with trace targets by prefix (i.e if a target is in the beginning
/// of a trace target it is considered a match). If an empty string is specified no
/// targets will be filtered out. The majority of targets correspond to Rust module names,
/// and the ones that do not are typically "hardcoded" into span or event location
/// somewhere in the Substrate source code. ("Non-hardcoded" targets typically come from frame
/// support macros.)
/// - `storage_keys` (param index 2): String of comma separated (no spaces) hex encoded
/// (no `0x` prefix) storage keys. If an empty string is specified no events will
/// be filtered out. If anything other than an empty string is specified, events
/// will be filtered by storage key (so non-storage events will **not** show up).
/// You can specify any length of a storage key prefix (i.e. if a specified storage
/// key is in the beginning of an events storage key it is considered a match).
/// Example: for balance tracking on Polkadot & Kusama you would likely want
/// to track changes to account balances with the frame_system::Account storage item,
/// which is a map from `AccountId` to `AccountInfo`. The key filter for this would be
/// the storage prefix for the map:
/// `26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9`
/// Additionally you would want to track the extrinsic index, which is under the
/// `:extrinsic_index` key. The key for this would be the aforementioned string as bytes
/// in hex: `3a65787472696e7369635f696e646578`.
/// The following are some resources to learn more about storage keys in substrate:
/// [substrate storage][1], [transparent keys in substrate][2],
/// [querying substrate storage via rpc][3].
///
/// [1]: https://substrate.dev/docs/en/knowledgebase/advanced/storage#storage-map-key
/// [2]: https://www.shawntabrizi.com/substrate/transparent-keys-in-substrate/
/// [3]: https://www.shawntabrizi.com/substrate/querying-substrate-storage-via-rpc/
///
/// ### Maximum payload size
///
/// The maximum payload size allowed is 15mb. Payloads over this size will return a
/// object with a simple error message. If you run into issues with payload size you can
/// narrow down the traces using a smaller set of targets and/or storage keys.
///
/// If you are having issues with maximum payload size you can use the flag
/// `-lstate_tracing=trace` to get some logging during tracing.
#[rpc(name = "state_traceBlock")]
fn trace_block(
&self,
block: Hash,
targets: Option<String>,
storage_keys: Option<String>,
) -> FutureResult<sp_rpc::tracing::TraceBlockResponse>;
}