Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Add methods param for RPC state_traceBlock (#9642)
Browse files Browse the repository at this point in the history
* Add methods param for RPC state_traceBlock

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* rename event_values_filter arg

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Add some doc

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Add some doc

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Fix doc

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* format

Signed-off-by: koushiro <koushiro.cqx@gmail.com>
  • Loading branch information
koushiro authored Aug 30, 2021
1 parent d6847a7 commit 864d096
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 8 deletions.
47 changes: 45 additions & 2 deletions client/rpc-api/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,55 @@ pub trait StateApi<Hash> {
///
/// ### `curl` example
///
/// - Get tracing spans and events
/// ```text
/// curl \
/// -H "Content-Type: application/json" \
/// -d '{"id":1, "jsonrpc":"2.0", "method": "state_traceBlock", \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264"]}' \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264", "pallet,frame,state", "", ""]}' \
/// http://localhost:9933/
/// ```
///
/// - Get tracing events with all `storage_keys`
/// ```text
/// curl \
/// -H "Content-Type: application/json" \
/// -d '{"id":1, "jsonrpc":"2.0", "method": "state_traceBlock", \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264", "state", "", ""]}' \
/// http://localhost:9933/
/// ```
///
/// - Get tracing events with `storage_keys` ('f0c365c3cf59d671eb72da0e7a4113c4')
/// ```text
/// curl \
/// -H "Content-Type: application/json" \
/// -d '{"id":1, "jsonrpc":"2.0", "method": "state_traceBlock", \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264", "state", "f0c365c3cf59d671eb72da0e7a4113c4", ""]}' \
/// http://localhost:9933/
/// ```
///
/// - Get tracing events with `storage_keys` ('f0c365c3cf59d671eb72da0e7a4113c4') and method
/// ('Put')
/// ```text
/// curl \
/// -H "Content-Type: application/json" \
/// -d '{"id":1, "jsonrpc":"2.0", "method": "state_traceBlock", \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264", "state", "f0c365c3cf59d671eb72da0e7a4113c4", "Put"]}' \
/// http://localhost:9933/
/// ```
///
/// - Get tracing events with all `storage_keys` and method ('Put')
/// ```text
/// curl \
/// -H "Content-Type: application/json" \
/// -d '{"id":1, "jsonrpc":"2.0", "method": "state_traceBlock", \
/// "params": ["0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264", "state", "", "Put"]}' \
/// http://localhost:9933/
/// ```
///
/// ### Params
///
/// - `block_hash` (param index 0): Hash of the block to trace.
/// - `block` (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
Expand All @@ -251,6 +289,10 @@ pub trait StateApi<Hash> {
/// which is a map from `AccountId` to `AccountInfo`. The key filter for this would be
/// the storage prefix for the map:
/// `26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9`
/// - `methods` (param index 3): String of comma separated (no spaces) tracing event method.
/// 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 method (so non-method events will
/// **not** show up).
///
/// 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
Expand All @@ -277,5 +319,6 @@ pub trait StateApi<Hash> {
block: Hash,
targets: Option<String>,
storage_keys: Option<String>,
methods: Option<String>,
) -> FutureResult<sp_rpc::tracing::TraceBlockResponse>;
}
4 changes: 3 additions & 1 deletion client/rpc/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ where
block: Block::Hash,
targets: Option<String>,
storage_keys: Option<String>,
methods: Option<String>,
) -> FutureResult<sp_rpc::tracing::TraceBlockResponse>;
}

Expand Down Expand Up @@ -413,12 +414,13 @@ where
block: Block::Hash,
targets: Option<String>,
storage_keys: Option<String>,
methods: Option<String>,
) -> FutureResult<sp_rpc::tracing::TraceBlockResponse> {
if let Err(err) = self.deny_unsafe.check_if_safe() {
return async move { Err(err.into()) }.boxed()
}

self.backend.trace_block(block, targets, storage_keys)
self.backend.trace_block(block, targets, storage_keys, methods)
}
}

Expand Down
2 changes: 2 additions & 0 deletions client/rpc/src/state/state_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,12 +581,14 @@ where
block: Block::Hash,
targets: Option<String>,
storage_keys: Option<String>,
methods: Option<String>,
) -> FutureResult<sp_rpc::tracing::TraceBlockResponse> {
let block_executor = sc_tracing::block::BlockExecutor::new(
self.client.clone(),
block,
targets,
storage_keys,
methods,
self.rpc_max_payload,
);
let r = block_executor
Expand Down
1 change: 1 addition & 0 deletions client/rpc/src/state/state_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ where
_block: Block::Hash,
_targets: Option<String>,
_storage_keys: Option<String>,
_methods: Option<String>,
) -> FutureResult<sp_rpc::tracing::TraceBlockResponse> {
async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
}
Expand Down
19 changes: 14 additions & 5 deletions client/tracing/src/block/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ pub struct BlockExecutor<Block: BlockT, Client> {
block: Block::Hash,
targets: Option<String>,
storage_keys: Option<String>,
methods: Option<String>,
rpc_max_payload: usize,
}

Expand All @@ -201,12 +202,13 @@ where
block: Block::Hash,
targets: Option<String>,
storage_keys: Option<String>,
methods: Option<String>,
rpc_max_payload: Option<usize>,
) -> Self {
let rpc_max_payload = rpc_max_payload
.map(|mb| mb.saturating_mul(MEGABYTE))
.unwrap_or(RPC_MAX_PAYLOAD_DEFAULT);
Self { client, block, targets, storage_keys, rpc_max_payload }
Self { client, block, targets, storage_keys, methods, rpc_max_payload }
}

/// Execute block, record all spans and events belonging to `Self::targets`
Expand Down Expand Up @@ -274,7 +276,13 @@ where
.filter(|e| {
self.storage_keys
.as_ref()
.map(|keys| event_key_filter(e, keys))
.map(|keys| event_values_filter(e, "key", keys))
.unwrap_or(false)
})
.filter(|e| {
self.methods
.as_ref()
.map(|methods| event_values_filter(e, "method", methods))
.unwrap_or(false)
})
.map(|s| s.into())
Expand All @@ -292,6 +300,7 @@ where
parent_hash: block_id_as_string(parent_id),
tracing_targets: targets.to_string(),
storage_keys: self.storage_keys.clone().unwrap_or_default(),
methods: self.methods.clone().unwrap_or_default(),
spans,
events,
})
Expand All @@ -301,12 +310,12 @@ where
}
}

fn event_key_filter(event: &TraceEvent, storage_keys: &str) -> bool {
fn event_values_filter(event: &TraceEvent, filter_kind: &str, values: &str) -> bool {
event
.values
.string_values
.get("key")
.and_then(|key| Some(check_target(storage_keys, key, &event.level)))
.get(filter_kind)
.and_then(|value| Some(check_target(values, value, &event.level)))
.unwrap_or(false)
}

Expand Down
3 changes: 3 additions & 0 deletions primitives/rpc/src/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub struct BlockTrace {
/// Storage key targets used to filter out events that do not have one of the storage keys.
/// Empty string means do not filter out any events.
pub storage_keys: String,
/// Method targets used to filter out events that do not have one of the event method.
/// Empty string means do not filter out any events.
pub methods: String,
/// Vec of tracing spans
pub spans: Vec<Span>,
/// Vec of tracing events
Expand Down

0 comments on commit 864d096

Please sign in to comment.