Skip to content

Commit

Permalink
Stabilize chainHead to version 1 (#147)
Browse files Browse the repository at this point in the history
* Stabilize `chainHead_v1_follow`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_body`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_storage`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_call`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_continue`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_unpin`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_unfollow`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_header`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Stabilize `chainHead_v1_stopOperation`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
  • Loading branch information
lexnv committed Apr 3, 2024
1 parent 602068f commit 814228a
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 98 deletions.
18 changes: 9 additions & 9 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
- [archive_unstable_header](api/archive_unstable_header.md)
- [archive_unstable_storage](api/archive_unstable_storage.md)
- [chainHead](api/chainHead.md)
- [chainHead_unstable_body](api/chainHead_unstable_body.md)
- [chainHead_unstable_call](api/chainHead_unstable_call.md)
- [chainHead_unstable_continue](api/chainHead_unstable_continue.md)
- [chainHead_unstable_follow](api/chainHead_unstable_follow.md)
- [chainHead_unstable_header](api/chainHead_unstable_header.md)
- [chainHead_unstable_stopOperation](api/chainHead_unstable_stopOperation.md)
- [chainHead_unstable_storage](api/chainHead_unstable_storage.md)
- [chainHead_unstable_unfollow](api/chainHead_unstable_unfollow.md)
- [chainHead_unstable_unpin](api/chainHead_unstable_unpin.md)
- [chainHead_v1_body](api/chainHead_v1_body.md)
- [chainHead_v1_call](api/chainHead_v1_call.md)
- [chainHead_v1_continue](api/chainHead_v1_continue.md)
- [chainHead_v1_follow](api/chainHead_v1_follow.md)
- [chainHead_v1_header](api/chainHead_v1_header.md)
- [chainHead_v1_stopOperation](api/chainHead_v1_stopOperation.md)
- [chainHead_v1_storage](api/chainHead_v1_storage.md)
- [chainHead_v1_unfollow](api/chainHead_v1_unfollow.md)
- [chainHead_v1_unpin](api/chainHead_v1_unpin.md)
- [chainSpec](api/chainSpec.md)
- [chainSpec_v1_chainName](api/chainSpec_v1_chainName.md)
- [chainSpec_v1_genesisHash](api/chainSpec_v1_genesisHash.md)
Expand Down
4 changes: 2 additions & 2 deletions src/api/archive_unstable_storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ For the purpose of storage requests, the trie root hash of the child tries of th
If the height of the block hash provided is less than or equal to the current finalized block height (which can be obtained via archive_unstable_finalizedHeight), then calling this method with the same parameters will always return the same response.
If the height of the block hash provided is greater than the current finalized block height, then the block might be pruned at any time and calling this method may return null.

This function should be used when the target block is older than the blocks reported by `chainHead_unstable_follow`.
Use `chainHead_unstable_storage` if instead you want to retrieve the storage of a block obtained by the `chainHead_unstable_follow`.
This function should be used when the target block is older than the blocks reported by `chainHead_v1_follow`.
Use `chainHead_v1_storage` if instead you want to retrieve the storage of a block obtained by the `chainHead_v1_follow`.

If `items` contains multiple identical or overlapping queries, the JSON-RPC server can choose whether to merge or not the items in the result. For example, if the request contains two items with the same key, one with `hash` and one with `value`, the JSON-RPC server can choose whether to generate two `item` objects, one with the value and one with the hash, or only a single `item` object with both `hash` and `value` set.

Expand Down
12 changes: 6 additions & 6 deletions src/api/chainHead.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Functions with the `chainHead` prefix allow tracking the head of the chain (in other words, the latest new and finalized blocks) and their storage.

The most important function in this category is `chainHead_unstable_follow`. It is the first function that is the user is expected to call, before (almost) any other. `chainHead_unstable_follow` returns the current list of blocks that are near the head of the chain, and generates notifications about new blocks. The `chainHead_unstable_body`, `chainHead_unstable_call`, `chainHead_unstable_header` and `chainHead_unstable_storage` functions can be used to obtain more details about the blocks that have been reported by `chainHead_unstable_follow`.
The most important function in this category is `chainHead_v1_follow`. It is the first function that is the user is expected to call, before (almost) any other. `chainHead_v1_follow` returns the current list of blocks that are near the head of the chain, and generates notifications about new blocks. The `chainHead_v1_body`, `chainHead_v1_call`, `chainHead_v1_header` and `chainHead_v1_storage` functions can be used to obtain more details about the blocks that have been reported by `chainHead_v1_follow`.

These functions are the functions most of the JSON-RPC clients will most commonly use. A JSON-RPC server implementation is encouraged to prioritize serving these functions over other functions, and to put pinned blocks in a quickly-accessible cache.

Expand All @@ -12,23 +12,23 @@ _This section contains a small beginner guide destined for JSON-RPC client users

This beginner guide shows how to use the `chainHead` functions in order to know the value of a certain storage item.

1. Call `chainHead_unstable_follow` with `withRuntime: true` to obtain a `followSubscription`. This `followSubscription` will need to be passed when calling most of the other `chainHead`-prefixed functions. If at any point in the future the JSON-RPC server sends back a `{"event": "stop"}` notification, jump back to step 1.
1. Call `chainHead_v1_follow` with `withRuntime: true` to obtain a `followSubscription`. This `followSubscription` will need to be passed when calling most of the other `chainHead`-prefixed functions. If at any point in the future the JSON-RPC server sends back a `{"event": "stop"}` notification, jump back to step 1.

2. When the JSON-RPC server sends back a `{"event": "initialized"}` notification with `subscription` equal to your `followSubscription`, store the value of `finalizedBlockHashes` found in that notification. If `finalizedBlockHashes` contains multiple values, you should use the last entry. The last entry corresponds to the _current finalized block_ of the chain. You must then call `chainHead_unstable_unpin`, passing the `followSubscription` and each of the other values in `finalizedBlockHashes`.
2. When the JSON-RPC server sends back a `{"event": "initialized"}` notification with `subscription` equal to your `followSubscription`, store the value of `finalizedBlockHashes` found in that notification. If `finalizedBlockHashes` contains multiple values, you should use the last entry. The last entry corresponds to the _current finalized block_ of the chain. You must then call `chainHead_v1_unpin`, passing the `followSubscription` and each of the other values in `finalizedBlockHashes`.

3. Make sure that the `finalizedBlockRuntime` field of the event contains a field `type` containing `valid`, and that the `spec` -> `apis` object contains a key `0xd2bc9897eed08f15` whose value is `3`. This verifies that the runtime of the chain supports the `Metadata_metadata` function that we will call below (`0xd2bc9897eed08f15` is the 64bits blake2 hash of the ASCII string `Metadata`). If it is not the case, enter panic mode as the client software is incompatible with the current state of the blockchain.

4. Call `chainHead_unstable_call` with `hash` equal to the _current finalized block_ you've just retrieved, `function` equal to `Metadata_metadata`, and an empty `callParameters`.
4. Call `chainHead_v1_call` with `hash` equal to the _current finalized block_ you've just retrieved, `function` equal to `Metadata_metadata`, and an empty `callParameters`.

5. If the JSON-RPC server sends back a `{"event": "operationInaccessible"}` notification, jump back to step 4 to try again. If the JSON-RPC server sends back a `{"event": "operationError"}` notification, enter panic mode. If the JSON-RPC server instead sends back a `{"event": "operationCallDone"}` notification, save the return value.

6. The return value you've just saved is called the metadata, prefixed with its SCALE-compact-encoded length. You must decode and parse this metadata. How to do this is out of scope of this small guide. The metadata contains information about the layout of the storage of the chain. Inspect it to determine how to find the storage item you're looking for.

7. In order to obtain a value in the storage, call `chainHead_unstable_storage` with `hash` equal to the _current finalized block_, `key` the desired key, and `type` equal to `value`. If the JSON-RPC server instead sends back a `{"event": "operationInaccessible"}` notification, the value you're looking for is unfortunately inaccessible and you can either try again or give up. If the JSON-RPC server instead sends back a `{"event": "operationStorageItems"}` notification, you can find the desired value inside.
7. In order to obtain a value in the storage, call `chainHead_v1_storage` with `hash` equal to the _current finalized block_, `key` the desired key, and `type` equal to `value`. If the JSON-RPC server instead sends back a `{"event": "operationInaccessible"}` notification, the value you're looking for is unfortunately inaccessible and you can either try again or give up. If the JSON-RPC server instead sends back a `{"event": "operationStorageItems"}` notification, you can find the desired value inside.

8. You are strongly encouraged to maintain [a `Set`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Set) of the blocks where the runtime changes. Whenever a `{"event": "newBlock"}` notification is received with `subscription` equal to your `followSubcriptionId`, and `newRuntime` is non-null, store the provided `blockHash` in this set.

9. Whenever a `{"event": "finalized"}` notification is received with `subscription` equal to your `followSubcriptionId`, call `chainHead_unstable_unpin` with the _current finalized block_ hash, the `prunedBlockHashes`, and with each value in `finalizedBlockHashes` of the `finalized` event except for the last entry. The last entry in `finalizedBlockHashes` becomes your new _current finalized block_. If one or more entries of `finalizedBlockHashes` are found in your `Set` (see step 7), remove them from the set and jump to step 3 as the metadata has likely been modified. Otherwise, jump to step 7.
9. Whenever a `{"event": "finalized"}` notification is received with `subscription` equal to your `followSubcriptionId`, call `chainHead_v1_unpin` with the _current finalized block_ hash, the `prunedBlockHashes`, and with each value in `finalizedBlockHashes` of the `finalized` event except for the last entry. The last entry in `finalizedBlockHashes` becomes your new _current finalized block_. If one or more entries of `finalizedBlockHashes` are found in your `Set` (see step 7), remove them from the set and jump to step 3 as the metadata has likely been modified. Otherwise, jump to step 7.

Note that these steps are a bit complicated. Any serious user of the JSON-RPC interface is expected to implement high-level wrappers around the various JSON-RPC functions.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# chainHead_unstable_body
# chainHead_v1_body

**Parameters**:

- `followSubscription`: An opaque string that was returned by `chainHead_unstable_follow`.
- `followSubscription`: An opaque string that was returned by `chainHead_v1_follow`.
- `hash`: String containing a hexadecimal-encoded hash of the header of the block whose body will be retrieved.

**Return value**: A JSON object.
Expand Down Expand Up @@ -32,25 +32,25 @@ This return value indicates that the request has successfully started.

This return value indicates the request couldn't be started because the server is overloaded, or that the `followSubscription` is invalid or stale.

The JSON-RPC client should try again after an on-going `chainHead_unstable_storage`, `chainHead_unstable_body`, or `chainHead_unstable_call` operation finishes.
The JSON-RPC client should try again after an on-going `chainHead_v1_storage`, `chainHead_v1_body`, or `chainHead_v1_call` operation finishes.

The JSON-RPC server must accept at least 16 concurrent operations for any given `chainHead_unstable_follow` subscription. In other words, as long as the JSON-RPC client makes sure that no more than 16 operations are in progress at any given item, it is guaranteed that all of its operations will be accepted by the JSON-RPC server.
For this purpose, each item requested through `chainHead_unstable_storage` counts as one operation, and each call to `chainHead_unstable_body` and `chainHead_unstable_call` counts as one operation.
The JSON-RPC server must accept at least 16 concurrent operations for any given `chainHead_v1_follow` subscription. In other words, as long as the JSON-RPC client makes sure that no more than 16 operations are in progress at any given item, it is guaranteed that all of its operations will be accepted by the JSON-RPC server.
For this purpose, each item requested through `chainHead_v1_storage` counts as one operation, and each call to `chainHead_v1_body` and `chainHead_v1_call` counts as one operation.

## Overview

The JSON-RPC server must start obtaining the body (in other words the list of transactions) of the given block.

The progress of the operation is indicated through `operationBodyDone`, `operationInaccessible`, or `operationError` notifications generated on the corresponding `chainHead_unstable_follow` subscription.
The progress of the operation is indicated through `operationBodyDone`, `operationInaccessible`, or `operationError` notifications generated on the corresponding `chainHead_v1_follow` subscription.

The operation continues even if the target block is unpinned with `chainHead_unstable_unpin`.
The operation continues even if the target block is unpinned with `chainHead_v1_unpin`.

This function should be seen as a complement to `chainHead_unstable_follow`, allowing the JSON-RPC client to retrieve more information about a block that has been reported. Use `archive_unstable_body` if instead you want to retrieve the body of an arbitrary block.
This function should be seen as a complement to `chainHead_v1_follow`, allowing the JSON-RPC client to retrieve more information about a block that has been reported. Use `archive_unstable_body` if instead you want to retrieve the body of an arbitrary block.

## Possible errors

- If the networking part of the behaviour fails, then a `{"event": "operationInaccessible"}` notification is generated (as explained above).
- If the `followSubscription` is invalid or stale, then `"result": "limitReached"` is returned (as explained above).
- A JSON-RPC error with error code `-32801` is generated if the block hash passed as parameter doesn't correspond to any block that has been reported by `chainHead_unstable_follow`, or the block hash has been unpinned.
- A JSON-RPC error with error code `-32801` is generated if the block hash passed as parameter doesn't correspond to any block that has been reported by `chainHead_v1_follow`, or the block hash has been unpinned.
- A JSON-RPC error with error code `-32602` is generated if one of the parameters doesn't correspond to the expected type (similarly to a missing parameter or an invalid parameter type).
- A JSON-RPC error with error code `-32603` is generated if the JSON-RPC server cannot interpret the block (hardware issues, corrupted database, disk failure etc).
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# chainHead_unstable_call
# chainHead_v1_call

**Parameters**:

- `followSubscription`: An opaque string that was returned by `chainHead_unstable_follow`. The `withRuntime` parameter of the call must have been equal to `true`.
- `followSubscription`: An opaque string that was returned by `chainHead_v1_follow`. The `withRuntime` parameter of the call must have been equal to `true`.
- `hash`: String containing the hexadecimal-encoded hash of the header of the block to make the call against.
- `function`: Name of the runtime entry point to call as a string.
- `callParameters`: Hexadecimal-encoded SCALE-encoded value to pass as input to the runtime function.
Expand Down Expand Up @@ -34,22 +34,22 @@ This return value indicates that the request has successfully started.

This return value indicates the call couldn't be started because the server is overloaded, or that the `followSubscription` is invalid or stale.

The JSON-RPC client should try again after an on-going `chainHead_unstable_storage`, `chainHead_unstable_body`, or `chainHead_unstable_call` operation finishes.
The JSON-RPC client should try again after an on-going `chainHead_v1_storage`, `chainHead_v1_body`, or `chainHead_v1_call` operation finishes.

The JSON-RPC server must accept at least 16 concurrent operations for any given `chainHead_unstable_follow` subscription. In other words, as long as the JSON-RPC client makes sure that no more than 16 operations are in progress at any given item, it is guaranteed that all of its operations will be accepted by the JSON-RPC server.
For this purpose, each item requested through `chainHead_unstable_storage` counts as one operation, and each call to `chainHead_unstable_body` and `chainHead_unstable_call` counts as one operation.
The JSON-RPC server must accept at least 16 concurrent operations for any given `chainHead_v1_follow` subscription. In other words, as long as the JSON-RPC client makes sure that no more than 16 operations are in progress at any given item, it is guaranteed that all of its operations will be accepted by the JSON-RPC server.
For this purpose, each item requested through `chainHead_v1_storage` counts as one operation, and each call to `chainHead_v1_body` and `chainHead_v1_call` counts as one operation.

## Overview

The JSON-RPC server must invoke the entry point of the runtime of the given block using the storage of the given block.

**Note**: The runtime is still allowed to call host functions with side effects, however these side effects must be discarded. For example, a runtime function call can try to modify the storage of the chain, but this modification must not be actually applied. The only motivation for performing a call is to obtain the return value.

The progress of the operation is indicated through `operationCallDone`, `operationInaccessible`, or `operationError` notifications generated on the corresponding `chainHead_unstable_follow` subscription.
The progress of the operation is indicated through `operationCallDone`, `operationInaccessible`, or `operationError` notifications generated on the corresponding `chainHead_v1_follow` subscription.

The operation continues even if the target block is unpinned with `chainHead_unstable_unpin`.
The operation continues even if the target block is unpinned with `chainHead_v1_unpin`.

This function should be seen as a complement to `chainHead_unstable_follow`, allowing the JSON-RPC client to retrieve more information about a block that has been reported. Use `archive_unstable_call` if instead you want to call the runtime of an arbitrary block.
This function should be seen as a complement to `chainHead_v1_follow`, allowing the JSON-RPC client to retrieve more information about a block that has been reported. Use `archive_unstable_call` if instead you want to call the runtime of an arbitrary block.

**Note**: This can be used as a replacement for the legacy `state_getMetadata`, `system_accountNextIndex`, and `payment_queryInfo` functions.

Expand All @@ -59,7 +59,7 @@ This function should be seen as a complement to `chainHead_unstable_follow`, all
- If the `followSubscription` is invalid or stale, then `"result": "limitReached"` is returned (as explained above).
- If the method to call doesn't exist in the Wasm runtime of the chain, then an `{"event": "operationError"}` notification is generated.
- If the runtime call fails (e.g. because it triggers a panic in the runtime, running out of memory, etc., or if the runtime call takes too much time), then an `{"event": "operationError"}` notification is generated.
- A JSON-RPC error with error code `-32801` is generated if the block hash passed as parameter doesn't correspond to any block that has been reported by `chainHead_unstable_follow`, or the block hash has been unpinned.
- A JSON-RPC error with error code `-32801` is generated if the block hash passed as parameter doesn't correspond to any block that has been reported by `chainHead_v1_follow`, or the block hash has been unpinned.
- A JSON-RPC error with error code `-32802` is generated if the `followSubscription` corresponds to a follow where `withRuntime` was `false`.
- A JSON-RPC error with error code `-32602` is generated if one of the parameters doesn't correspond to the expected type (similarly to a missing parameter or an invalid parameter type).

Expand Down
Loading

0 comments on commit 814228a

Please sign in to comment.