-
Notifications
You must be signed in to change notification settings - Fork 2.6k
[RPC-Spec-V2] Storage: Add support for storage closest merkle descendant #14550
Comments
(merkle as in Ralph Merkle, not Angela Merkel) |
We could first check if the provided key exists in the trie-db: substrate/primitives/state-machine/src/backend.rs Lines 208 to 220 in 25d9dd1
If the key does not exist in storage, we'd need to iterate over the next key available: substrate/primitives/state-machine/src/backend.rs Lines 222 to 230 in 25d9dd1
And finally, we can fetch the proof by providing the key found above substrate/client/api/src/proof_provider.rs Lines 27 to 41 in 25d9dd1
I do have a few questions about this approach since I don't have much context wrt our trie-db implementation:
Would love to get some feedback on this 🙏 (@cheme @arkpar @bkchr) |
I got no idea what this But to reply:
The merkle value is the hash of a merkle node (branch, or leaf), no idea if it can include inline nodes though: probably can return the sized encoded node in this case, but depending on the purpose, maybe it is the parent hash that we want??? So the storage proof does include this info, but this is not really how one should access it: producing the storage proof is costy and the info is just something we query while accessing the trie.
Next storage only access storage content, since it is a storage rpc, it seems appropriate, but merkle value is an info that we fetch at trie level. Note that in practice, using triedb iterator on the block state is more efficient than using next_storage to access content. But generally our subscription are running over the change of storage value seen after each block processing. These changes are pure storage change (no trie level info). Getting change in merkle value for subscription (done efficiently, I mean not querying at each block) would mean having it plugged on the trie root processing which is quite not easy to do (we can read the delta of all trie node change but these do not have structural information so no way to say which is the right merkle value unless rebuilding the trie and accessing it which is not as bad as doing query on state but still an unneeded overhead). So I don't have a good solution (costy or breaking badly the architecture by leaking rpc subscription into block processsing).
if it is just for query, I would say yes, but I am not sure if a read_proof is needed here, and if IIUC the target is subscription, so there should be no call to exists_storage (just compare subscribed item against each block storage changes).
Using the read proof is better (we access trie content in memory when storage_hash may hit the db), but producing the read proof is more costy in the first place. |
Thinking of (but maybe there is the intention to directly query content from the return merkle value, but this is something that limit how to store the trie (currently we can somehow do it but some future design would break this possibility, but would just mean accessing the key from root which may not be that bad (but then just a boolean is enough)). |
paritytech/json-rpc-interface-spec#37 (comment) maybe this helps |
Thanks, got my replies:
So if the intention is to check for a change, then I think we should just return event with key indicating a change did occur at or under the key. |
@tomaka, just pinging you as this conversation is relevant re the |
The I can't just say "an opaque value" in the specification, as the JSON-RPC client might want to disconnect and reconnect and still have the same value. In other words, the meaning of this opaque value had to be defined so that all server implementations return the same. |
Considering the above it would be simpler from the substrate point of view to have an event-based notification regarding storage changes (similar what we have today). One downside of this would be indeed that clients may disconnect and reconnect. In this window of time, the storage might change without the client knowing it. I'm not sure how expensive that might be from the light-client perspective. |
If you're talking about changes to the JSON-RPC API, please let's not discuss this in the Substrate repo. The reason why there's a JSON-RPC API repo is specifically so that everyone can follow discussions, rather than look around for random bits of discussions in Substrate issues like happens often. |
From the spec conversation here:
This makes me lean towards implementing a hashing ("merkle value hash"), but as mentioned above it might be tricky to implement. It is my understanding that the paritytech/parity-db#199 will add support for That would imply:
The following change could keep the RPC spec agnostic of the multi-tree implementation: trieKey: A hexadecimal-encoded string representing the root key of the trie for which storage look-ups are performed That makes me wonder:
struct NewNode {
data: Vec<u8>,
// Add a new hash field updated to the top of the trie with every storage change
merkle_value: Hash,
children: Vec<NodeRef>, // May reference the node in the same commit or an existing node.
} Would love to hear your thoughts on this 🙏 |
I realize I did not think about:
thus I did propose to just emit a boolean event when something under the prefix did change, but that do not cover these two cases. But if the light client is missing events or disconnecting would querying a storage proof at disconnected block and a storage proof at reconnected block be enough.
I don't remember too well all the design. cc @arkpar (to sum-up: the change notification is only looking at key value change of each imported blocks for notification, but we could also pass the trie nodes block modificatio and use the fact that the key is build from "trienodekeyprefix"++"trienodehash" to return the new trienodehash on change for the first trienodekeyprefix of a prefix we listen at). But removing this key prefixing scheme is something that would be good for the trie crate (requires removing deps on rocksdb first). |
For the |
…1153) This PR adds support for fetching the closest merkle value of some key. Builds on top of - paritytech/trie#199 Migrates paritytech/substrate#14818 to the monorepo. Closes: paritytech/substrate#14550 Closes: #1506 // @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Sebastian Kunert <skunert49@gmail.com>
…aritytech#1153) This PR adds support for fetching the closest merkle value of some key. Builds on top of - paritytech/trie#199 Migrates paritytech/substrate#14818 to the monorepo. Closes: paritytech/substrate#14550 Closes: paritytech#1506 // @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Sebastian Kunert <skunert49@gmail.com>
Fetch the Merkel value of the provided key when using the
closest-descendant-merkle-value
param.When the key is not present in the trie, the Merkle value of the closest descendant must be returned.
From spec: https://github.com/paritytech/json-rpc-interface-spec/blob/main/src/api/chainHead_unstable_storage.md
// @paritytech/subxt-team
The text was updated successfully, but these errors were encountered: