@@ -32,7 +32,7 @@ use sp_externalities::{
32
32
} ;
33
33
use codec:: { Decode , Encode , EncodeAppend } ;
34
34
35
- use sp_std:: { fmt, any:: { Any , TypeId } , vec:: Vec , vec, boxed:: Box } ;
35
+ use sp_std:: { fmt, any:: { Any , TypeId } , vec:: Vec , vec, boxed:: Box , cmp :: Ordering } ;
36
36
use crate :: { warn, trace, log_error} ;
37
37
#[ cfg( feature = "std" ) ]
38
38
use crate :: changes_trie:: State as ChangesTrieState ;
@@ -323,16 +323,37 @@ where
323
323
}
324
324
325
325
fn next_storage_key ( & self , key : & [ u8 ] ) -> Option < StorageKey > {
326
- let next_backend_key = self . backend . next_storage_key ( key) . expect ( EXT_NOT_ALLOWED_TO_FAIL ) ;
327
- let next_overlay_key_change = self . overlay . next_storage_key_change ( key) ;
328
-
329
- match ( next_backend_key, next_overlay_key_change) {
330
- ( Some ( backend_key) , Some ( overlay_key) ) if & backend_key[ ..] < overlay_key. 0 => Some ( backend_key) ,
331
- ( backend_key, None ) => backend_key,
332
- ( _, Some ( overlay_key) ) => if overlay_key. 1 . value ( ) . is_some ( ) {
333
- Some ( overlay_key. 0 . to_vec ( ) )
334
- } else {
335
- self . next_storage_key ( & overlay_key. 0 [ ..] )
326
+ let mut next_backend_key = self . backend . next_storage_key ( key) . expect ( EXT_NOT_ALLOWED_TO_FAIL ) ;
327
+ let mut overlay_changes = self . overlay . iter_after ( key) . peekable ( ) ;
328
+
329
+ match ( & next_backend_key, overlay_changes. peek ( ) ) {
330
+ ( _, None ) => next_backend_key,
331
+ ( Some ( _) , Some ( _) ) => {
332
+ while let Some ( overlay_key) = overlay_changes. next ( ) {
333
+ let cmp = next_backend_key. as_deref ( ) . map ( |v| v. cmp ( & overlay_key. 0 ) ) ;
334
+
335
+ // If `backend_key` is less than the `overlay_key`, we found out next key.
336
+ if cmp == Some ( Ordering :: Less ) {
337
+ return next_backend_key
338
+ } else if overlay_key. 1 . value ( ) . is_some ( ) {
339
+ // If there exists a value for the `overlay_key` in the overlay
340
+ // (aka the key is still valid), it means we have found our next key.
341
+ return Some ( overlay_key. 0 . to_vec ( ) )
342
+ } else if cmp == Some ( Ordering :: Equal ) {
343
+ // If the `backend_key` and `overlay_key` are equal, it means that we need
344
+ // to search for the next backend key, because the overlay has overwritten
345
+ // this key.
346
+ next_backend_key = self . backend . next_storage_key (
347
+ & overlay_key. 0 ,
348
+ ) . expect ( EXT_NOT_ALLOWED_TO_FAIL ) ;
349
+ }
350
+ }
351
+
352
+ next_backend_key
353
+ } ,
354
+ ( None , Some ( _) ) => {
355
+ // Find the next overlay key that has a value attached.
356
+ overlay_changes. find_map ( |k| k. 1 . value ( ) . as_ref ( ) . map ( |_| k. 0 . to_vec ( ) ) )
336
357
} ,
337
358
}
338
359
}
@@ -342,24 +363,43 @@ where
342
363
child_info : & ChildInfo ,
343
364
key : & [ u8 ] ,
344
365
) -> Option < StorageKey > {
345
- let next_backend_key = self . backend
366
+ let mut next_backend_key = self . backend
346
367
. next_child_storage_key ( child_info, key)
347
368
. expect ( EXT_NOT_ALLOWED_TO_FAIL ) ;
348
- let next_overlay_key_change = self . overlay . next_child_storage_key_change (
369
+ let mut overlay_changes = self . overlay . child_iter_after (
349
370
child_info. storage_key ( ) ,
350
371
key
351
- ) ;
372
+ ) . peekable ( ) ;
373
+
374
+ match ( & next_backend_key, overlay_changes. peek ( ) ) {
375
+ ( _, None ) => next_backend_key,
376
+ ( Some ( _) , Some ( _) ) => {
377
+ while let Some ( overlay_key) = overlay_changes. next ( ) {
378
+ let cmp = next_backend_key. as_deref ( ) . map ( |v| v. cmp ( & overlay_key. 0 ) ) ;
379
+
380
+ // If `backend_key` is less than the `overlay_key`, we found out next key.
381
+ if cmp == Some ( Ordering :: Less ) {
382
+ return next_backend_key
383
+ } else if overlay_key. 1 . value ( ) . is_some ( ) {
384
+ // If there exists a value for the `overlay_key` in the overlay
385
+ // (aka the key is still valid), it means we have found our next key.
386
+ return Some ( overlay_key. 0 . to_vec ( ) )
387
+ } else if cmp == Some ( Ordering :: Equal ) {
388
+ // If the `backend_key` and `overlay_key` are equal, it means that we need
389
+ // to search for the next backend key, because the overlay has overwritten
390
+ // this key.
391
+ next_backend_key = self . backend . next_child_storage_key (
392
+ child_info,
393
+ & overlay_key. 0 ,
394
+ ) . expect ( EXT_NOT_ALLOWED_TO_FAIL ) ;
395
+ }
396
+ }
352
397
353
- match ( next_backend_key, next_overlay_key_change) {
354
- ( Some ( backend_key) , Some ( overlay_key) ) if & backend_key[ ..] < overlay_key. 0 => Some ( backend_key) ,
355
- ( backend_key, None ) => backend_key,
356
- ( _, Some ( overlay_key) ) => if overlay_key. 1 . value ( ) . is_some ( ) {
357
- Some ( overlay_key. 0 . to_vec ( ) )
358
- } else {
359
- self . next_child_storage_key (
360
- child_info,
361
- & overlay_key. 0 [ ..] ,
362
- )
398
+ next_backend_key
399
+ } ,
400
+ ( None , Some ( _) ) => {
401
+ // Find the next overlay key that has a value attached.
402
+ overlay_changes. find_map ( |k| k. 1 . value ( ) . as_ref ( ) . map ( |_| k. 0 . to_vec ( ) ) )
363
403
} ,
364
404
}
365
405
}
@@ -971,6 +1011,34 @@ mod tests {
971
1011
assert_eq ! ( ext. next_storage_key( & [ 40 ] ) , Some ( vec![ 50 ] ) ) ;
972
1012
}
973
1013
1014
+ #[ test]
1015
+ fn next_storage_key_works_with_a_lot_empty_values_in_overlay ( ) {
1016
+ let mut cache = StorageTransactionCache :: default ( ) ;
1017
+ let mut overlay = OverlayedChanges :: default ( ) ;
1018
+ overlay. set_storage ( vec ! [ 20 ] , None ) ;
1019
+ overlay. set_storage ( vec ! [ 21 ] , None ) ;
1020
+ overlay. set_storage ( vec ! [ 22 ] , None ) ;
1021
+ overlay. set_storage ( vec ! [ 23 ] , None ) ;
1022
+ overlay. set_storage ( vec ! [ 24 ] , None ) ;
1023
+ overlay. set_storage ( vec ! [ 25 ] , None ) ;
1024
+ overlay. set_storage ( vec ! [ 26 ] , None ) ;
1025
+ overlay. set_storage ( vec ! [ 27 ] , None ) ;
1026
+ overlay. set_storage ( vec ! [ 28 ] , None ) ;
1027
+ overlay. set_storage ( vec ! [ 29 ] , None ) ;
1028
+ let backend = Storage {
1029
+ top : map ! [
1030
+ vec![ 30 ] => vec![ 30 ]
1031
+ ] ,
1032
+ children_default : map ! [ ]
1033
+ } . into ( ) ;
1034
+
1035
+ let ext = TestExt :: new ( & mut overlay, & mut cache, & backend, None , None ) ;
1036
+
1037
+ assert_eq ! ( ext. next_storage_key( & [ 5 ] ) , Some ( vec![ 30 ] ) ) ;
1038
+
1039
+ drop ( ext) ;
1040
+ }
1041
+
974
1042
#[ test]
975
1043
fn next_child_storage_key_works ( ) {
976
1044
let child_info = ChildInfo :: new_default ( b"Child1" ) ;
0 commit comments