1use crate::hash::{ReversibleStorageHasher, StorageHasher};
21use alloc::{boxed::Box, vec::Vec};
22use codec::{Encode, EncodeLike, FullCodec, MaxEncodedLen};
23use paste::paste;
24use scale_info::StaticTypeInfo;
25
26pub struct Key<Hasher, KeyType>(core::marker::PhantomData<(Hasher, KeyType)>);
36
37pub trait KeyGenerator {
39 type Key: EncodeLike<Self::Key> + StaticTypeInfo;
40 type KArg: Encode + EncodeLike<Self::KArg>;
41 type HashFn: FnOnce(&[u8]) -> Vec<u8>;
42 type HArg;
43
44 const HASHER_METADATA: &'static [sp_metadata_ir::StorageHasherIR];
45
46 fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8>;
49 fn migrate_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(
52 key: &KArg,
53 hash_fns: Self::HArg,
54 ) -> Vec<u8>;
55}
56
57pub trait KeyGeneratorMaxEncodedLen: KeyGenerator {
59 fn key_max_encoded_len() -> usize;
60}
61
62pub trait KeyGeneratorInner: KeyGenerator {
65 type Hasher: StorageHasher;
66
67 fn final_hash(encoded: &[u8]) -> Vec<u8>;
69}
70
71impl<H: StorageHasher, K: FullCodec + StaticTypeInfo> KeyGenerator for Key<H, K> {
72 type Key = K;
73 type KArg = (K,);
74 type HashFn = Box<dyn FnOnce(&[u8]) -> Vec<u8>>;
75 type HArg = (Self::HashFn,);
76
77 const HASHER_METADATA: &'static [sp_metadata_ir::StorageHasherIR] = &[H::METADATA];
78
79 fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8> {
80 H::hash(&key.to_encoded_iter().next().expect("should have at least one element!"))
81 .as_ref()
82 .to_vec()
83 }
84
85 fn migrate_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(
86 key: &KArg,
87 hash_fns: Self::HArg,
88 ) -> Vec<u8> {
89 (hash_fns.0)(&key.to_encoded_iter().next().expect("should have at least one element!"))
90 }
91}
92
93impl<H: StorageHasher, K: FullCodec + MaxEncodedLen + StaticTypeInfo> KeyGeneratorMaxEncodedLen
94 for Key<H, K>
95{
96 fn key_max_encoded_len() -> usize {
97 H::max_len::<K>()
98 }
99}
100
101impl<H: StorageHasher, K: FullCodec + StaticTypeInfo> KeyGeneratorInner for Key<H, K> {
102 type Hasher = H;
103
104 fn final_hash(encoded: &[u8]) -> Vec<u8> {
105 H::hash(encoded).as_ref().to_vec()
106 }
107}
108
109#[impl_trait_for_tuples::impl_for_tuples(1, 18)]
110#[tuple_types_custom_trait_bound(KeyGeneratorInner)]
111impl KeyGenerator for Tuple {
112 for_tuples!( type Key = ( #(Tuple::Key),* ); );
113 for_tuples!( type KArg = ( #(Tuple::Key),* ); );
114 for_tuples!( type HArg = ( #(Tuple::HashFn),* ); );
115 type HashFn = Box<dyn FnOnce(&[u8]) -> Vec<u8>>;
116
117 const HASHER_METADATA: &'static [sp_metadata_ir::StorageHasherIR] =
118 &[for_tuples!( #(Tuple::Hasher::METADATA),* )];
119
120 fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8> {
121 let mut final_key = Vec::new();
122 let mut iter = key.to_encoded_iter();
123 for_tuples!(
124 #(
125 let next_encoded = iter.next().expect("KArg number should be equal to Key number");
126 final_key.extend_from_slice(&Tuple::final_hash(&next_encoded));
127 )*
128 );
129 final_key
130 }
131
132 fn migrate_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(
133 key: &KArg,
134 hash_fns: Self::HArg,
135 ) -> Vec<u8> {
136 let mut migrated_key = Vec::new();
137 let mut iter = key.to_encoded_iter();
138 for_tuples!(
139 #(
140 let next_encoded = iter.next().expect("KArg number should be equal to Key number");
141 migrated_key.extend_from_slice(&(hash_fns.Tuple)(&next_encoded));
142 )*
143 );
144 migrated_key
145 }
146}
147
148#[impl_trait_for_tuples::impl_for_tuples(1, 18)]
149#[tuple_types_custom_trait_bound(KeyGeneratorInner + KeyGeneratorMaxEncodedLen)]
150impl KeyGeneratorMaxEncodedLen for Tuple {
151 fn key_max_encoded_len() -> usize {
152 let mut len = 0usize;
153 for_tuples!(
154 #(
155 len = len.saturating_add(Tuple::key_max_encoded_len());
156 )*
157 );
158 len
159 }
160}
161
162pub trait EncodeLikeTuple<T>: crate::storage::private::Sealed {}
167
168macro_rules! impl_encode_like_tuples {
169 ($($elem:ident),+) => {
170 paste! {
171 impl<$($elem: Encode,)+ $([<$elem $elem>]: Encode + EncodeLike<$elem>,)+>
172 EncodeLikeTuple<($($elem,)+)> for
173 ($([<$elem $elem>],)+) {}
174 impl<$($elem: Encode,)+ $([<$elem $elem>]: Encode + EncodeLike<$elem>,)+>
175 EncodeLikeTuple<($($elem,)+)> for
176 &($([<$elem $elem>],)+) {}
177 }
178 };
179}
180
181impl_encode_like_tuples!(A);
182impl_encode_like_tuples!(A, B);
183impl_encode_like_tuples!(A, B, C);
184impl_encode_like_tuples!(A, B, C, D);
185impl_encode_like_tuples!(A, B, C, D, E);
186impl_encode_like_tuples!(A, B, C, D, E, F);
187impl_encode_like_tuples!(A, B, C, D, E, F, G);
188impl_encode_like_tuples!(A, B, C, D, E, F, G, H);
189impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I);
190impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J);
191impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K);
192impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
193impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M);
194impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O);
195impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P);
196impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q);
197impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q, R);
198
199impl<'a, T: EncodeLike<U> + EncodeLikeTuple<U>, U: Encode> EncodeLikeTuple<U>
200 for codec::Ref<'a, T, U>
201{
202}
203
204pub trait TupleToEncodedIter {
206 fn to_encoded_iter(&self) -> alloc::vec::IntoIter<Vec<u8>>;
207}
208
209#[impl_trait_for_tuples::impl_for_tuples(1, 18)]
210#[tuple_types_custom_trait_bound(Encode)]
211impl TupleToEncodedIter for Tuple {
212 fn to_encoded_iter(&self) -> alloc::vec::IntoIter<Vec<u8>> {
213 [for_tuples!( #(self.Tuple.encode()),* )].to_vec().into_iter()
214 }
215}
216
217impl<T: TupleToEncodedIter> TupleToEncodedIter for &T {
218 fn to_encoded_iter(&self) -> alloc::vec::IntoIter<Vec<u8>> {
219 (*self).to_encoded_iter()
220 }
221}
222
223impl<'a, T: EncodeLike<U> + TupleToEncodedIter, U: Encode> TupleToEncodedIter
224 for codec::Ref<'a, T, U>
225{
226 fn to_encoded_iter(&self) -> alloc::vec::IntoIter<Vec<u8>> {
227 use core::ops::Deref as _;
228 self.deref().to_encoded_iter()
229 }
230}
231
232pub trait ReversibleKeyGenerator: KeyGenerator {
234 type ReversibleHasher;
235 fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error>;
236}
237
238impl<H: ReversibleStorageHasher, K: FullCodec + StaticTypeInfo> ReversibleKeyGenerator
239 for Key<H, K>
240{
241 type ReversibleHasher = H;
242
243 fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error> {
244 let mut current_key_material = Self::ReversibleHasher::reverse(key_material);
245 let key = K::decode(&mut current_key_material)?;
246 Ok((key, current_key_material))
247 }
248}
249
250#[impl_trait_for_tuples::impl_for_tuples(2, 18)]
251#[tuple_types_custom_trait_bound(ReversibleKeyGenerator + KeyGeneratorInner)]
252impl ReversibleKeyGenerator for Tuple {
253 for_tuples!( type ReversibleHasher = ( #(Tuple::ReversibleHasher),* ); );
254
255 fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error> {
256 let mut current_key_material = key_material;
257 Ok((
258 (for_tuples! {
259 #({
260 let (key, material) = Tuple::decode_final_key(current_key_material)?;
261 current_key_material = material;
262 key
263 }),*
264 }),
265 current_key_material,
266 ))
267 }
268}
269
270pub trait HasKeyPrefix<P>: KeyGenerator {
272 type Suffix;
273
274 fn partial_key(prefix: P) -> Vec<u8>;
275}
276
277pub trait HasReversibleKeyPrefix<P>: ReversibleKeyGenerator + HasKeyPrefix<P> {
279 fn decode_partial_key(key_material: &[u8]) -> Result<Self::Suffix, codec::Error>;
280}
281
282frame_support_procedural::impl_key_prefix_for_tuples!();