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}