avail_rust_core/substrate/
storage.rs1use 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 Blake2_128,
10 Blake2_256,
12 Blake2_128Concat,
14 Twox128,
16 Twox256,
18 Twox64Concat,
20 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 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 fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
99 Self::VALUE::decode(value)
100 }
101
102 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 #[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 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 *value = &value[32..];
181
182 Self::KEY_HASHER.from_hash::<Self::KEY>(value)
183 }
184
185 #[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 fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
201 Self::VALUE::decode(value)
202 }
203
204 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 *value = &value[32..];
276
277 Self::KEY1_HASHER.from_hash::<Self::KEY1>(value)
278 }
279
280 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 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 *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 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 fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
322 Self::VALUE::decode(value)
323 }
324
325 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 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 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 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 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}