axon_tools/
types.rs

1use alloc::vec::Vec;
2
3use bytes::Bytes;
4pub use ethereum_types::{Bloom, H160, H256, H64, U256};
5#[cfg(feature = "impl-rlp")]
6use rlp::{Encodable, RlpStream};
7
8#[cfg(feature = "hex")]
9use crate::hex::{hex_decode, hex_encode};
10#[cfg(feature = "hex")]
11use crate::Error;
12
13#[cfg(feature = "hex")]
14#[cfg_attr(doc_cfg, doc(cfg(feature = "hex")))]
15#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
16pub struct Hex(String);
17
18#[cfg(feature = "hex")]
19#[cfg_attr(doc_cfg, doc(cfg(feature = "hex")))]
20impl Hex {
21    const HEX_PREFIX: &str = "0x";
22    const HEX_PREFIX_UPPER: &str = "0X";
23
24    pub fn empty() -> Self {
25        Hex(String::from(Self::HEX_PREFIX))
26    }
27
28    pub fn is_empty(&self) -> bool {
29        self.0.len() == 2
30    }
31
32    pub fn encode<T: AsRef<[u8]>>(src: T) -> Self {
33        let mut s = Self::HEX_PREFIX.to_string();
34        s.push_str(&hex_encode(src));
35        Hex(s)
36    }
37
38    pub fn decode(s: String) -> Result<Bytes, Error> {
39        let s = if Self::is_prefixed(s.as_str()) {
40            &s[2..]
41        } else {
42            s.as_str()
43        };
44
45        Ok(Bytes::from(hex_decode(s)?))
46    }
47
48    pub fn from_string(s: String) -> Result<Self, Error> {
49        let s = if Self::is_prefixed(s.as_str()) {
50            s
51        } else {
52            Self::HEX_PREFIX.to_string() + &s
53        };
54
55        let _ = hex_decode(&s[2..])?;
56        Ok(Hex(s))
57    }
58
59    pub fn as_string(&self) -> String {
60        self.0.to_owned()
61    }
62
63    pub fn as_string_trim0x(&self) -> String {
64        (self.0[2..]).to_owned()
65    }
66
67    pub fn as_bytes(&self) -> Bytes {
68        Bytes::from(hex_decode(&self.0[2..]).expect("impossible, already checked in from_string"))
69    }
70
71    fn is_prefixed(s: &str) -> bool {
72        s.starts_with(Self::HEX_PREFIX) || s.starts_with(Self::HEX_PREFIX_UPPER)
73    }
74}
75
76#[cfg(feature = "impl-serde")]
77impl serde::ser::Serialize for Hex {
78    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
79    where
80        S: serde::ser::Serializer,
81    {
82        serializer.serialize_str(&self.0)
83    }
84}
85
86#[cfg(feature = "impl-serde")]
87struct HexVisitor;
88
89#[cfg(feature = "impl-serde")]
90impl<'de> serde::de::Visitor<'de> for HexVisitor {
91    type Value = Hex;
92
93    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
94        formatter.write_str("Expect a hex string")
95    }
96
97    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
98    where
99        E: serde::de::Error,
100    {
101        Hex::from_string(v).map_err(|e| serde::de::Error::custom(e.to_string()))
102    }
103
104    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
105    where
106        E: serde::de::Error,
107    {
108        Hex::from_string(v.to_owned()).map_err(|e| serde::de::Error::custom(e.to_string()))
109    }
110}
111
112#[cfg(feature = "impl-serde")]
113impl<'de> serde::de::Deserialize<'de> for Hex {
114    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
115    where
116        D: serde::de::Deserializer<'de>,
117    {
118        deserializer.deserialize_string(HexVisitor)
119    }
120}
121
122#[derive(Clone, Debug, PartialEq, Eq)]
123#[cfg_attr(
124    feature = "impl-rlp",
125    derive(rlp_derive::RlpEncodable, rlp_derive::RlpDecodable)
126)]
127#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
128pub struct AxonHeader {
129    pub prev_hash:                H256,
130    pub proposer:                 H160,
131    pub state_root:               H256,
132    pub transactions_root:        H256,
133    pub signed_txs_hash:          H256,
134    pub receipts_root:            H256,
135    pub log_bloom:                Bloom,
136    pub difficulty:               U256,
137    #[cfg_attr(
138        feature = "impl-serde",
139        serde(deserialize_with = "decode::deserialize_u64")
140    )]
141    pub timestamp:                u64,
142    #[cfg_attr(
143        feature = "impl-serde",
144        serde(deserialize_with = "decode::deserialize_u64")
145    )]
146    pub number:                   u64,
147    pub gas_used:                 U256,
148    pub gas_limit:                U256,
149    pub extra_data:               Bytes,
150    pub mixed_hash:               Option<H256>,
151    pub nonce:                    H64,
152    pub base_fee_per_gas:         U256,
153    pub proof:                    Proof,
154    #[cfg_attr(
155        feature = "impl-serde",
156        serde(deserialize_with = "decode::deserialize_u32")
157    )]
158    pub call_system_script_count: u32,
159    #[cfg_attr(
160        feature = "impl-serde",
161        serde(deserialize_with = "decode::deserialize_u64")
162    )]
163    pub chain_id:                 u64,
164}
165
166#[derive(Clone, Debug, PartialEq, Eq)]
167#[cfg_attr(
168    feature = "impl-rlp",
169    derive(rlp_derive::RlpEncodable, rlp_derive::RlpDecodable)
170)]
171#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
172pub struct AxonBlock {
173    pub header:    AxonHeader,
174    pub tx_hashes: Vec<H256>,
175}
176
177#[cfg(feature = "proof")]
178#[derive(Clone, Debug, PartialEq, Eq)]
179#[cfg_attr(doc_cfg, doc(cfg(feature = "proof")))]
180#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
181pub struct Proposal {
182    pub prev_hash:                H256,
183    pub proposer:                 H160,
184    pub prev_state_root:          H256,
185    pub transactions_root:        H256,
186    pub signed_txs_hash:          H256,
187    pub timestamp:                u64,
188    pub number:                   u64,
189    pub gas_limit:                U256,
190    pub extra_data:               Bytes,
191    pub mixed_hash:               Option<H256>,
192    pub base_fee_per_gas:         U256,
193    pub proof:                    Proof,
194    pub chain_id:                 u64,
195    pub call_system_script_count: u32,
196    pub tx_hashes:                Vec<H256>,
197}
198
199#[cfg(feature = "impl-rlp")]
200impl Encodable for Proposal {
201    fn rlp_append(&self, s: &mut RlpStream) {
202        s.begin_list(10)
203            .append(&self.prev_hash)
204            .append(&self.proposer)
205            .append(&self.prev_state_root)
206            .append(&self.transactions_root)
207            .append(&self.signed_txs_hash)
208            .append(&self.timestamp)
209            .append(&self.number)
210            .append(&self.proof)
211            .append(&self.call_system_script_count)
212            .append_list(&self.tx_hashes);
213    }
214}
215
216#[derive(Clone, Debug, PartialEq, Eq)]
217#[cfg_attr(
218    feature = "impl-rlp",
219    derive(rlp_derive::RlpEncodable, rlp_derive::RlpDecodable)
220)]
221#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
222pub struct Proof {
223    #[cfg_attr(
224        feature = "impl-serde",
225        serde(deserialize_with = "decode::deserialize_u64")
226    )]
227    pub number:     u64,
228    #[cfg_attr(
229        feature = "impl-serde",
230        serde(deserialize_with = "decode::deserialize_u64")
231    )]
232    pub round:      u64,
233    pub block_hash: H256,
234    #[cfg_attr(
235        feature = "impl-serde",
236        serde(deserialize_with = "decode::deserialize_bytes")
237    )]
238    pub signature:  Bytes,
239    #[cfg_attr(
240        feature = "impl-serde",
241        serde(deserialize_with = "decode::deserialize_bytes")
242    )]
243    pub bitmap:     Bytes,
244}
245
246#[cfg(feature = "proof")]
247#[derive(Clone, Debug, PartialEq, Eq)]
248#[cfg_attr(doc_cfg, doc(cfg(feature = "proof")))]
249#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
250pub struct Validator {
251    pub bls_pub_key:    Bytes,
252    pub address:        H160,
253    pub propose_weight: u32,
254    pub vote_weight:    u32,
255}
256
257#[cfg(feature = "proof")]
258#[cfg_attr(doc_cfg, doc(cfg(feature = "proof")))]
259impl core::cmp::PartialOrd for Validator {
260    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
261        Some(self.cmp(other))
262    }
263}
264
265#[cfg(feature = "proof")]
266#[cfg_attr(doc_cfg, doc(cfg(feature = "proof")))]
267impl core::cmp::Ord for Validator {
268    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
269        self.address.cmp(&other.address)
270    }
271}
272
273#[cfg(feature = "proof")]
274#[derive(Clone, Debug, PartialEq, Eq)]
275#[cfg_attr(doc_cfg, doc(cfg(feature = "proof")))]
276#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
277pub struct Vote {
278    pub height:     u64,
279    pub round:      u64,
280    pub vote_type:  u8,
281    pub block_hash: Bytes,
282}
283
284#[cfg(feature = "impl-rlp")]
285impl Encodable for Vote {
286    fn rlp_append(&self, s: &mut RlpStream) {
287        let vote_type: u8 = self.vote_type.clone().into();
288        s.begin_list(4)
289            .append(&self.height)
290            .append(&self.round)
291            .append(&vote_type)
292            .append(&self.block_hash.to_vec());
293    }
294}
295
296#[cfg(test)]
297impl Vote {
298    fn random() -> Self {
299        Self {
300            height:     rand::random(),
301            round:      rand::random(),
302            vote_type:  2,
303            block_hash: tests::random_bytes(32),
304        }
305    }
306}
307
308#[derive(Clone, Debug, PartialEq, Eq)]
309#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
310pub struct Metadata {
311    pub version:         MetadataVersion,
312    #[cfg_attr(
313        feature = "impl-serde",
314        serde(deserialize_with = "decode::deserialize_u64")
315    )]
316    pub epoch:           u64,
317    #[cfg_attr(
318        feature = "impl-serde",
319        serde(deserialize_with = "decode::deserialize_u64")
320    )]
321    pub gas_limit:       u64,
322    #[cfg_attr(
323        feature = "impl-serde",
324        serde(deserialize_with = "decode::deserialize_u64")
325    )]
326    pub gas_price:       u64,
327    #[cfg_attr(
328        feature = "impl-serde",
329        serde(deserialize_with = "decode::deserialize_u64")
330    )]
331    pub interval:        u64,
332    pub verifier_list:   Vec<ValidatorExtend>,
333    #[cfg_attr(
334        feature = "impl-serde",
335        serde(deserialize_with = "decode::deserialize_u64")
336    )]
337    pub propose_ratio:   u64,
338    #[cfg_attr(
339        feature = "impl-serde",
340        serde(deserialize_with = "decode::deserialize_u64")
341    )]
342    pub prevote_ratio:   u64,
343    #[cfg_attr(
344        feature = "impl-serde",
345        serde(deserialize_with = "decode::deserialize_u64")
346    )]
347    pub precommit_ratio: u64,
348    #[cfg_attr(
349        feature = "impl-serde",
350        serde(deserialize_with = "decode::deserialize_u64")
351    )]
352    pub brake_ratio:     u64,
353    #[cfg_attr(
354        feature = "impl-serde",
355        serde(deserialize_with = "decode::deserialize_u64")
356    )]
357    pub tx_num_limit:    u64,
358    #[cfg_attr(
359        feature = "impl-serde",
360        serde(deserialize_with = "decode::deserialize_u64")
361    )]
362    pub max_tx_size:     u64,
363    #[cfg_attr(feature = "impl-serde", serde(skip_deserializing))]
364    pub propose_counter: Vec<ProposeCount>,
365}
366
367#[derive(Default, Clone, Debug, PartialEq, Eq)]
368#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
369pub struct MetadataVersion {
370    #[cfg_attr(
371        feature = "impl-serde",
372        serde(deserialize_with = "decode::deserialize_u64")
373    )]
374    pub start: u64,
375    #[cfg_attr(
376        feature = "impl-serde",
377        serde(deserialize_with = "decode::deserialize_u64")
378    )]
379    pub end:   u64,
380}
381
382#[derive(Clone, Debug, PartialEq, Eq)]
383#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
384pub struct ProposeCount {
385    pub address: H160,
386    #[cfg_attr(
387        feature = "impl-serde",
388        serde(deserialize_with = "decode::deserialize_u64")
389    )]
390    pub count:   u64,
391}
392
393#[derive(Clone, Debug, PartialEq, Eq)]
394#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
395pub struct ValidatorExtend {
396    #[cfg_attr(
397        feature = "impl-serde",
398        serde(deserialize_with = "decode::deserialize_bytes")
399    )]
400    pub bls_pub_key:    Bytes,
401    #[cfg_attr(
402        feature = "impl-serde",
403        serde(deserialize_with = "decode::deserialize_bytes")
404    )]
405    pub pub_key:        Bytes,
406    pub address:        H160,
407    #[cfg_attr(
408        feature = "impl-serde",
409        serde(deserialize_with = "decode::deserialize_u32")
410    )]
411    pub propose_weight: u32,
412    #[cfg_attr(
413        feature = "impl-serde",
414        serde(deserialize_with = "decode::deserialize_u32")
415    )]
416    pub vote_weight:    u32,
417}
418
419#[derive(Clone, Debug, PartialEq, Eq)]
420#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
421pub struct NodePubKey {
422    pub bls_pub_key: Bytes,
423    pub pub_key:     Bytes,
424}
425
426#[derive(Clone, Debug, PartialEq, Eq)]
427#[cfg_attr(feature = "impl-serde", derive(serde::Serialize, serde::Deserialize))]
428pub struct CkbRelatedInfo {
429    pub metadata_type_id:     H256,
430    pub checkpoint_type_id:   H256,
431    pub xudt_args:            H256,
432    pub stake_smt_type_id:    H256,
433    pub delegate_smt_type_id: H256,
434    pub reward_smt_type_id:   H256,
435}
436
437#[cfg(feature = "impl-serde")]
438mod decode {
439    use bytes::Bytes;
440    use ethereum_types::U256;
441    use serde::de::{Deserialize, Deserializer};
442
443    use crate::types::Hex;
444
445    pub fn deserialize_u64<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u64, D::Error> {
446        Ok(U256::deserialize(deserializer)?.as_u64())
447    }
448
449    pub fn deserialize_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
450        Ok(U256::deserialize(deserializer)?.as_u32())
451    }
452
453    pub fn deserialize_bytes<'de, D: Deserializer<'de>>(
454        deserializer: D,
455    ) -> Result<Bytes, D::Error> {
456        Ok(Hex::deserialize(deserializer)?.as_bytes())
457    }
458}
459
460#[cfg(test)]
461mod tests {
462    use super::*;
463
464    pub fn random_bytes(len: usize) -> Bytes {
465        (0..len).map(|_| rand::random()).collect::<Vec<u8>>().into()
466    }
467
468    #[test]
469    fn test_vote_codec() {
470        let vote = Vote::random();
471        let raw = rlp::encode(&vote);
472        let decoded: overlord::types::Vote = rlp::decode(&raw).unwrap();
473        assert_eq!(vote.height, decoded.height);
474        assert_eq!(vote.round, decoded.round);
475        assert_eq!(vote.block_hash, decoded.block_hash);
476    }
477}