@@ -26,6 +26,7 @@ use sp_state_machine::{
2626 ChangesTrieState , ChangesTrieStorage as StateChangesTrieStorage , ChangesTrieTransaction ,
2727 StorageCollection , ChildStorageCollection ,
2828} ;
29+ use sp_storage:: { StorageData , StorageKey , ChildInfo } ;
2930use crate :: {
3031 blockchain:: {
3132 Backend as BlockchainBackend , well_known_cache_keys
@@ -38,6 +39,7 @@ use sp_consensus::BlockOrigin;
3839use parking_lot:: RwLock ;
3940
4041pub use sp_state_machine:: Backend as StateBackend ;
42+ use std:: marker:: PhantomData ;
4143
4244/// Extracts the state backend type for the given backend.
4345pub type StateBackendFor < B , Block > = <B as Backend < Block > >:: State ;
@@ -237,6 +239,123 @@ pub trait AuxStore {
237239 fn get_aux ( & self , key : & [ u8 ] ) -> sp_blockchain:: Result < Option < Vec < u8 > > > ;
238240}
239241
242+ /// An `Iterator` that iterates keys in a given block under a prefix.
243+ pub struct KeyIterator < ' a , State , Block > {
244+ state : State ,
245+ prefix : Option < & ' a StorageKey > ,
246+ current_key : Vec < u8 > ,
247+ _phantom : PhantomData < Block > ,
248+ }
249+
250+ impl < ' a , State , Block > KeyIterator < ' a , State , Block > {
251+ /// create a KeyIterator instance
252+ pub fn new ( state : State , prefix : Option < & ' a StorageKey > , current_key : Vec < u8 > ) -> Self {
253+ Self {
254+ state,
255+ prefix,
256+ current_key,
257+ _phantom : PhantomData ,
258+ }
259+ }
260+ }
261+
262+ impl < ' a , State , Block > Iterator for KeyIterator < ' a , State , Block > where
263+ Block : BlockT ,
264+ State : StateBackend < HashFor < Block > > ,
265+ {
266+ type Item = StorageKey ;
267+
268+ fn next ( & mut self ) -> Option < Self :: Item > {
269+ let next_key = self . state
270+ . next_storage_key ( & self . current_key )
271+ . ok ( )
272+ . flatten ( ) ?;
273+ // this terminates the iterator the first time it fails.
274+ if let Some ( prefix) = self . prefix {
275+ if !next_key. starts_with ( & prefix. 0 [ ..] ) {
276+ return None ;
277+ }
278+ }
279+ self . current_key = next_key. clone ( ) ;
280+ Some ( StorageKey ( next_key) )
281+ }
282+ }
283+ /// Provides acess to storage primitives
284+ pub trait StorageProvider < Block : BlockT , B : Backend < Block > > {
285+ /// Given a `BlockId` and a key, return the value under the key in that block.
286+ fn storage ( & self , id : & BlockId < Block > , key : & StorageKey ) -> sp_blockchain:: Result < Option < StorageData > > ;
287+
288+ /// Given a `BlockId` and a key prefix, return the matching storage keys in that block.
289+ fn storage_keys ( & self , id : & BlockId < Block > , key_prefix : & StorageKey ) -> sp_blockchain:: Result < Vec < StorageKey > > ;
290+
291+ /// Given a `BlockId` and a key, return the value under the hash in that block.
292+ fn storage_hash ( & self , id : & BlockId < Block > , key : & StorageKey ) -> sp_blockchain:: Result < Option < Block :: Hash > > ;
293+
294+ /// Given a `BlockId` and a key prefix, return the matching child storage keys and values in that block.
295+ fn storage_pairs (
296+ & self ,
297+ id : & BlockId < Block > ,
298+ key_prefix : & StorageKey
299+ ) -> sp_blockchain:: Result < Vec < ( StorageKey , StorageData ) > > ;
300+
301+ /// Given a `BlockId` and a key prefix, return a `KeyIterator` iterates matching storage keys in that block.
302+ fn storage_keys_iter < ' a > (
303+ & self ,
304+ id : & BlockId < Block > ,
305+ prefix : Option < & ' a StorageKey > ,
306+ start_key : Option < & StorageKey >
307+ ) -> sp_blockchain:: Result < KeyIterator < ' a , B :: State , Block > > ;
308+
309+ /// Given a `BlockId`, a key and a child storage key, return the value under the key in that block.
310+ fn child_storage (
311+ & self ,
312+ id : & BlockId < Block > ,
313+ storage_key : & StorageKey ,
314+ child_info : ChildInfo ,
315+ key : & StorageKey
316+ ) -> sp_blockchain:: Result < Option < StorageData > > ;
317+
318+ /// Given a `BlockId`, a key prefix, and a child storage key, return the matching child storage keys.
319+ fn child_storage_keys (
320+ & self ,
321+ id : & BlockId < Block > ,
322+ child_storage_key : & StorageKey ,
323+ child_info : ChildInfo ,
324+ key_prefix : & StorageKey
325+ ) -> sp_blockchain:: Result < Vec < StorageKey > > ;
326+
327+ /// Given a `BlockId`, a key and a child storage key, return the hash under the key in that block.
328+ fn child_storage_hash (
329+ & self ,
330+ id : & BlockId < Block > ,
331+ storage_key : & StorageKey ,
332+ child_info : ChildInfo ,
333+ key : & StorageKey
334+ ) -> sp_blockchain:: Result < Option < Block :: Hash > > ;
335+
336+ /// Get longest range within [first; last] that is possible to use in `key_changes`
337+ /// and `key_changes_proof` calls.
338+ /// Range could be shortened from the beginning if some changes tries have been pruned.
339+ /// Returns Ok(None) if changes tries are not supported.
340+ fn max_key_changes_range (
341+ & self ,
342+ first : NumberFor < Block > ,
343+ last : BlockId < Block > ,
344+ ) -> sp_blockchain:: Result < Option < ( NumberFor < Block > , BlockId < Block > ) > > ;
345+
346+ /// Get pairs of (block, extrinsic) where key has been changed at given blocks range.
347+ /// Works only for runtimes that are supporting changes tries.
348+ ///
349+ /// Changes are returned in descending order (i.e. last block comes first).
350+ fn key_changes (
351+ & self ,
352+ first : NumberFor < Block > ,
353+ last : BlockId < Block > ,
354+ storage_key : Option < & StorageKey > ,
355+ key : & StorageKey
356+ ) -> sp_blockchain:: Result < Vec < ( NumberFor < Block > , u32 ) > > ;
357+ }
358+
240359/// Client backend.
241360///
242361/// Manages the data layer.
0 commit comments