heliosphere_core/
block.rs

1//! Block definitions
2use core::{fmt::Display, str::FromStr};
3
4use crate::{
5    transaction::Transaction,
6    util::{as_hex_array, as_hex_buffer},
7    Address, Error,
8};
9use alloc::{
10    string::{String, ToString},
11    vec::Vec,
12};
13use serde::{Deserialize, Serialize};
14
15/// Block ID (hash)
16#[derive(
17    Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord,
18)]
19#[repr(transparent)]
20pub struct BlockId(#[serde(with = "as_hex_array")] pub [u8; 32]);
21
22impl FromStr for BlockId {
23    type Err = Error;
24    fn from_str(s: &str) -> Result<Self, Self::Err> {
25        let mut bytes = [0x00; 32];
26        hex::decode_to_slice(s, &mut bytes).map_err(|_| Error::InvalidBlockId)?;
27        Ok(Self(bytes))
28    }
29}
30
31impl Display for BlockId {
32    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33        write!(f, "{}", hex::encode(self.0))
34    }
35}
36
37impl From<alloy_primitives::BlockHash> for BlockId {
38    fn from(value: alloy_primitives::BlockHash) -> Self {
39        Self(value.0)
40    }
41}
42
43impl From<BlockId> for alloy_primitives::BlockHash {
44    fn from(value: BlockId) -> Self {
45        Self(value.0)
46    }
47}
48
49/// Block selector
50#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
51pub enum BlockBy {
52    /// ById
53    Id(BlockId),
54    /// ByNumber
55    Number(u64),
56}
57
58impl BlockBy {
59    /// By id or number
60    pub fn id_or_num(&self) -> String {
61        match self {
62            Self::Id(id) => id.to_string(),
63            Self::Number(num) => num.to_string(),
64        }
65    }
66}
67
68/// Block raw data struct
69#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
70pub struct BlockRawData {
71    /// Block number
72    pub number: u64,
73    /// Tx trie root
74    #[serde(with = "as_hex_buffer", rename = "txTrieRoot")]
75    pub tx_trie_root: Vec<u8>,
76    /// Witness address
77    pub witness_address: Address,
78    /// Parent hash
79    #[serde(with = "as_hex_buffer", rename = "parentHash")]
80    pub parent_hash: Vec<u8>,
81    /// Version
82    pub version: u32,
83    /// Block timestamp
84    pub timestamp: u64,
85}
86
87/// Block header struct
88#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
89pub struct BlockHeader {
90    /// raw data
91    pub raw_data: BlockRawData,
92    /// witness signature
93    #[serde(with = "as_hex_buffer")]
94    pub witness_signature: Vec<u8>,
95}
96
97impl BlockHeader {
98    /// Get block number
99    pub fn block_number(&self) -> u64 {
100        self.raw_data.number
101    }
102}
103
104/// Block struct
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
106pub struct Block {
107    /// Block id
108    #[serde(rename = "blockID")]
109    pub block_id: BlockId,
110    /// Block header
111    pub block_header: BlockHeader,
112    /// Transactions
113    #[serde(default)]
114    pub transactions: Vec<Transaction>,
115}
116
117impl Block {
118    /// Get block number
119    pub fn block_number(&self) -> u64 {
120        self.block_header.block_number()
121    }
122}