eth_rlp_verify/
block_header.rs

1use ethereum_types::H256;
2use sha3::{Digest, Keccak256};
3
4/// Represents an Ethereum block header with various properties like block hash, gas limits, and more.
5///
6/// This struct provides a way to store and manipulate data related to an Ethereum block header,
7/// including cryptographic information (like the block hash and state root), as well as metadata
8/// about the block (such as gas usage and the miner address). It supports fields with optional values,
9/// as certain block headers may lack specific information, depending on their context in the chain.
10///
11/// # Fields
12///
13/// - `block_hash`: The unique identifier for the block, as a 66-character hexadecimal string (not null).
14/// - `number`: The block number, a sequential integer starting from 0 (not null).
15/// - `gas_limit`: The maximum amount of gas that can be spent on transactions in this block (not null).
16/// - `gas_used`: The actual amount of gas used by transactions within the block (not null).
17/// - `nonce`: A 78-character string representing the proof-of-work nonce (not null).
18/// - `transaction_root`: The Merkle root of the transactions in the block, if available (optional).
19/// - `receipts_root`: The Merkle root of the transaction receipts in the block, if available (optional).
20/// - `state_root`: The root of the state trie after transactions in the block are processed (optional).
21/// - `base_fee_per_gas`: The base fee per gas for the block in the new fee market mechanism (optional).
22/// - `parent_hash`: The hash of the previous block, which this block references (optional).
23/// - `ommers_hash`: The hash of the ommers (or uncles), which are alternative blocks that could have been part of the chain (optional).
24/// - `miner`: The address of the miner that mined the block (optional).
25/// - `logs_bloom`: The bloom filter for logs included in the block, useful for filtering logs efficiently (optional).
26/// - `difficulty`: The difficulty level required to mine the block (optional).
27/// - `total_difficulty`: The total difficulty of the chain up to this block (optional).
28/// - `sha3_uncles`: The SHA3 hash of the uncles (ommers) included in the block (optional).
29/// - `timestamp`: The time at which the block was mined, as a string (optional).
30/// - `extra_data`: Extra data included in the block, up to 1024 bytes (optional).
31/// - `mix_hash`: A hash used to verify the proof of work, ensuring that the mining process was valid (optional).
32/// - `withdrawals_root`: The Merkle root of withdrawal data for withdrawals included in the block, if any (optional).
33/// - `blob_gas_used`: The amount of blob gas used, specific to blob transactions (optional).
34/// - `excess_blob_gas`: The excess blob gas present in the block (optional).
35/// - `parent_beacon_block_root`: The root of the parent beacon block, used in Ethereum's proof-of-stake chain (optional).
36#[derive(Debug)]
37pub struct BlockHeader {
38    pub block_hash: String,               // character(66) NOT NULL
39    pub number: i64,                      // bigint NOT NULL
40    pub gas_limit: i64,                   // bigint NOT NULL
41    pub gas_used: i64,                    // bigint NOT NULL
42    pub nonce: String,                    // character varying(78) NOT NULL
43    pub transaction_root: Option<String>, // character(66)
44    pub receipts_root: Option<String>,    // character(66)
45    pub state_root: Option<String>,       // character(66)
46    pub base_fee_per_gas: Option<String>, // character varying(78)
47    pub parent_hash: Option<String>,
48    pub ommers_hash: Option<String>,      // character varying(66)
49    pub miner: Option<String>,            // character varying(42)
50    pub logs_bloom: Option<String>,       // character varying(1024)
51    pub difficulty: Option<String>,       // character varying(78)
52    pub total_difficulty: Option<String>, // character varying(78)
53    pub sha3_uncles: Option<String>,      // character varying(66)
54    pub timestamp: Option<String>,        // character varying(100)
55    pub extra_data: Option<String>,       // character varying(1024)
56    pub mix_hash: Option<String>,         // character varying(66)
57    pub withdrawals_root: Option<String>, // character varying(66)
58    pub blob_gas_used: Option<String>,    // character varying(78)
59    pub excess_blob_gas: Option<String>,  // character varying(78)
60    pub parent_beacon_block_root: Option<String>, // character varying(66)
61}
62
63/// A trait that defines common behaviors for Ethereum block headers, including RLP encoding and hash computation.
64///
65/// This trait provides methods to handle standard operations on Ethereum block headers such as encoding
66/// and hashing, which are critical for verifying the integrity of a block and its inclusion in the blockchain.
67/// It also provides a utility method for converting hexadecimal strings into fixed-size byte arrays, which is
68/// useful when handling Ethereum's cryptographic data.
69///
70/// # Example
71///
72/// ```rust
73/// struct MyBlockHeader {
74///     // block header fields...
75/// }
76///
77/// impl BlockHeaderTrait for MyBlockHeader {
78///     fn rlp_encode(&self) -> Vec<u8> {
79///         // perform RLP encoding...
80///     }
81/// }
82///
83/// let my_header = MyBlockHeader { /* fields... */ };
84/// let block_hash = my_header.compute_hash();
85/// ```
86pub trait BlockHeaderTrait {
87    /// Encodes the block header using RLP (Recursive Length Prefix) encoding, which is used to serialize Ethereum objects.
88    ///
89    /// This method should encode the block header into a byte vector using RLP encoding. It is essential for
90    /// transmitting the block header in a compact format or for use in cryptographic operations, such as computing
91    /// the block hash.
92    ///
93    /// # Returns
94    ///
95    /// A `Vec<u8>` containing the RLP-encoded block header.
96    fn rlp_encode(&self) -> Vec<u8>;
97
98    /// Computes the Keccak256 hash of the block header.
99    ///
100    /// This method first encodes the block header using the `rlp_encode` method and then computes the Keccak256
101    /// hash of the resulting bytes. This hash is used as the block's unique identifier (`block_hash`) in the Ethereum
102    /// blockchain and plays a crucial role in the consensus and security mechanisms.
103    ///
104    /// # Returns
105    ///
106    /// An `H256` hash, representing the 32-byte Keccak256 hash of the block header.
107    fn compute_hash(&self) -> H256 {
108        let rlp_encoded = self.rlp_encode();
109        let hash = Keccak256::digest(rlp_encoded);
110        H256::from_slice(&hash)
111    }
112
113    /// Converts a hexadecimal string to a fixed-size byte array.
114    ///
115    /// This utility function converts a hexadecimal string (prefixed with "0x") into a fixed-size array of bytes.
116    /// It ensures that the length of the byte array matches the expected size, and will panic if the input
117    /// string does not have the correct length.
118    ///
119    /// # Arguments
120    ///
121    /// - `hex_str`: A string slice containing a hexadecimal string (e.g., "0x1234...").
122    ///
123    /// # Returns
124    ///
125    /// A fixed-size array of `N` bytes representing the decoded hexadecimal string.
126    ///
127    /// # Panics
128    ///
129    /// This function will panic if the length of the decoded bytes does not match the expected size `N`.
130    fn hex_to_fixed_array<const N: usize>(hex_str: &str) -> [u8; N] {
131        let bytes = hex::decode(&hex_str[2..]).unwrap();
132        let mut array = [0u8; N];
133        let len = bytes.len();
134        if len != N {
135            panic!("Invalid input length: expected {}, got {}", N, len);
136        }
137        array.copy_from_slice(&bytes);
138        array
139    }
140}