Introduction
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_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.
Usage
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.
-
Call
chainHead_v1_follow
withwithRuntime: true
to obtain afollowSubscription
. ThisfollowSubscription
will need to be passed when calling most of the otherchainHead
-prefixed functions. If at any point in the future the JSON-RPC server sends back a{"event": "stop"}
notification, jump back to step 1. -
When the JSON-RPC server sends back a
{"event": "initialized"}
notification withsubscription
equal to yourfollowSubscription
, store the value offinalizedBlockHashes
found in that notification. IffinalizedBlockHashes
contains multiple values, you should use the last entry. The last entry corresponds to the current finalized block of the chain. You must then callchainHead_v1_unpin
, passing thefollowSubscription
and each of the other values infinalizedBlockHashes
. -
Make sure that the
finalizedBlockRuntime
field of the event contains a fieldtype
containingvalid
, and that thespec
->apis
object contains a key0xd2bc9897eed08f15
whose value is3
. This verifies that the runtime of the chain supports theMetadata_metadata
function that we will call below (0xd2bc9897eed08f15
is the 64bits blake2 hash of the ASCII stringMetadata
). If it is not the case, enter panic mode as the client software is incompatible with the current state of the blockchain. -
Call
chainHead_v1_call
withhash
equal to the current finalized block you've just retrieved,function
equal toMetadata_metadata
, and an emptycallParameters
. -
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. -
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.
-
In order to obtain a value in the storage, call
chainHead_v1_storage
withhash
equal to the current finalized block,key
the desired key, andtype
equal tovalue
. 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. -
You are strongly encouraged to maintain a
Set
of the blocks where the runtime changes. Whenever a{"event": "newBlock"}
notification is received withsubscription
equal to yourfollowSubcriptionId
, andnewRuntime
is non-null, store the providedblockHash
in this set. -
Whenever a
{"event": "finalized"}
notification is received withsubscription
equal to yourfollowSubcriptionId
, callchainHead_v1_unpin
with the current finalized block hash, theprunedBlockHashes
, and with each value infinalizedBlockHashes
of thefinalized
event except for the last entry. The last entry infinalizedBlockHashes
becomes your new current finalized block. If one or more entries offinalizedBlockHashes
are found in yourSet
(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.
For example, if multiple storage values are desired, only step 7 should be repeated once per storage item. All other steps are application-wide.