avail_rust_core/
decoded_storage.rs

1use crate::{Error, rpc};
2use codec::{Decode, Encode};
3use primitive_types::H256;
4use std::marker::PhantomData;
5use subxt_rpcs::RpcClient;
6
7#[derive(Debug, Clone, Copy)]
8pub enum StorageHasher {
9	/// 128-bit Blake2 hash.
10	Blake2_128,
11	/// 256-bit Blake2 hash.
12	Blake2_256,
13	/// Multiple 128-bit Blake2 hashes concatenated.
14	Blake2_128Concat,
15	/// 128-bit XX hash.
16	Twox128,
17	/// 256-bit XX hash.
18	Twox256,
19	/// Multiple 64-bit XX hashes concatenated.
20	Twox64Concat,
21	/// Identity hashing (no hashing).
22	Identity,
23}
24
25impl StorageHasher {
26	pub fn hash(&self, data: &[u8]) -> Vec<u8> {
27		match self {
28			StorageHasher::Blake2_128 => sp_crypto_hashing::blake2_128(data).into(),
29			StorageHasher::Blake2_256 => sp_crypto_hashing::blake2_256(data).into(),
30			StorageHasher::Blake2_128Concat => {
31				let mut hash = sp_crypto_hashing::blake2_128(data).to_vec();
32				hash.extend_from_slice(data);
33				hash
34			},
35			StorageHasher::Twox128 => sp_crypto_hashing::twox_128(data).into(),
36			StorageHasher::Twox256 => sp_crypto_hashing::twox_256(data).into(),
37			StorageHasher::Twox64Concat => {
38				let mut hash = sp_crypto_hashing::twox_64(data).to_vec();
39				hash.extend_from_slice(data);
40				hash
41			},
42			StorageHasher::Identity => data.to_vec(),
43		}
44	}
45
46	pub fn from_hash<Key: codec::Decode>(&self, data: &mut &[u8]) -> Result<Key, codec::Error> {
47		match self {
48			StorageHasher::Blake2_128Concat => {
49				if data.len() < 17 {
50					return Err(codec::Error::from("Not enough data to compute Blake2_128Concat"));
51				}
52				Key::decode(&mut &data[16..])
53			},
54			StorageHasher::Twox64Concat => {
55				if data.len() < 9 {
56					return Err(codec::Error::from("Not enough data to compute Twox64Concat"));
57				}
58				Key::decode(&mut &data[8..])
59			},
60			StorageHasher::Identity => Key::decode(data),
61			_ => unimplemented!(),
62		}
63	}
64}
65
66pub trait StorageValue {
67	const PALLET_NAME: &str;
68	const STORAGE_NAME: &str;
69	type VALUE: codec::Decode;
70
71	fn encode_storage_key() -> [u8; 32] {
72		use sp_crypto_hashing::twox_128;
73
74		let mut encoded_storage_key = [0u8; 32];
75		encoded_storage_key[0..16].copy_from_slice(&twox_128(Self::PALLET_NAME.as_bytes()));
76		encoded_storage_key[16..].copy_from_slice(&twox_128(Self::STORAGE_NAME.as_bytes()));
77
78		encoded_storage_key
79	}
80
81	fn hex_encode_storage_key() -> String {
82		std::format!("0x{}", const_hex::encode(Self::encode_storage_key()))
83	}
84
85	/// Decodes the Hex and SCALE encoded Storage Value
86	/// This is equal to Hex::decode + Self::decode
87	///
88	/// If you need to decode bytes call `decode`
89	fn hex_decode(value: &str) -> Result<Self::VALUE, codec::Error> {
90		let Ok(hex_decoded) = const_hex::decode(value.trim_start_matches("0x")) else {
91			return Err("Failed to hex decode storage".into());
92		};
93		Self::decode(&mut hex_decoded.as_slice())
94	}
95
96	/// Decodes the SCALE encoded Storage Value
97	///
98	/// If you need to decode Hex string call `hex_decode`
99	fn decode(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
100		Self::VALUE::decode(value)
101	}
102
103	/// Fetches and decodes a Storage Value
104	///
105	/// Returns None if no Storage Value is present
106	fn fetch(
107		client: &RpcClient,
108		at: Option<H256>,
109	) -> impl std::future::Future<Output = Result<Option<Self::VALUE>, Error>> {
110		async move {
111			let storage_key = const_hex::encode(Self::encode_storage_key());
112
113			let storage_value = rpc::state::get_storage(client, &storage_key, at).await?;
114			let Some(storage_value) = storage_value else {
115				return Ok(None);
116			};
117
118			let storage_value = Self::decode(&mut storage_value.as_slice())?;
119			Ok(Some(storage_value))
120		}
121	}
122}
123
124pub trait StorageMap {
125	const PALLET_NAME: &str;
126	const STORAGE_NAME: &str;
127	const KEY_HASHER: StorageHasher;
128	type KEY: codec::Decode + codec::Encode;
129	type VALUE: codec::Decode;
130
131	fn encode_partial_key() -> [u8; 32] {
132		use sp_crypto_hashing::twox_128;
133
134		let mut encoded_storage_key = [0u8; 32];
135		encoded_storage_key[0..16].copy_from_slice(&twox_128(Self::PALLET_NAME.as_bytes()));
136		encoded_storage_key[16..].copy_from_slice(&twox_128(Self::STORAGE_NAME.as_bytes()));
137
138		encoded_storage_key
139	}
140
141	fn hex_encode_partial_key() -> String {
142		std::format!("0x{}", const_hex::encode(Self::encode_partial_key()))
143	}
144
145	fn encode_storage_key(key: &Self::KEY) -> Vec<u8> {
146		let mut storage_key: Vec<u8> = Vec::new();
147		storage_key.extend_from_slice(&Self::encode_partial_key());
148
149		let encoded_key = key.encode();
150		storage_key.extend_from_slice(&Self::KEY_HASHER.hash(&encoded_key));
151
152		storage_key
153	}
154
155	fn hex_encode_storage_key(key: &Self::KEY) -> String {
156		std::format!("0x{}", const_hex::encode(Self::encode_storage_key(key)))
157	}
158
159	/// Decodes the Hex and SCALE encoded Storage Key
160	/// This is equal to Hex::decode + Self::decode_storage_key
161	///
162	/// If you need to decode bytes call `decode_storage_key`
163	#[inline(always)]
164	fn decode_hex_storage_key(value: &str) -> Result<Self::KEY, codec::Error> {
165		let Ok(hex_decoded) = const_hex::decode(value.trim_start_matches("0x")) else {
166			return Err("Failed to hex decode storage key".into());
167		};
168		Self::decode_storage_key(&mut hex_decoded.as_slice())
169	}
170
171	/// Decodes the SCALE encoded Storage Key
172	///
173	/// If you need to decode Hex string call `decode_hex_storage_key`
174	fn decode_storage_key(value: &mut &[u8]) -> Result<Self::KEY, codec::Error> {
175		if value.len() < 32 {
176			return Err("Storage Key is malformed. Has less than 32 bytes".into());
177		}
178
179		// Skip pallet/variant
180		*value = &value[32..];
181
182		Self::KEY_HASHER.from_hash::<Self::KEY>(value)
183	}
184
185	/// Decodes the Hex and SCALE encoded Storage Value
186	/// This is equal to Hex::decode + Self::decode_storage_value
187	///
188	/// If you need to decode bytes call `decode_storage_value`
189	#[inline(always)]
190	fn decode_hex_storage_value(value: &str) -> Result<Self::VALUE, codec::Error> {
191		let Ok(hex_decoded) = const_hex::decode(value.trim_start_matches("0x")) else {
192			return Err("Failed to hex decode storage value".into());
193		};
194		Self::decode_storage_value(&mut hex_decoded.as_slice())
195	}
196
197	/// Decodes the SCALE encoded Storage Value
198	///
199	/// If you need to decode Hex string call `decode_hex_storage_value`
200	fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
201		Self::VALUE::decode(value)
202	}
203
204	/// Fetches and decodes a Storage Value
205	///
206	/// Returns None if no Storage Value is present
207	fn fetch(
208		client: &RpcClient,
209		key: &Self::KEY,
210		at: Option<H256>,
211	) -> impl std::future::Future<Output = Result<Option<Self::VALUE>, Error>> {
212		async move {
213			let storage_key = const_hex::encode(Self::encode_storage_key(key));
214			let storage_value = rpc::state::get_storage(client, &storage_key, at).await?;
215			let Some(storage_value) = storage_value else {
216				return Ok(None);
217			};
218
219			let storage_value = Self::decode_storage_value(&mut storage_value.as_slice())?;
220			Ok(Some(storage_value))
221		}
222	}
223
224	fn iter(client: RpcClient, block_hash: H256) -> StorageMapIterator<Self>
225	where
226		Self: Sized,
227	{
228		StorageMapIterator::new(client, block_hash)
229	}
230}
231
232pub trait StorageDoubleMap {
233	const PALLET_NAME: &str;
234	const STORAGE_NAME: &str;
235	const KEY1_HASHER: StorageHasher;
236	const KEY2_HASHER: StorageHasher;
237	type KEY1: codec::Decode + codec::Encode;
238	type KEY2: codec::Decode + codec::Encode;
239	type VALUE: codec::Decode;
240
241	fn encode_partial_key(key1: &Self::KEY1) -> Vec<u8> {
242		use sp_crypto_hashing::twox_128;
243
244		let mut encoded_storage_key = Vec::new();
245		encoded_storage_key.extend_from_slice(&twox_128(Self::PALLET_NAME.as_bytes()));
246		encoded_storage_key.extend_from_slice(&twox_128(Self::STORAGE_NAME.as_bytes()));
247		encoded_storage_key.extend_from_slice(&Self::KEY1_HASHER.hash(&key1.encode()));
248
249		encoded_storage_key
250	}
251
252	fn hex_encode_partial_key(key1: &Self::KEY1) -> String {
253		std::format!("0x{}", const_hex::encode(Self::encode_partial_key(key1)))
254	}
255
256	fn encode_storage_key(key1: &Self::KEY1, key2: &Self::KEY2) -> Vec<u8> {
257		let mut storage_key: Vec<u8> = Vec::new();
258		storage_key.extend_from_slice(&Self::encode_partial_key(key1));
259		storage_key.extend_from_slice(&Self::KEY2_HASHER.hash(&key2.encode()));
260
261		storage_key
262	}
263
264	fn hex_encode_storage_key(key1: &Self::KEY1, key2: &Self::KEY2) -> String {
265		std::format!("0x{}", const_hex::encode(Self::encode_storage_key(key1, key2)))
266	}
267
268	fn decode_partial_key(value: &mut &[u8]) -> Result<Self::KEY1, codec::Error> {
269		if value.len() < 32 {
270			return Err("Storage Key is malformed. Has less than 32 bytes".into());
271		}
272
273		// Skip pallet/variant
274		*value = &value[32..];
275
276		Self::KEY1_HASHER.from_hash::<Self::KEY1>(value)
277	}
278
279	/// Decodes the Hex and SCALE encoded Storage Key
280	/// This is equal to Hex::decode + Self::decode_storage_key
281	///
282	/// If you need to decode bytes call `decode_storage_key`
283	fn decode_hex_storage_key(value: &str) -> Result<(Self::KEY1, Self::KEY2), codec::Error> {
284		let Ok(hex_decoded) = const_hex::decode(value.trim_start_matches("0x")) else {
285			return Err("Failed to hex decode storage key".into());
286		};
287		Self::decode_storage_key(&mut hex_decoded.as_slice())
288	}
289
290	/// Decodes the SCALE encoded Storage Key
291	///
292	/// If you need to decode Hex string call `decode_hex_storage_key`
293	fn decode_storage_key(value: &mut &[u8]) -> Result<(Self::KEY1, Self::KEY2), codec::Error> {
294		if value.len() < 32 {
295			return Err("Storage Key is malformed. Has less than 32 bytes".into());
296		}
297
298		// Skip pallet/variant
299		*value = &value[32..];
300
301		let key1 = Self::KEY1_HASHER.from_hash::<Self::KEY1>(value)?;
302		let key2 = Self::KEY2_HASHER.from_hash::<Self::KEY2>(value)?;
303		Ok((key1, key2))
304	}
305
306	/// Decodes the Hex and SCALE encoded Storage Value
307	/// This is equal to Hex::decode + Self::decode_storage_value
308	///
309	/// If you need to decode bytes call `decode_storage_value`
310	fn decode_hex_storage_value(value: &str) -> Result<Self::VALUE, codec::Error> {
311		let Ok(hex_decoded) = const_hex::decode(value.trim_start_matches("0x")) else {
312			return Err("Failed to hex decode storage value".into());
313		};
314		Self::decode_storage_value(&mut hex_decoded.as_slice())
315	}
316
317	/// Decodes the SCALE encoded Storage Value
318	///
319	/// If you need to decode Hex string call `decode_hex_storage_value`
320	fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
321		Self::VALUE::decode(value)
322	}
323
324	/// Fetches and decodes a Storage Value
325	///
326	/// Returns None if no Storage Value is present
327	fn fetch(
328		client: &RpcClient,
329		key_1: &Self::KEY1,
330		key_2: &Self::KEY2,
331		at: Option<H256>,
332	) -> impl std::future::Future<Output = Result<Option<Self::VALUE>, Error>> {
333		async move {
334			let storage_key = const_hex::encode(Self::encode_storage_key(key_1, key_2));
335			let storage_value = rpc::state::get_storage(client, &storage_key, at).await?;
336			let Some(storage_value) = storage_value else {
337				return Ok(None);
338			};
339
340			let storage_value = Self::decode_storage_value(&mut storage_value.as_slice())?;
341			Ok(Some(storage_value))
342		}
343	}
344
345	fn iter(client: RpcClient, key_1: &Self::KEY1, block_hash: H256) -> StorageDoubleMapIterator<Self>
346	where
347		Self: Sized,
348	{
349		StorageDoubleMapIterator::new(client, key_1, block_hash)
350	}
351}
352
353#[derive(Clone)]
354pub struct StorageMapIterator<T: StorageMap> {
355	client: RpcClient,
356	phantom: PhantomData<T>,
357	block_hash: H256,
358	fetched_keys: Vec<String>,
359	last_key: Option<String>,
360	is_done: bool,
361	prefix: String,
362}
363
364impl<T: StorageMap> StorageMapIterator<T> {
365	pub fn new(client: RpcClient, block_hash: H256) -> Self {
366		Self {
367			client,
368			phantom: PhantomData::<T>,
369			block_hash,
370			fetched_keys: Vec::new(),
371			last_key: None,
372			is_done: false,
373			prefix: const_hex::encode(T::encode_partial_key()),
374		}
375	}
376
377	pub async fn next_key_value(&mut self) -> Result<Option<(T::KEY, T::VALUE)>, Error> {
378		if self.is_done {
379			return Ok(None);
380		}
381
382		// Fetch new keys
383		if self.fetched_keys.is_empty() {
384			self.fetch_new_keys().await?;
385		}
386
387		let Some(storage_key) = self.fetched_keys.last() else {
388			return Ok(None);
389		};
390
391		let Some(storage_value) = self.fetch_storage_value(storage_key).await? else {
392			return Ok(None);
393		};
394
395		let key = const_hex::decode(storage_key.trim_start_matches("0x")).map_err(|x| x.to_string())?;
396		let key = T::decode_storage_key(&mut key.as_slice())?;
397
398		self.last_key = Some(storage_key.clone());
399		self.fetched_keys.pop();
400
401		Ok(Some((key, storage_value)))
402	}
403
404	pub async fn next(&mut self) -> Result<Option<T::VALUE>, Error> {
405		if self.is_done {
406			return Ok(None);
407		}
408
409		// Fetch new keys
410		if self.fetched_keys.is_empty() {
411			self.fetch_new_keys().await?;
412		}
413
414		let Some(storage_key) = self.fetched_keys.last() else {
415			return Ok(None);
416		};
417
418		let Some(storage_value) = self.fetch_storage_value(storage_key).await? else {
419			return Ok(None);
420		};
421
422		self.last_key = Some(storage_key.clone());
423		self.fetched_keys.pop();
424
425		Ok(Some(storage_value))
426	}
427
428	async fn fetch_new_keys(&mut self) -> Result<(), Error> {
429		self.fetched_keys = rpc::state::get_keys_paged(
430			&self.client,
431			Some(self.prefix.clone()),
432			100,
433			self.last_key.clone(),
434			Some(self.block_hash),
435		)
436		.await?;
437
438		self.fetched_keys.reverse();
439		if self.fetched_keys.is_empty() {
440			self.is_done = true
441		}
442
443		Ok(())
444	}
445
446	async fn fetch_storage_value(&self, key: &str) -> Result<Option<T::VALUE>, Error> {
447		let storage_value = rpc::state::get_storage(&self.client, key, Some(self.block_hash)).await?;
448		let Some(storage_value) = storage_value else {
449			return Ok(None);
450		};
451		let storage_value = T::decode_storage_value(&mut storage_value.as_slice())?;
452
453		Ok(Some(storage_value))
454	}
455}
456
457#[derive(Clone)]
458pub struct StorageDoubleMapIterator<T: StorageDoubleMap> {
459	client: RpcClient,
460	phantom: PhantomData<T>,
461	block_hash: H256,
462	fetched_keys: Vec<String>,
463	last_key: Option<String>,
464	is_done: bool,
465	prefix: String,
466}
467
468impl<T: StorageDoubleMap> StorageDoubleMapIterator<T> {
469	pub fn new(client: RpcClient, key_1: &T::KEY1, block_hash: H256) -> Self {
470		Self {
471			client,
472			phantom: PhantomData::<T>,
473			block_hash,
474			fetched_keys: Vec::new(),
475			last_key: None,
476			is_done: false,
477
478			prefix: const_hex::encode(T::encode_partial_key(key_1)),
479		}
480	}
481
482	pub async fn next_key_value(&mut self) -> Result<Option<(T::KEY1, T::KEY2, T::VALUE)>, Error> {
483		if self.is_done {
484			return Ok(None);
485		}
486
487		// Fetch new keys
488		if self.fetched_keys.is_empty() {
489			self.fetch_new_keys().await?;
490		}
491
492		let Some(storage_key) = self.fetched_keys.last() else {
493			return Ok(None);
494		};
495
496		let Some(storage_value) = self.fetch_storage_value(storage_key).await? else {
497			return Ok(None);
498		};
499
500		let key = const_hex::decode(storage_key.trim_start_matches("0x")).map_err(|x| x.to_string())?;
501		let (key1, key2) = T::decode_storage_key(&mut key.as_slice())?;
502
503		self.last_key = Some(storage_key.clone());
504		self.fetched_keys.pop();
505
506		Ok(Some((key1, key2, storage_value)))
507	}
508
509	pub async fn next(&mut self) -> Result<Option<T::VALUE>, Error> {
510		if self.is_done {
511			return Ok(None);
512		}
513
514		// Fetch new keys
515		if self.fetched_keys.is_empty() {
516			self.fetch_new_keys().await?;
517		}
518
519		let Some(storage_key) = self.fetched_keys.last() else {
520			return Ok(None);
521		};
522
523		let Some(storage_value) = self.fetch_storage_value(storage_key).await? else {
524			return Ok(None);
525		};
526
527		self.last_key = Some(storage_key.clone());
528		self.fetched_keys.pop();
529
530		Ok(Some(storage_value))
531	}
532
533	async fn fetch_new_keys(&mut self) -> Result<(), Error> {
534		self.fetched_keys = rpc::state::get_keys_paged(
535			&self.client,
536			Some(self.prefix.clone()),
537			100,
538			self.last_key.clone(),
539			Some(self.block_hash),
540		)
541		.await?;
542
543		self.fetched_keys.reverse();
544		if self.fetched_keys.is_empty() {
545			self.is_done = true
546		}
547
548		Ok(())
549	}
550
551	async fn fetch_storage_value(&self, key: &str) -> Result<Option<T::VALUE>, Error> {
552		let storage_value = rpc::state::get_storage(&self.client, key, Some(self.block_hash)).await?;
553		let Some(storage_value) = storage_value else {
554			return Ok(None);
555		};
556		let storage_value = T::decode_storage_value(&mut storage_value.as_slice())?;
557
558		Ok(Some(storage_value))
559	}
560}