-
Notifications
You must be signed in to change notification settings - Fork 814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pallet-revive] add tracing support (3/3) #6727
Changes from 9 commits
f3b3d0e
7c06a39
c17c94c
b66aec2
db77731
e5314b2
807ebd6
3fbcaed
ce2ff1e
92ae9ad
2e16534
a37a5ef
0189fb8
8b34beb
01c2ebc
c484137
0641eeb
b09394f
505d89f
d9b0b2c
dbed695
e356429
3adbc1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,56 @@ pub trait StateApi<Hash> { | |
#[method(name = "state_call", aliases = ["state_callAt"], blocking)] | ||
fn call(&self, name: String, bytes: Bytes, hash: Option<Hash>) -> Result<Bytes, Error>; | ||
|
||
/// Retrieve the block using the specified hash and invoke a runtime API method from the parent | ||
/// state of this block. This allows the method to replay the extrinsics from the parent state | ||
/// of the block. | ||
/// | ||
/// This is typically used to replay transactions with tracing enabled. For example, | ||
/// `pallet_revive` uses this to capture smart-contract call traces. | ||
/// | ||
/// # Parameters | ||
/// - `name`: The name of the runtime API method to call. | ||
/// - `block`: The hash of the block to replay. | ||
/// - `bytes`: Additional, encoded data to pass to the runtime API method, after the block data. | ||
/// | ||
/// # Note | ||
/// | ||
/// - This API is designed to be executed on dedicated nodes, such as tracing nodes, whose sole | ||
/// purpose is to run a node to index data. | ||
/// - These nodes may need to adjust `--rpc-max-response-limit` to a higher value if large | ||
/// responses are anticipated. | ||
/// | ||
/// # `curl` example | ||
/// | ||
/// - Call `pallet_revive` [`trace_block`](https://paritytech.github.io/polkadot-sdk/master/pallet_revive/trait.ReviveApi.html#method.trace_block) | ||
/// to replay a block and capture call traces. | ||
/// | ||
/// ```text | ||
/// curl http://localhost:9944 \ | ||
/// -H 'Content-Type: application/json' \ | ||
/// -d '{ | ||
/// "id":1, "jsonrpc":"2.0", "method":"state_debugBlock", \ | ||
/// "params": ["ReviveApi_trace_block", "0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264"] | ||
/// }' | ||
/// }' | ||
/// ``` | ||
/// | ||
/// - Call `pallet_revive` [`trace_tx`](https://paritytech.github.io/polkadot-sdk/master/pallet_revive/trait.ReviveApi.html#method.trace_block) | ||
/// to replay a block and capture the call trace of the transaction at the given index. | ||
/// | ||
/// ```text | ||
/// curl http://localhost:9944 \ | ||
/// -H 'Content-Type: application/json' \ | ||
/// -d '{ | ||
/// "id":1, "jsonrpc":"2.0", "method":"state_debugBlock", \ | ||
/// "params": ["ReviveApi_trace_tx", | ||
/// "0xb246acf1adea1f801ce15c77a5fa7d8f2eb8fed466978bcee172cc02cf64e264", "0x2a000000"] | ||
/// }' | ||
/// }' | ||
/// ``` | ||
#[method(name = "state_debugBlock", blocking, with_extensions)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we build this entirely with the new RPC APIs instead? We plan to revisit the legacy ones soon and deprecate as much as possible. One way that this could work without introducing the
Overall the code looks good 🙏 I feel like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @lexnv thanks for the review, sorry for the slow response, I was trying to test this end to end and it took more time than expected. I wasn't aware of the new "unstable" APIs. If we can port the "debug_block" fn to the new unstable APIs then it looks like this should be a simple port.
Do you mean polkadot-sdk crate / rpc folder ? This will be a core feature of Plaza and needs to live in the mono-repo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, the idea is that someone could implement this on the "client-side" like CLI tool which under the hood would do two RPC calls (not adding a new server API called debug_block): For example you could add it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok going with that so we don't have to touch the legacy endpoints, will update the PR |
||
fn debug_block(&self, name: String, block: Hash, bytes: Bytes) -> Result<Bytes, Error>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't get why you should pass the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also asking better docs as to what each param is in general, RPC docs are important and get propagated into PJS/PAPI. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah maybe this is not the one that is meant to be used by end users? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for the docs, added more details.
A few reason, We have 2 runtime methods that make use of this. One that replay an entire block, the other that replay a single transaction. Replaying a single transaction involve that you replay all the transactions that precede Also potentially other Runtime API could make use of this, so hard coding it does not make much sense here. |
||
|
||
/// Returns the keys with prefix, leave empty to get all the keys. | ||
#[method(name = "state_getKeys", blocking)] | ||
#[deprecated(since = "2.0.0", note = "Please use `getKeysPaged` with proper paging support")] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +59,15 @@ where | |
call_data: Bytes, | ||
) -> Result<Bytes, Error>; | ||
|
||
/// Call the runtime method at the block's parent state. | ||
/// and pass the block to be replayed, followed by the call data. | ||
fn debug_block( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder whether these could be pallet specific RPCs/runtime APIs for pallet-revive instead of "state_debug_block" because from my understanding it supposed to be used for "ReviveApi_trace_tx" and "ReviveApi_trace_block"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought it was pretty generic and potentially useful for other pallets that could setup tracing features in a similar way. It can't just be a runtime API as it need to load the runtime and the blocks before passing it over to the runtime api that will handle this data There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general I'm quite reluctant to add new stuff to the legacy RPCs but this is fine by me. You didn't look into implementing this on-top of https://paritytech.github.io/json-rpc-interface-spec/api/archive_unstable_body.html? |
||
&self, | ||
method: String, | ||
block: Block::Hash, | ||
extra_call_data: Bytes, | ||
) -> Result<Bytes, Error>; | ||
|
||
/// Returns the keys with prefix, leave empty to get all the keys. | ||
fn storage_keys( | ||
&self, | ||
|
@@ -209,6 +218,17 @@ where | |
self.backend.call(block, method, data).map_err(Into::into) | ||
} | ||
|
||
fn debug_block( | ||
&self, | ||
ext: &Extensions, | ||
method: String, | ||
block: Block::Hash, | ||
data: Bytes, | ||
) -> Result<Bytes, Error> { | ||
check_if_safe(ext)?; | ||
self.backend.debug_block(method, block, data).map_err(Into::into) | ||
} | ||
|
||
fn storage_keys( | ||
&self, | ||
key_prefix: StorageKey, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know "ballpark size" of the response for
ReviveApi_trace_block
?The reason why I'm asking is because
--rpc-max-response-limit==10MB
by default and maybe worth adding a comment about it whether one needs a bigger limit for this RPCThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point I will mention it in the doc
People running this will probably do it on a dedicated "tracing node" where they can tune this up.
Similarly, can the wasm heap memory @kianenigma be tuned up for this kind of "offchain" call?
For validators, I understand this is defined on-chain, but I want people running such "tracing node" to be able to adjust it.