avail_rust_core/
decoded_storage.rs

1use codec::{Decode, Encode};
2
3#[derive(Debug, Clone, Copy)]
4pub enum StorageHasher {
5	/// 128-bit Blake2 hash.
6	Blake2_128,
7	/// 256-bit Blake2 hash.
8	Blake2_256,
9	/// Multiple 128-bit Blake2 hashes concatenated.
10	Blake2_128Concat,
11	/// 128-bit XX hash.
12	Twox128,
13	/// 256-bit XX hash.
14	Twox256,
15	/// Multiple 64-bit XX hashes concatenated.
16	Twox64Concat,
17	/// Identity hashing (no hashing).
18	Identity,
19}
20
21impl StorageHasher {
22	pub fn hash(&self, data: &[u8]) -> Vec<u8> {
23		match self {
24			StorageHasher::Blake2_128 => sp_crypto_hashing::blake2_128(data).into(),
25			StorageHasher::Blake2_256 => sp_crypto_hashing::blake2_256(data).into(),
26			StorageHasher::Blake2_128Concat => {
27				let mut hash = sp_crypto_hashing::blake2_128(data).to_vec();
28				hash.extend_from_slice(data);
29				hash
30			},
31			StorageHasher::Twox128 => sp_crypto_hashing::twox_128(data).into(),
32			StorageHasher::Twox256 => sp_crypto_hashing::twox_256(data).into(),
33			StorageHasher::Twox64Concat => {
34				let mut hash = sp_crypto_hashing::twox_64(data).to_vec();
35				hash.extend_from_slice(data);
36				hash
37			},
38			StorageHasher::Identity => data.to_vec(),
39		}
40	}
41
42	pub fn from_hash<Key: codec::Decode>(&self, data: &mut &[u8]) -> Result<Key, codec::Error> {
43		match self {
44			StorageHasher::Blake2_128Concat => {
45				if data.len() < 17 {
46					return Err(codec::Error::from("Not enough data to compute Blake2_128Concat"));
47				}
48				Key::decode(&mut &data[16..])
49			},
50			StorageHasher::Twox64Concat => {
51				if data.len() < 9 {
52					return Err(codec::Error::from("Not enough data to compute Twox64Concat"));
53				}
54				Key::decode(&mut &data[8..])
55			},
56			StorageHasher::Identity => Key::decode(data),
57			_ => unimplemented!(),
58		}
59	}
60}
61
62pub trait StorageValue {
63	const PALLET_NAME: &str;
64	const STORAGE_NAME: &str;
65	type VALUE: codec::Decode;
66
67	fn encode_storage_key() -> [u8; 32] {
68		use sp_crypto_hashing::twox_128;
69
70		let mut encoded_storage_key = [0u8; 32];
71		encoded_storage_key[0..16].copy_from_slice(&twox_128(Self::PALLET_NAME.as_bytes()));
72		encoded_storage_key[16..].copy_from_slice(&twox_128(Self::STORAGE_NAME.as_bytes()));
73
74		encoded_storage_key
75	}
76
77	fn hex_encode_storage_key() -> String {
78		std::format!("0x{}", hex::encode(&Self::encode_storage_key()))
79	}
80
81	fn decode(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
82		Self::VALUE::decode(value)
83	}
84}
85
86pub trait StorageMap {
87	const PALLET_NAME: &str;
88	const STORAGE_NAME: &str;
89	const KEY_HASHER: StorageHasher;
90	type KEY: codec::Decode + codec::Encode;
91	type VALUE: codec::Decode;
92
93	fn encode_partial_key() -> [u8; 32] {
94		use sp_crypto_hashing::twox_128;
95
96		let mut encoded_storage_key = [0u8; 32];
97		encoded_storage_key[0..16].copy_from_slice(&twox_128(Self::PALLET_NAME.as_bytes()));
98		encoded_storage_key[16..].copy_from_slice(&twox_128(Self::STORAGE_NAME.as_bytes()));
99
100		encoded_storage_key
101	}
102
103	fn hex_encode_partial_key() -> String {
104		std::format!("0x{}", hex::encode(&Self::encode_partial_key()))
105	}
106
107	fn encode_storage_key(key: Self::KEY) -> Vec<u8> {
108		let mut storage_key: Vec<u8> = Vec::new();
109		storage_key.extend_from_slice(&Self::encode_partial_key());
110
111		let encoded_key = key.encode();
112		storage_key.extend_from_slice(&Self::KEY_HASHER.hash(&encoded_key));
113
114		storage_key
115	}
116
117	fn hex_encode_storage_key(key: Self::KEY) -> String {
118		std::format!("0x{}", hex::encode(&Self::encode_storage_key(key)))
119	}
120
121	fn decode_storage_key(value: &mut &[u8]) -> Result<Self::KEY, codec::Error> {
122		// Skip pallet/variant
123		*value = &value[32..];
124
125		Self::KEY_HASHER.from_hash::<Self::KEY>(value)
126	}
127
128	fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
129		Self::VALUE::decode(value)
130	}
131}
132
133pub trait StorageDoubleMap {
134	const PALLET_NAME: &str;
135	const STORAGE_NAME: &str;
136	const KEY1_HASHER: StorageHasher;
137	const KEY2_HASHER: StorageHasher;
138	type KEY1: codec::Decode + codec::Encode;
139	type KEY2: codec::Decode + codec::Encode;
140	type VALUE: codec::Decode;
141
142	fn encode_partial_key(key1: Self::KEY1) -> Vec<u8> {
143		use sp_crypto_hashing::twox_128;
144
145		let mut encoded_storage_key = Vec::new();
146		encoded_storage_key.extend_from_slice(&twox_128(Self::PALLET_NAME.as_bytes()));
147		encoded_storage_key.extend_from_slice(&twox_128(Self::STORAGE_NAME.as_bytes()));
148		encoded_storage_key.extend_from_slice(&Self::KEY1_HASHER.hash(&key1.encode()));
149
150		encoded_storage_key
151	}
152
153	fn hex_encode_partial_key(key1: Self::KEY1) -> String {
154		std::format!("0x{}", hex::encode(&Self::encode_partial_key(key1)))
155	}
156
157	fn encode_storage_key(key1: Self::KEY1, key2: Self::KEY2) -> Vec<u8> {
158		let mut storage_key: Vec<u8> = Vec::new();
159		storage_key.extend_from_slice(&Self::encode_partial_key(key1));
160		storage_key.extend_from_slice(&Self::KEY2_HASHER.hash(&key2.encode()));
161
162		storage_key
163	}
164
165	fn hex_encode_storage_key(key1: Self::KEY1, key2: Self::KEY2) -> String {
166		std::format!("0x{}", hex::encode(&Self::encode_storage_key(key1, key2)))
167	}
168
169	fn decode_partial_key(value: &mut &[u8]) -> Result<Self::KEY1, codec::Error> {
170		// Skip pallet/variant
171		*value = &value[32..];
172
173		Self::KEY1_HASHER.from_hash::<Self::KEY1>(value)
174	}
175
176	fn decode_storage_key(value: &mut &[u8]) -> Result<(Self::KEY1, Self::KEY2), codec::Error> {
177		// Skip pallet/variant
178		*value = &value[32..];
179
180		let key1 = Self::KEY1_HASHER.from_hash::<Self::KEY1>(value)?;
181		let key2 = Self::KEY2_HASHER.from_hash::<Self::KEY2>(value)?;
182		Ok((key1, key2))
183	}
184
185	fn decode_storage_value(value: &mut &[u8]) -> Result<Self::VALUE, codec::Error> {
186		Self::VALUE::decode(value)
187	}
188}
189
190/* pub struct DataAvailabilityAppKeys;
191
192#[derive(Debug, Clone, codec::Decode)]
193pub struct AppKey {
194	pub owner: AccountId,
195	#[codec(compact)]
196	pub id: u32,
197}
198
199impl StorageMap for DataAvailabilityAppKeys {
200	const PALLET_NAME: &str = "DataAvailability";
201	const STORAGE_NAME: &str = "AppKeys";
202	const KEY_HASHER: StorageHasher = StorageHasher::Blake2_128Concat;
203	type KEY = Vec<u8>;
204	type VALUE = AppKey;
205}
206
207pub struct TimestampNow;
208
209impl StorageValue for TimestampNow {
210	const PALLET_NAME: &str = "Timestamp";
211	const STORAGE_NAME: &str = "Now";
212	type VALUE = u64;
213}
214
215pub struct StakingErasValidatorPrefs;
216
217impl StorageDoubleMap for StakingErasValidatorPrefs {
218	const PALLET_NAME: &str = "Staking";
219	const STORAGE_NAME: &str = "ErasValidatorPrefs";
220	const KEY1_HASHER: StorageHasher = StorageHasher::Twox64Concat;
221	const KEY2_HASHER: StorageHasher = StorageHasher::Twox64Concat;
222	type KEY1 = u32;
223	type KEY2 = AccountId;
224	type VALUE = ValidatorPrefs;
225}
226
227#[derive(Debug, Clone, codec::Encode, codec::Decode)]
228pub struct ValidatorPrefs {
229	/// Reward that validator takes up-front; only the rest is split between themselves and
230	/// nominators.
231	#[codec(compact)]
232	pub commission: u32,
233	/// Whether or not this validator is accepting more nominations. If `true`, then no nominator
234	/// who is not already nominating this validator may nominate them. By default, validators
235	/// are accepting nominations.
236	pub blocked: bool,
237}
238 */