1use super::{
8 extrinsic_params::{BaseExtrinsicParams, BaseExtrinsicParamsBuilder},
9 Config, Hasher, Header,
10};
11use codec::{Decode, Encode};
12use serde::{Deserialize, Serialize};
13
14pub use crate::utils::{AccountId32, MultiAddress, MultiSignature};
15pub use primitive_types::{H256, U256};
16
17pub enum SubstrateConfig {}
21
22impl Config for SubstrateConfig {
23 type Index = u32;
24 type Hash = H256;
25 type AccountId = AccountId32;
26 type Address = MultiAddress<Self::AccountId, u32>;
27 type Signature = MultiSignature;
28 type Hasher = BlakeTwo256;
29 type Header = SubstrateHeader<u32, BlakeTwo256>;
30 type ExtrinsicParams = SubstrateExtrinsicParams<Self>;
31}
32
33pub type SubstrateExtrinsicParams<T> = BaseExtrinsicParams<T, AssetTip>;
36
37pub type SubstrateExtrinsicParamsBuilder<T> = BaseExtrinsicParamsBuilder<T, AssetTip>;
40
41pub use super::extrinsic_params::Era;
43
44#[derive(Copy, Clone, Debug, Default, Encode)]
46pub struct AssetTip {
47 #[codec(compact)]
48 tip: u128,
49 asset: Option<u32>,
50}
51
52impl AssetTip {
53 pub fn new(amount: u128) -> Self {
55 AssetTip {
56 tip: amount,
57 asset: None,
58 }
59 }
60
61 pub fn of_asset(mut self, asset: u32) -> Self {
64 self.asset = Some(asset);
65 self
66 }
67}
68
69impl From<u128> for AssetTip {
70 fn from(n: u128) -> Self {
71 AssetTip::new(n)
72 }
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode)]
77pub struct BlakeTwo256;
78
79impl Hasher for BlakeTwo256 {
80 type Output = H256;
81 fn hash(s: &[u8]) -> Self::Output {
82 sp_core_hashing::blake2_256(s).into()
83 }
84}
85
86#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
89#[serde(rename_all = "camelCase")]
90pub struct SubstrateHeader<N: Copy + Into<U256> + TryFrom<U256>, H: Hasher> {
91 pub parent_hash: H::Output,
93 #[serde(
95 serialize_with = "serialize_number",
96 deserialize_with = "deserialize_number"
97 )]
98 #[codec(compact)]
99 pub number: N,
100 pub state_root: H::Output,
102 pub extrinsics_root: H::Output,
104 pub digest: Digest,
106}
107
108impl<N, H> Header for SubstrateHeader<N, H>
109where
110 N: Copy + Into<u64> + Into<U256> + TryFrom<U256> + Encode,
111 H: Hasher + Encode,
112 SubstrateHeader<N, H>: Encode,
113{
114 type Number = N;
115 type Hasher = H;
116 fn number(&self) -> Self::Number {
117 self.number
118 }
119}
120
121#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Default)]
123pub struct Digest {
124 pub logs: Vec<DigestItem>,
126}
127
128#[derive(Debug, PartialEq, Eq, Clone)]
131pub enum DigestItem {
132 PreRuntime(ConsensusEngineId, Vec<u8>),
145
146 Consensus(ConsensusEngineId, Vec<u8>),
150
151 Seal(ConsensusEngineId, Vec<u8>),
154
155 Other(Vec<u8>),
157
158 RuntimeEnvironmentUpdated,
165}
166
167#[repr(u32)]
169#[derive(Encode, Decode)]
170enum DigestItemType {
171 Other = 0u32,
172 Consensus = 4u32,
173 Seal = 5u32,
174 PreRuntime = 6u32,
175 RuntimeEnvironmentUpdated = 8u32,
176}
177impl Encode for DigestItem {
178 fn encode(&self) -> Vec<u8> {
179 let mut v = Vec::new();
180
181 match self {
182 Self::Consensus(val, data) => {
183 DigestItemType::Consensus.encode_to(&mut v);
184 (val, data).encode_to(&mut v);
185 }
186 Self::Seal(val, sig) => {
187 DigestItemType::Seal.encode_to(&mut v);
188 (val, sig).encode_to(&mut v);
189 }
190 Self::PreRuntime(val, data) => {
191 DigestItemType::PreRuntime.encode_to(&mut v);
192 (val, data).encode_to(&mut v);
193 }
194 Self::Other(val) => {
195 DigestItemType::Other.encode_to(&mut v);
196 val.encode_to(&mut v);
197 }
198 Self::RuntimeEnvironmentUpdated => {
199 DigestItemType::RuntimeEnvironmentUpdated.encode_to(&mut v);
200 }
201 }
202
203 v
204 }
205}
206impl Decode for DigestItem {
207 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
208 let item_type: DigestItemType = Decode::decode(input)?;
209 match item_type {
210 DigestItemType::PreRuntime => {
211 let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
212 Ok(Self::PreRuntime(vals.0, vals.1))
213 }
214 DigestItemType::Consensus => {
215 let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
216 Ok(Self::Consensus(vals.0, vals.1))
217 }
218 DigestItemType::Seal => {
219 let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
220 Ok(Self::Seal(vals.0, vals.1))
221 }
222 DigestItemType::Other => Ok(Self::Other(Decode::decode(input)?)),
223 DigestItemType::RuntimeEnvironmentUpdated => Ok(Self::RuntimeEnvironmentUpdated),
224 }
225 }
226}
227
228pub type ConsensusEngineId = [u8; 4];
230
231impl serde::Serialize for DigestItem {
232 fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
233 where
234 S: serde::Serializer,
235 {
236 self.using_encoded(|bytes| impl_serde::serialize::serialize(bytes, seq))
237 }
238}
239
240impl<'a> serde::Deserialize<'a> for DigestItem {
241 fn deserialize<D>(de: D) -> Result<Self, D::Error>
242 where
243 D: serde::Deserializer<'a>,
244 {
245 let r = impl_serde::serialize::deserialize(de)?;
246 Decode::decode(&mut &r[..])
247 .map_err(|e| serde::de::Error::custom(format!("Decode error: {e}")))
248 }
249}
250
251fn serialize_number<S, T: Copy + Into<U256>>(val: &T, s: S) -> Result<S::Ok, S::Error>
252where
253 S: serde::Serializer,
254{
255 let u256: U256 = (*val).into();
256 serde::Serialize::serialize(&u256, s)
257}
258
259fn deserialize_number<'a, D, T: TryFrom<U256>>(d: D) -> Result<T, D::Error>
260where
261 D: serde::Deserializer<'a>,
262{
263 use crate::rpc::types::NumberOrHex;
266 let number_or_hex = NumberOrHex::deserialize(d)?;
267 let u256 = number_or_hex.into_u256();
268 TryFrom::try_from(u256).map_err(|_| serde::de::Error::custom("Try from failed"))
269}
270
271#[cfg(test)]
272mod test {
273 use super::*;
274
275 #[test]
278 fn can_deserialize_numeric_block_number() {
279 let numeric_block_number_json = r#"
280 {
281 "digest": {
282 "logs": []
283 },
284 "extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
285 "number": 4,
286 "parentHash": "0xcb2690b2c85ceab55be03fc7f7f5f3857e7efeb7a020600ebd4331e10be2f7a5",
287 "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
288 }
289 "#;
290
291 let header: SubstrateHeader<u32, BlakeTwo256> =
292 serde_json::from_str(numeric_block_number_json).expect("valid block header");
293 assert_eq!(header.number(), 4);
294 }
295
296 #[test]
298 fn can_deserialize_hex_block_number() {
299 let numeric_block_number_json = r#"
300 {
301 "digest": {
302 "logs": []
303 },
304 "extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
305 "number": "0x04",
306 "parentHash": "0xcb2690b2c85ceab55be03fc7f7f5f3857e7efeb7a020600ebd4331e10be2f7a5",
307 "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
308 }
309 "#;
310
311 let header: SubstrateHeader<u32, BlakeTwo256> =
312 serde_json::from_str(numeric_block_number_json).expect("valid block header");
313 assert_eq!(header.number(), 4);
314 }
315}