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 Blake2_128,
11 Blake2_256,
13 Blake2_128Concat,
15 Twox128,
17 Twox256,
19 Twox64Concat,
21 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 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 fn decode(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
100 Self::VALUE::decode(value)
101 }
102
103 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 #[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 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 *value = &value[32..];
275
276 Self::KEY1_HASHER.from_hash::<Self::KEY1>(value)
277 }
278
279 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 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 *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 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 fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
321 Self::VALUE::decode(value)
322 }
323
324 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 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 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 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 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}