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,20 +376,41 @@ 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 ( ) ;
429382 loop {
430383 match sp_io:: storage:: next_key ( & previous_key) . filter ( |n| n. starts_with ( & prefix) ) {
431384 Some ( next) => {
432385 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) ,
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 :: Hasher1 :: 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
438408 } ,
439- None => continue ,
409+ } ;
410+
411+ match f ( key1, key2, value) {
412+ Some ( new) => unhashed:: put :: < V > ( & previous_key, & new) ,
413+ None => unhashed:: kill ( & previous_key) ,
440414 }
441415 }
442416 None => return ,
@@ -450,7 +424,10 @@ impl<
450424#[ allow( dead_code) ]
451425mod test_iterators {
452426 use codec:: { Encode , Decode } ;
453- use crate :: storage:: { generator:: StorageDoubleMap , IterableStorageDoubleMap , unhashed} ;
427+ use crate :: {
428+ hash:: StorageHasher ,
429+ storage:: { generator:: StorageDoubleMap , IterableStorageDoubleMap , unhashed} ,
430+ } ;
454431
455432 pub trait Trait {
456433 type Origin ;
@@ -484,11 +461,6 @@ mod test_iterators {
484461 prefix
485462 }
486463
487- fn key_in_prefix ( mut prefix : Vec < u8 > ) -> Vec < u8 > {
488- prefix. push ( 0 ) ;
489- prefix
490- }
491-
492464 #[ test]
493465 fn double_map_reversible_reversible_iteration ( ) {
494466 sp_io:: TestExternalities :: default ( ) . execute_with ( || {
@@ -550,6 +522,47 @@ mod test_iterators {
550522 assert_eq ! ( DoubleMap :: iter_prefix( k1) . collect:: <Vec <_>>( ) , vec![ ] ) ;
551523 assert_eq ! ( unhashed:: get( & key_before_prefix( prefix. clone( ) ) ) , Some ( 1u64 ) ) ;
552524 assert_eq ! ( unhashed:: get( & key_after_prefix( prefix. clone( ) ) ) , Some ( 1u64 ) ) ;
525+
526+ // Translate
527+ let prefix = DoubleMap :: prefix_hash ( ) ;
528+
529+ unhashed:: put ( & key_before_prefix ( prefix. clone ( ) ) , & 1u64 ) ;
530+ unhashed:: put ( & key_after_prefix ( prefix. clone ( ) ) , & 1u64 ) ;
531+ for i in 0 ..4 {
532+ DoubleMap :: insert ( i as u16 , i as u32 , i as u64 ) ;
533+ }
534+
535+ // Wrong key1
536+ unhashed:: put (
537+ & [ prefix. clone ( ) , vec ! [ 1 , 2 , 3 ] ] . concat ( ) ,
538+ & 3u64 . encode ( )
539+ ) ;
540+ // Wrong key2
541+ unhashed:: put (
542+ & [ prefix. clone ( ) , crate :: Blake2_128Concat :: hash ( & 1u16 . encode ( ) ) ] . concat ( ) ,
543+ & 3u64 . encode ( )
544+ ) ;
545+
546+ // Wrong value
547+ unhashed:: put (
548+ & [
549+ prefix. clone ( ) ,
550+ crate :: Blake2_128Concat :: hash ( & 1u16 . encode ( ) ) ,
551+ crate :: Blake2_128Concat :: hash ( & 2u32 . encode ( ) ) ,
552+ ] . concat ( ) ,
553+ & vec ! [ 1 ] ,
554+ ) ;
555+
556+ DoubleMap :: translate ( |_k1, _k2, v : u64 | Some ( v* 2 ) ) ;
557+ assert_eq ! (
558+ DoubleMap :: iter( ) . collect:: <Vec <_>>( ) ,
559+ vec![
560+ ( 3 , 3 , 6 ) ,
561+ ( 0 , 0 , 0 ) ,
562+ ( 2 , 2 , 4 ) ,
563+ ( 1 , 1 , 2 ) ,
564+ ]
565+ ) ;
553566 } )
554567 }
555568}
0 commit comments