1818use sp_std:: prelude:: * ;
1919use sp_std:: borrow:: Borrow ;
2020use codec:: { FullCodec , FullEncode , Decode , Encode , EncodeLike } ;
21- use crate :: { storage:: { self , unhashed, StorageAppend } , Never } ;
21+ use crate :: { storage:: { self , unhashed, StorageAppend , PrefixIterator } , Never } ;
2222use crate :: hash:: { StorageHasher , Twox128 , ReversibleStorageHasher } ;
2323
2424/// Generator for `StorageDoubleMap` used by `decl_storage`.
@@ -213,10 +213,11 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
213213 KArg1 : ?Sized + EncodeLike < K1 >
214214 {
215215 let prefix = Self :: storage_double_map_final_key1 ( k1) ;
216- storage:: PrefixIterator :: < V > {
216+ storage:: PrefixIterator {
217217 prefix : prefix. clone ( ) ,
218218 previous_key : prefix,
219- phantom_data : Default :: default ( ) ,
219+ drain : false ,
220+ closure : |_raw_key, mut raw_value| V :: decode ( & mut raw_value) ,
220221 }
221222 }
222223
@@ -322,54 +323,6 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
322323 }
323324}
324325
325- /// Iterate over a prefix and decode raw_key and raw_value into `T`.
326- pub struct MapIterator < T > {
327- prefix : Vec < u8 > ,
328- previous_key : Vec < u8 > ,
329- /// If true then value are removed while iterating
330- drain : bool ,
331- /// Function that take `(raw_key_without_prefix, raw_value)` and decode `T`.
332- /// `raw_key_without_prefix` is the raw storage key without the prefix iterated on.
333- closure : fn ( & [ u8 ] , & [ u8 ] ) -> Result < T , codec:: Error > ,
334- }
335-
336- impl < T > Iterator for MapIterator < T > {
337- type Item = T ;
338-
339- fn next ( & mut self ) -> Option < Self :: Item > {
340- loop {
341- let maybe_next = sp_io:: storage:: next_key ( & self . previous_key )
342- . filter ( |n| n. starts_with ( & self . prefix ) ) ;
343- break match maybe_next {
344- Some ( next) => {
345- self . previous_key = next;
346- let raw_value = match unhashed:: get_raw ( & self . previous_key ) {
347- Some ( raw_value) => raw_value,
348- None => {
349- frame_support:: print ( "ERROR: next_key returned a key with no value in MapIterator" ) ;
350- continue
351- }
352- } ;
353- if self . drain {
354- unhashed:: kill ( & self . previous_key )
355- }
356- let raw_key_without_prefix = & self . previous_key [ self . prefix . len ( ) ..] ;
357- let item = match ( self . closure ) ( raw_key_without_prefix, & raw_value[ ..] ) {
358- Ok ( item) => item,
359- Err ( _e) => {
360- frame_support:: print ( "ERROR: (key, value) failed to decode in MapIterator" ) ;
361- continue
362- }
363- } ;
364-
365- Some ( item)
366- }
367- None => None ,
368- }
369- }
370- }
371- }
372-
373326impl <
374327 K1 : FullCodec ,
375328 K2 : FullCodec ,
@@ -379,8 +332,8 @@ impl<
379332 G :: Hasher1 : ReversibleStorageHasher ,
380333 G :: Hasher2 : ReversibleStorageHasher
381334{
382- type PrefixIterator = MapIterator < ( K2 , V ) > ;
383- type Iterator = MapIterator < ( K1 , K2 , V ) > ;
335+ type PrefixIterator = PrefixIterator < ( K2 , V ) > ;
336+ type Iterator = PrefixIterator < ( K1 , K2 , V ) > ;
384337
385338 fn iter_prefix ( k1 : impl EncodeLike < K1 > ) -> Self :: PrefixIterator {
386339 let prefix = G :: storage_double_map_final_key1 ( k1) ;
@@ -423,34 +376,54 @@ impl<
423376 iterator
424377 }
425378
426- fn translate < O : Decode , F : Fn ( O ) -> Option < V > > ( f : F ) {
379+ fn translate < O : Decode , F : Fn ( K1 , K2 , O ) -> Option < V > > ( f : F ) {
427380 let prefix = G :: prefix_hash ( ) ;
428381 let mut previous_key = prefix. clone ( ) ;
429- loop {
430- match sp_io:: storage:: next_key ( & previous_key) . filter ( |n| n. starts_with ( & prefix) ) {
431- Some ( next) => {
432- previous_key = next;
433- let maybe_value = unhashed:: get :: < O > ( & previous_key) ;
434- match maybe_value {
435- Some ( value) => match f ( value) {
436- Some ( new) => unhashed:: put :: < V > ( & previous_key, & new) ,
437- None => unhashed:: kill ( & previous_key) ,
438- } ,
439- None => continue ,
440- }
441- }
442- None => return ,
382+ while let Some ( next) = sp_io:: storage:: next_key ( & previous_key)
383+ . filter ( |n| n. starts_with ( & prefix) )
384+ {
385+ previous_key = next;
386+ let value = match unhashed:: get :: < O > ( & previous_key) {
387+ Some ( value) => value,
388+ None => {
389+ crate :: debug:: error!( "Invalid translate: fail to decode old value" ) ;
390+ continue
391+ } ,
392+ } ;
393+ let mut key_material = G :: Hasher1 :: reverse ( & previous_key[ prefix. len ( ) ..] ) ;
394+ let key1 = match K1 :: decode ( & mut key_material) {
395+ Ok ( key1) => key1,
396+ Err ( _) => {
397+ crate :: debug:: error!( "Invalid translate: fail to decode key1" ) ;
398+ continue
399+ } ,
400+ } ;
401+
402+ let mut key2_material = G :: Hasher2 :: reverse ( & key_material) ;
403+ let key2 = match K2 :: decode ( & mut key2_material) {
404+ Ok ( key2) => key2,
405+ Err ( _) => {
406+ crate :: debug:: error!( "Invalid translate: fail to decode key2" ) ;
407+ continue
408+ } ,
409+ } ;
410+
411+ match f ( key1, key2, value) {
412+ Some ( new) => unhashed:: put :: < V > ( & previous_key, & new) ,
413+ None => unhashed:: kill ( & previous_key) ,
443414 }
444415 }
445416 }
446417}
447418
448419/// Test iterators for StorageDoubleMap
449420#[ cfg( test) ]
450- #[ allow( dead_code) ]
451421mod test_iterators {
452422 use codec:: { Encode , Decode } ;
453- use crate :: storage:: { generator:: StorageDoubleMap , IterableStorageDoubleMap , unhashed} ;
423+ use crate :: {
424+ hash:: StorageHasher ,
425+ storage:: { generator:: StorageDoubleMap , IterableStorageDoubleMap , unhashed} ,
426+ } ;
454427
455428 pub trait Trait {
456429 type Origin ;
@@ -466,7 +439,7 @@ mod test_iterators {
466439
467440 crate :: decl_storage! {
468441 trait Store for Module <T : Trait > as Test {
469- DoubleMap : double_map hasher( blake2_128_concat) u16 , hasher( blake2_128_concat ) u32 => u64 ;
442+ DoubleMap : double_map hasher( blake2_128_concat) u16 , hasher( twox_64_concat ) u32 => u64 ;
470443 }
471444 }
472445
@@ -484,11 +457,6 @@ mod test_iterators {
484457 prefix
485458 }
486459
487- fn key_in_prefix ( mut prefix : Vec < u8 > ) -> Vec < u8 > {
488- prefix. push ( 0 ) ;
489- prefix
490- }
491-
492460 #[ test]
493461 fn double_map_reversible_reversible_iteration ( ) {
494462 sp_io:: TestExternalities :: default ( ) . execute_with ( || {
@@ -534,22 +502,59 @@ mod test_iterators {
534502
535503 assert_eq ! (
536504 DoubleMap :: iter_prefix( k1) . collect:: <Vec <_>>( ) ,
537- vec![ ( 0 , 0 ) , ( 2 , 2 ) , ( 1 , 1 ) , ( 3 , 3 ) ] ,
505+ vec![ ( 1 , 1 ) , ( 2 , 2 ) , ( 0 , 0 ) , ( 3 , 3 ) ] ,
538506 ) ;
539507
540508 assert_eq ! (
541509 DoubleMap :: iter_prefix_values( k1) . collect:: <Vec <_>>( ) ,
542- vec![ 0 , 2 , 1 , 3 ] ,
510+ vec![ 1 , 2 , 0 , 3 ] ,
543511 ) ;
544512
545513 assert_eq ! (
546514 DoubleMap :: drain_prefix( k1) . collect:: <Vec <_>>( ) ,
547- vec![ ( 0 , 0 ) , ( 2 , 2 ) , ( 1 , 1 ) , ( 3 , 3 ) ] ,
515+ vec![ ( 1 , 1 ) , ( 2 , 2 ) , ( 0 , 0 ) , ( 3 , 3 ) ] ,
548516 ) ;
549517
550518 assert_eq ! ( DoubleMap :: iter_prefix( k1) . collect:: <Vec <_>>( ) , vec![ ] ) ;
551519 assert_eq ! ( unhashed:: get( & key_before_prefix( prefix. clone( ) ) ) , Some ( 1u64 ) ) ;
552520 assert_eq ! ( unhashed:: get( & key_after_prefix( prefix. clone( ) ) ) , Some ( 1u64 ) ) ;
521+
522+ // Translate
523+ let prefix = DoubleMap :: prefix_hash ( ) ;
524+
525+ unhashed:: put ( & key_before_prefix ( prefix. clone ( ) ) , & 1u64 ) ;
526+ unhashed:: put ( & key_after_prefix ( prefix. clone ( ) ) , & 1u64 ) ;
527+ for i in 0 ..4 {
528+ DoubleMap :: insert ( i as u16 , i as u32 , i as u64 ) ;
529+ }
530+
531+ // Wrong key1
532+ unhashed:: put (
533+ & [ prefix. clone ( ) , vec ! [ 1 , 2 , 3 ] ] . concat ( ) ,
534+ & 3u64 . encode ( )
535+ ) ;
536+
537+ // Wrong key2
538+ unhashed:: put (
539+ & [ prefix. clone ( ) , crate :: Blake2_128Concat :: hash ( & 1u16 . encode ( ) ) ] . concat ( ) ,
540+ & 3u64 . encode ( )
541+ ) ;
542+
543+ // Wrong value
544+ unhashed:: put (
545+ & [
546+ prefix. clone ( ) ,
547+ crate :: Blake2_128Concat :: hash ( & 1u16 . encode ( ) ) ,
548+ crate :: Twox64Concat :: hash ( & 2u32 . encode ( ) ) ,
549+ ] . concat ( ) ,
550+ & vec ! [ 1 ] ,
551+ ) ;
552+
553+ DoubleMap :: translate ( |_k1, _k2, v : u64 | Some ( v* 2 ) ) ;
554+ assert_eq ! (
555+ DoubleMap :: iter( ) . collect:: <Vec <_>>( ) ,
556+ vec![ ( 3 , 3 , 6 ) , ( 0 , 0 , 0 ) , ( 2 , 2 , 4 ) , ( 1 , 1 , 2 ) ] ,
557+ ) ;
553558 } )
554559 }
555560}
0 commit comments