avail_rust_core/substrate/
storage.rs

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