-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
NOTE: This is intended to evolve into a full RFC, but is at present more of a bare collection of notes.
New overlay items:
Vec<u8>, keyed byname: Name.BTreeMap<Vec<u8>, Vec<u8>>, keyed byname: Name.
These obey transactional principles. They may, at the direction of the runtime through a host function, be archived in a regular, non-Merklised database for later off-chain querying. An RPC may be provided in order to query the contents (if stored).
There are two sets of new host functions for creating, manipulating and querying these items; one set for the Vec<_>s and one for the BTreeMap<_>s.
The set for the Vec<_>s are prefixed blob_ and are:
blob_new(name: Name, mode: Mode)blob_set(name: Name, value: &[u8])blob_clone(name: Name, target_name: Name)blob_rename(name: Name, target_name: Name)blob_edit(name: Name, data: &[u8], offset: u32) -> u32blob_append(name: Name, suffix: &[u8])blob_exists(name: Name) -> boolblob_get(name: Name) -> Option<Vec<u8>>blob_len(name: Name) -> Option<u32>blob_hash32(name: Name, algorithm: Hash32Algorithm) -> Option<[u8; 32]>blob_delete(name: Name)
The set for the BTreeMap<_>s are prefixed map_ and are:
map_new(name: Name, mode: Mode): Creates a new mapnamewith no items. It is cleared if it already exists.map_clone(name: Name, target_name: Name): Creates a clone of the mapnamewith nametarget_name.map_rename(name: Name, target_name: Name): Alters the name of mapnametotarget_name.map_insert(name: Name, key: &[u8], value: &[u8]): Inserts a single (key,value) pair into mapname, creating the map if it did not previously exist and overwriting the item if it did.map_remove_item(name: Name, key: &[u8]): Removes the pair with the givenkeyfrom the mapname, if the map exists and contains the item. Does nothing otherwise.map_exists(name: Name, key: &[u8]) -> bool: Returnstrueiff the mapnameis present in execution state.map_contains(name: Name, key: &[u8]) -> Option<bool>: ReturnsSomeiff the mapnameexists,Noneotherwise. The inner value ofSomeistrueiff the mapnamecontainskey.map_item_get(name: Name, key: &[u8]) -> Option<Vec<u8>>: ReturnsSomeiff the mapnameexists and containskey. If so, the inner value is that associated withkey.map_item_len(name: Name, key: &[u8]) -> Option<u32>: ReturnsSomeiff the mapnameexists and containskey. If so, the inner value is the length of the value associated withkey.map_item_hash32(name: Name, key: &[u8], algorithm: Hash32Algorithm) -> Option<[u8; 32]>: ReturnsSomeiff the mapnameexists and containskey. If so, the inner value is the value associated withkeywhen hashed withalgorithm.map_count(name: Name) -> Option<u32>: ReturnsSomeiff the mapnameexists,Noneotherwise. IfSome, then the inner value is the number of items in the mapname.map_root32(name: Name, structure: Root32Structure) -> Option<[u8; 32]>: Calculates and returns the root of the data structurestructurecontaining the items held in the mapname. ReturnsNoneif mapnamedoes not exist.map_dump(name: Name) -> Option<Vec<(Vec<u8>, Vec<u8>)>>: ReturnsSomeof aVecof all items in the mapname, sorted; orNoneif the mapnamedoes not exist.map_dump_hashed(name: Name, algorithm: Hash32Algorithm) -> Option<Vec<([u8; 32], [u8; 32])>>: ReturnsSomeof aVecof all pairs of keys and values in the mapnamehashed withalgorithmand in order of the (unhashed) key; orNoneif the mapnamedoes not exist.map_next_key(name: Name, key: &[u8], count: u32) -> Option<Vec<Vec<u8>>>: Returns up to the nextcountkeys in mapnameimmediately followingkey. If fewer items exist afterkeythancount, then only the remaining items are returned. If the mapnamedoes not exist thenNoneis returned.map_delete(name: Name): Delete the mapname, clearing all data.
There exists Hash32Algorithm and Root32Structure which should ultimately be defined in separate RFCs.
Mode is defined as:
enum Mode {
#[codec(index = 0)]
Drop,
#[codec(index = 1)]
Archive,
}
Drop: The data may be discarded at the end of block execution without possibility of later querying, on-chain or off-chain. If creation of an item occurs without an explicit mode being given, then the default modeThrowAwayis assumed.Archive: The data should be retained in an database associated with the block which is executing. It will not be accessible on-chain in later blocks (unless e.g. oraclised in some way).
It is intended that future RFCs introduce additional items to this as needed.
Runtime interfaces may exist allowing the runtime to generate proofs for light-clients.
These items can be used to ween ourselves from (mis-)using the Main State Trie, especially for large items which should never be in the PoV.
This functionality can be used to remove system events and code (:CODE) from the main state trie, avoiding possible PoV issues and the problems with storing events as a Vec<Event> (effectively concatenating encoded items). It allows for custom indexing and proof systems, improving efficiency and efficacy.
The host function map_dump_hashed allows for arbitrary digest ("Merkle hash") calculation within the runtime, allowing e.g. indexing by event topic and for proofs to use a base-2 Merkle structure. Multiple roots could be calculated to optimise for multiple indexing systems.
The host function blob_hash32 allows for comparison and retrieval of large blobs, e.g. of runtime code. The location of the "actual" code could even be moved outside of the main state into one of these items.
Storage values and maps may be marked as non-persistent and these host functions may be used, resulting in better performance as well as guaranteed non-persistence. This is useful for block-specific data (like block height), contextual information (e.g. transaction index) as well safe "thread-local" storage.
Future Work
The Mode may be extended to include the possibility of persisting the regular (non-Merklised) key/value database between blocks. Additional configuration may allow a map's keys to be of fixed length.
Metadata
Metadata
Labels
Type
Projects
Status
Status