1use core::marker::PhantomData;
2
3use common_primitives::msa::MessageSourceId;
4use core::fmt::Debug;
5use frame_support::{
6 storage::{child, child::ChildInfo, ChildTriePrefixIterator},
7 Blake2_128, Blake2_256, Hashable, StorageHasher, Twox128, Twox256,
8};
9use parity_scale_codec::{Decode, Encode};
10use sp_core::{ConstU8, Get};
11use sp_io::hashing::twox_64;
12extern crate alloc;
13use alloc::{boxed::Box, vec::Vec};
14
15pub trait MultipartKeyStorageHasher: StorageHasher {
17 type HashSize: Get<u8>;
18 fn reverse(x: &[u8], num_key_parts: u8) -> &[u8] {
22 let hash_len: usize = (Self::HashSize::get() * num_key_parts).into();
23 if x.len() < hash_len {
24 log::error!("Invalid reverse: hash length too short");
25 return &[]
26 }
27 &x[hash_len..]
28 }
29}
30impl MultipartKeyStorageHasher for Blake2_128 {
32 type HashSize = ConstU8<16>;
33}
34impl MultipartKeyStorageHasher for Blake2_256 {
36 type HashSize = ConstU8<32>;
37}
38impl MultipartKeyStorageHasher for Twox128 {
40 type HashSize = ConstU8<16>;
41}
42impl MultipartKeyStorageHasher for Twox256 {
44 type HashSize = ConstU8<32>;
45}
46
47pub trait MultipartStorageKeyPart:
48 Clone + Debug + Default + Decode + Encode + Eq + PartialEq + Hashable
49{
50}
51impl<T> MultipartStorageKeyPart for T where
52 T: Clone + Debug + Default + Decode + Encode + Eq + PartialEq + Hashable
53{
54}
55
56pub trait MultipartKey<H: MultipartKeyStorageHasher>: MultipartStorageKeyPart {
59 type Arity: Get<u8>;
60
61 fn hash(&self) -> Vec<u8>;
62 fn hash_prefix_only(&self) -> Vec<u8>;
63
64 #[allow(dead_code)]
65 fn decode(hash: &[u8]) -> Result<Self, parity_scale_codec::Error> {
66 let mut key_material = H::reverse(hash, Self::Arity::get());
67 <Self as Decode>::decode(&mut key_material)
68 }
69
70 fn decode_without_prefix(
71 hash: &[u8],
72 prefix_len: u8,
73 ) -> Result<Self, parity_scale_codec::Error> {
74 if prefix_len > Self::Arity::get() {
75 return Err("Prefix longer than total key length".into())
76 }
77
78 let mut key_material = H::reverse(hash, Self::Arity::get() - prefix_len);
79 <Self as Decode>::decode(&mut key_material)
80 }
81}
82
83impl<H: MultipartKeyStorageHasher> MultipartKey<H> for () {
84 type Arity = ConstU8<0>;
85
86 fn hash(&self) -> Vec<u8> {
87 Vec::new()
88 }
89
90 fn hash_prefix_only(&self) -> Vec<u8> {
91 Vec::new()
92 }
93
94 fn decode(_hash: &[u8]) -> Result<Self, parity_scale_codec::Error> {
95 Ok(())
96 }
97}
98
99impl<H: MultipartKeyStorageHasher, T1: MultipartStorageKeyPart> MultipartKey<H> for (T1,) {
100 type Arity = ConstU8<1>;
101
102 fn hash(&self) -> Vec<u8> {
103 let encoded_1 = self.0.encode();
104 <H as StorageHasher>::hash(&encoded_1)
105 .as_ref()
106 .iter()
107 .chain(self.encode().iter())
108 .cloned()
109 .collect::<Vec<_>>()
110 }
111
112 fn hash_prefix_only(&self) -> Vec<u8> {
113 let encoded_1 = self.0.encode();
114 <H as StorageHasher>::hash(&encoded_1).as_ref().to_vec()
115 }
116}
117
118impl<H: MultipartKeyStorageHasher, T1: MultipartStorageKeyPart, T2: MultipartStorageKeyPart>
119 MultipartKey<H> for (T1, T2)
120{
121 type Arity = ConstU8<2>;
122
123 fn hash(&self) -> Vec<u8> {
124 let encoded_1 = self.0.encode();
125 let encoded_2 = self.1.encode();
126 H::hash(&encoded_1)
127 .as_ref()
128 .iter()
129 .chain(H::hash(&encoded_2).as_ref().iter())
130 .chain(self.encode().iter())
131 .cloned()
132 .collect::<Vec<_>>()
133 }
134
135 fn hash_prefix_only(&self) -> Vec<u8> {
136 let encoded_1 = self.0.encode();
137 let encoded_2 = self.1.encode();
138 <H as StorageHasher>::hash(&encoded_1)
139 .as_ref()
140 .iter()
141 .chain(H::hash(&encoded_2).as_ref().iter())
142 .cloned()
143 .collect::<Vec<_>>()
144 }
145}
146
147impl<
148 H: MultipartKeyStorageHasher,
149 T1: MultipartStorageKeyPart,
150 T2: MultipartStorageKeyPart,
151 T3: MultipartStorageKeyPart,
152 > MultipartKey<H> for (T1, T2, T3)
153{
154 type Arity = ConstU8<3>;
155
156 fn hash(&self) -> Vec<u8> {
157 let encoded_1 = self.0.encode();
158 let encoded_2 = self.1.encode();
159 let encoded_3 = self.2.encode();
160 H::hash(&encoded_1)
161 .as_ref()
162 .iter()
163 .chain(H::hash(&encoded_2).as_ref().iter())
164 .chain(H::hash(&encoded_3).as_ref().iter())
165 .chain(self.encode().iter())
166 .cloned()
167 .collect::<Vec<_>>()
168 }
169
170 fn hash_prefix_only(&self) -> Vec<u8> {
171 let encoded_1 = self.0.encode();
172 let encoded_2 = self.1.encode();
173 let encoded_3 = self.2.encode();
174 <H as StorageHasher>::hash(&encoded_1)
175 .as_ref()
176 .iter()
177 .chain(H::hash(&encoded_2).as_ref().iter())
178 .chain(H::hash(&encoded_3).as_ref().iter())
179 .cloned()
180 .collect::<Vec<_>>()
181 }
182}
183
184impl<
185 H: MultipartKeyStorageHasher,
186 T1: MultipartStorageKeyPart,
187 T2: MultipartStorageKeyPart,
188 T3: MultipartStorageKeyPart,
189 T4: MultipartStorageKeyPart,
190 > MultipartKey<H> for (T1, T2, T3, T4)
191{
192 type Arity = ConstU8<4>;
193
194 fn hash(&self) -> Vec<u8> {
195 let encoded_1 = self.0.encode();
196 let encoded_2 = self.1.encode();
197 let encoded_3 = self.2.encode();
198 let encoded_4 = self.3.encode();
199 H::hash(&encoded_1)
200 .as_ref()
201 .iter()
202 .chain(H::hash(&encoded_2).as_ref().iter())
203 .chain(H::hash(&encoded_3).as_ref().iter())
204 .chain(H::hash(&encoded_4).as_ref().iter())
205 .chain(self.encode().iter())
206 .cloned()
207 .collect::<Vec<_>>()
208 }
209
210 fn hash_prefix_only(&self) -> Vec<u8> {
211 let encoded_1 = self.0.encode();
212 let encoded_2 = self.1.encode();
213 let encoded_3 = self.2.encode();
214 let encoded_4 = self.3.encode();
215 <H as StorageHasher>::hash(&encoded_1)
216 .as_ref()
217 .iter()
218 .chain(H::hash(&encoded_2).as_ref().iter())
219 .chain(H::hash(&encoded_3).as_ref().iter())
220 .chain(H::hash(&encoded_4).as_ref().iter())
221 .cloned()
222 .collect::<Vec<_>>()
223 }
224}
225
226pub trait IsTuplePrefix<H: MultipartKeyStorageHasher, T: MultipartStorageKeyPart>:
228 MultipartKey<H>
229{
230}
231impl<H: MultipartKeyStorageHasher, T1: MultipartStorageKeyPart> IsTuplePrefix<H, (T1,)> for () {}
232impl<H: MultipartKeyStorageHasher, T1: MultipartStorageKeyPart, T2: MultipartStorageKeyPart>
233 IsTuplePrefix<H, (T1, T2)> for ()
234{
235}
236impl<H: MultipartKeyStorageHasher, T1: MultipartStorageKeyPart, T2: MultipartStorageKeyPart>
237 IsTuplePrefix<H, (T1, T2)> for (T1,)
238{
239}
240impl<
241 H: MultipartKeyStorageHasher,
242 T1: MultipartStorageKeyPart,
243 T2: MultipartStorageKeyPart,
244 T3: MultipartStorageKeyPart,
245 > IsTuplePrefix<H, (T1, T2, T3)> for ()
246{
247}
248impl<
249 H: MultipartKeyStorageHasher,
250 T1: MultipartStorageKeyPart,
251 T2: MultipartStorageKeyPart,
252 T3: MultipartStorageKeyPart,
253 > IsTuplePrefix<H, (T1, T2, T3)> for (T1,)
254{
255}
256impl<
257 H: MultipartKeyStorageHasher,
258 T1: MultipartStorageKeyPart,
259 T2: MultipartStorageKeyPart,
260 T3: MultipartStorageKeyPart,
261 > IsTuplePrefix<H, (T1, T2, T3)> for (T1, T2)
262{
263}
264impl<
265 H: MultipartKeyStorageHasher,
266 T1: MultipartStorageKeyPart,
267 T2: MultipartStorageKeyPart,
268 T3: MultipartStorageKeyPart,
269 T4: MultipartStorageKeyPart,
270 > IsTuplePrefix<H, (T1, T2, T3, T4)> for ()
271{
272}
273impl<
274 H: MultipartKeyStorageHasher,
275 T1: MultipartStorageKeyPart,
276 T2: MultipartStorageKeyPart,
277 T3: MultipartStorageKeyPart,
278 T4: MultipartStorageKeyPart,
279 > IsTuplePrefix<H, (T1, T2, T3, T4)> for (T1,)
280{
281}
282impl<
283 H: MultipartKeyStorageHasher,
284 T1: MultipartStorageKeyPart,
285 T2: MultipartStorageKeyPart,
286 T3: MultipartStorageKeyPart,
287 T4: MultipartStorageKeyPart,
288 > IsTuplePrefix<H, (T1, T2, T3, T4)> for (T1, T2)
289{
290}
291impl<
292 H: MultipartKeyStorageHasher,
293 T1: MultipartStorageKeyPart,
294 T2: MultipartStorageKeyPart,
295 T3: MultipartStorageKeyPart,
296 T4: MultipartStorageKeyPart,
297 > IsTuplePrefix<H, (T1, T2, T3, T4)> for (T1, T2, T3)
298{
299}
300
301pub struct StatefulChildTree<H: MultipartKeyStorageHasher = Twox128> {
303 hasher: PhantomData<H>,
304}
305impl<H: MultipartKeyStorageHasher> StatefulChildTree<H> {
306 pub fn try_read<K: MultipartKey<H>, V: Decode + Sized>(
311 msa_id: &MessageSourceId,
312 pallet_name: &[u8],
313 storage_name: &[u8],
314 keys: &K,
315 ) -> Result<Option<V>, ()> {
316 let child = Self::get_child_tree_for_storage(*msa_id, pallet_name, storage_name);
317 let value = child::get_raw(&child, &keys.hash());
318 match value {
319 None => Ok(None),
320 Some(v) => Ok(Decode::decode(&mut &v[..]).map(Some).map_err(|_| ())?),
321 }
322 }
323
324 pub fn prefix_iterator<
329 V: Decode + Sized,
330 K: MultipartKey<H> + Sized,
331 PrefixKey: IsTuplePrefix<H, K>,
332 >(
333 msa_id: &MessageSourceId,
334 pallet_name: &[u8],
335 storage_name: &[u8],
336 prefix_keys: &PrefixKey,
337 ) -> Box<impl Iterator<Item = (K, V)>> {
338 let child = Self::get_child_tree_for_storage(*msa_id, pallet_name, storage_name);
339 let result = ChildTriePrefixIterator::<(Vec<u8>, V)>::with_prefix(
340 &child,
341 &prefix_keys.hash_prefix_only(),
342 )
343 .filter_map(|(k, v)| {
344 if let Ok(key) =
345 <K as MultipartKey<H>>::decode_without_prefix(&k, PrefixKey::Arity::get())
346 {
347 Some((key, v))
348 } else {
349 None
350 }
351 });
352 Box::new(result)
353 }
354
355 pub fn write<K: MultipartKey<H>, V: Encode + Sized>(
357 msa_id: &MessageSourceId,
358 pallet_name: &[u8],
359 storage_name: &[u8],
360 keys: &K,
361 new_value: V,
362 ) {
363 let child_trie_info = &Self::get_child_tree_for_storage(*msa_id, pallet_name, storage_name);
364 child::put_raw(child_trie_info, &keys.hash(), new_value.encode().as_ref());
365 }
366
367 pub fn kill<K: MultipartKey<H>>(
369 msa_id: &MessageSourceId,
370 pallet_name: &[u8],
371 storage_name: &[u8],
372 keys: &K,
373 ) {
374 let child_trie_info = &Self::get_child_tree_for_storage(*msa_id, pallet_name, storage_name);
375 child::kill(child_trie_info, &keys.hash());
376 }
377
378 fn get_child_tree_for_storage(
380 msa_id: MessageSourceId,
381 pallet_name: &[u8],
382 storage_name: &[u8],
383 ) -> ChildInfo {
384 let trie_root = Self::get_tree_prefix(msa_id);
385 let hashed_keys: Vec<u8> = [
387 Blake2_128::hash(&trie_root[..]).as_ref(),
388 twox_64(pallet_name).as_ref(),
389 twox_64(storage_name).as_ref(),
390 ]
391 .concat();
392 child::ChildInfo::new_default(&hashed_keys)
393 }
394
395 fn get_tree_prefix(msa_id: MessageSourceId) -> Vec<u8> {
397 let arr = [&msa_id.encode()[..], b"::"].concat();
398 arr.to_vec()
399 }
400}