diff --git a/substrate/frame/support/src/storage/generator/double_map.rs b/substrate/frame/support/src/storage/generator/double_map.rs index 5edd8ee90f..036b1f506e 100644 --- a/substrate/frame/support/src/storage/generator/double_map.rs +++ b/substrate/frame/support/src/storage/generator/double_map.rs @@ -181,6 +181,17 @@ where unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref()) } + fn iter_prefix(k1: KArg1) -> storage::PrefixIterator + where KArg1: ?Sized + EncodeLike + { + let prefix = Self::storage_double_map_final_key1(k1); + storage::PrefixIterator:: { + prefix: prefix.clone(), + previous_key: prefix, + phantom_data: Default::default(), + } + } + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, @@ -266,3 +277,34 @@ where } } } + +#[cfg(test)] +mod test { + use sp_io::TestExternalities; + use crate::storage::{self, StorageDoubleMap}; + use crate::hash::Twox128; + + #[test] + fn iter_prefix_works() { + TestExternalities::default().execute_with(|| { + struct MyStorage; + impl storage::generator::StorageDoubleMap for MyStorage { + type Query = Option; + fn module_prefix() -> &'static [u8] { b"MyModule" } + fn storage_prefix() -> &'static [u8] { b"MyStorage" } + type Hasher1 = Twox128; + type Hasher2 = Twox128; + fn from_optional_value_to_query(v: Option) -> Self::Query { v } + fn from_query_to_optional_value(v: Self::Query) -> Option { v } + } + + MyStorage::insert(1, 3, 7); + MyStorage::insert(1, 4, 8); + MyStorage::insert(2, 5, 9); + MyStorage::insert(2, 6, 10); + + assert_eq!(MyStorage::iter_prefix(1).collect::>(), vec![7, 8]); + assert_eq!(MyStorage::iter_prefix(2).collect::>(), vec![10, 9]); + }); + } +} diff --git a/substrate/frame/support/src/storage/mod.rs b/substrate/frame/support/src/storage/mod.rs index 7c0ee4c8e4..43be8699f4 100644 --- a/substrate/frame/support/src/storage/mod.rs +++ b/substrate/frame/support/src/storage/mod.rs @@ -305,6 +305,9 @@ pub trait StorageDoubleMap { fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; + fn iter_prefix(k1: KArg1) -> PrefixIterator + where KArg1: ?Sized + EncodeLike; + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike,