diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index b70436785af12..333f4382557b1 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -27,7 +27,7 @@ use crate::{ use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode}; use sp_core::storage::ChildInfo; use sp_runtime::generic::{Digest, DigestItem}; -use sp_std::{marker::PhantomData, prelude::*}; +use sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*}; pub use self::{ transactional::{ @@ -1303,6 +1303,7 @@ mod private { impl Sealed for WeakBoundedVec {} impl Sealed for bounded_btree_map::BoundedBTreeMap {} impl Sealed for bounded_btree_set::BoundedBTreeSet {} + impl Sealed for BTreeSet {} macro_rules! impl_sealed_for_tuple { ($($elem:ident),+) => { @@ -1335,6 +1336,9 @@ mod private { impl StorageAppend for Vec {} impl StorageDecodeLength for Vec {} +impl StorageAppend for BTreeSet {} +impl StorageDecodeLength for BTreeSet {} + /// We abuse the fact that SCALE does not put any marker into the encoding, i.e. we only encode the /// internal vec and we can append to this vec. We have a test that ensures that if the `Digest` /// format ever changes, we need to remove this here. @@ -1832,4 +1836,22 @@ mod test { ); }); } + + #[crate::storage_alias] + type FooSet = StorageValue>; + + #[test] + fn btree_set_append_and_decode_len_works() { + TestExternalities::default().execute_with(|| { + let btree = BTreeSet::from([1, 2, 3]); + FooSet::put(btree); + + FooSet::append(4); + FooSet::append(5); + FooSet::append(6); + FooSet::append(7); + + assert_eq!(FooSet::decode_len().unwrap(), 7); + }); + } }