1use crate::types::{Bytes, H160, H2048, H256, H64, U256, U64};
2use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
3
4#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
6pub struct BlockHeader {
7 pub hash: Option<H256>,
9 #[serde(rename = "parentHash")]
11 pub parent_hash: H256,
12 #[serde(rename = "sha3Uncles")]
14 pub uncles_hash: H256,
15 #[serde(rename = "miner")]
17 #[serde(default)]
18 pub author: H160,
19 #[serde(rename = "stateRoot")]
21 pub state_root: H256,
22 #[serde(rename = "transactionsRoot")]
24 pub transactions_root: H256,
25 #[serde(rename = "receiptsRoot")]
27 pub receipts_root: H256,
28 pub number: Option<U64>,
30 #[serde(rename = "gasUsed")]
32 pub gas_used: U256,
33 #[serde(rename = "gasLimit")]
35 pub gas_limit: U256,
36 #[serde(rename = "extraData")]
38 pub extra_data: Bytes,
39 #[serde(rename = "logsBloom")]
41 pub logs_bloom: H2048,
42 pub timestamp: U256,
44 pub difficulty: U256,
46 #[serde(rename = "mixHash")]
48 pub mix_hash: Option<H256>,
49 pub nonce: Option<H64>,
51}
52
53#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
56pub struct Block<TX> {
57 pub hash: Option<H256>,
59 #[serde(rename = "parentHash")]
61 pub parent_hash: H256,
62 #[serde(rename = "sha3Uncles")]
64 pub uncles_hash: H256,
65 #[serde(rename = "miner")]
67 #[serde(default)]
68 pub author: H160,
69 #[serde(rename = "stateRoot")]
71 pub state_root: H256,
72 #[serde(rename = "transactionsRoot")]
74 pub transactions_root: H256,
75 #[serde(rename = "receiptsRoot")]
77 pub receipts_root: H256,
78 pub number: Option<U64>,
80 #[serde(rename = "gasUsed")]
82 pub gas_used: U256,
83 #[serde(rename = "gasLimit")]
85 pub gas_limit: U256,
86 #[serde(rename = "extraData")]
88 pub extra_data: Bytes,
89 #[serde(rename = "logsBloom")]
91 pub logs_bloom: Option<H2048>,
92 pub timestamp: U256,
94 pub difficulty: U256,
96 #[serde(rename = "totalDifficulty")]
98 pub total_difficulty: Option<U256>,
99 #[serde(default, rename = "sealFields")]
101 pub seal_fields: Vec<Bytes>,
102 pub uncles: Vec<H256>,
104 pub transactions: Vec<TX>,
106 pub size: Option<U256>,
108 #[serde(rename = "mixHash")]
110 pub mix_hash: Option<H256>,
111 pub nonce: Option<H64>,
113}
114
115#[derive(Copy, Clone, Debug, PartialEq)]
117pub enum BlockNumber {
118 Latest,
120 Earliest,
122 Pending,
124 Number(U64),
126}
127
128impl<T: Into<U64>> From<T> for BlockNumber {
129 fn from(num: T) -> Self {
130 BlockNumber::Number(num.into())
131 }
132}
133
134impl Serialize for BlockNumber {
135 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136 where
137 S: Serializer,
138 {
139 match *self {
140 BlockNumber::Number(ref x) => serializer.serialize_str(&format!("0x{:x}", x)),
141 BlockNumber::Latest => serializer.serialize_str("latest"),
142 BlockNumber::Earliest => serializer.serialize_str("earliest"),
143 BlockNumber::Pending => serializer.serialize_str("pending"),
144 }
145 }
146}
147
148#[derive(Copy, Clone, Debug, PartialEq)]
150pub enum BlockId {
151 Hash(H256),
153 Number(BlockNumber),
155}
156
157impl Serialize for BlockId {
158 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
159 where
160 S: Serializer,
161 {
162 match *self {
163 BlockId::Hash(ref x) => {
164 let mut s = serializer.serialize_struct("BlockIdEip1898", 1)?;
165 s.serialize_field("blockHash", &format!("{:?}", x))?;
166 s.end()
167 }
168 BlockId::Number(ref num) => num.serialize(serializer),
169 }
170 }
171}
172
173impl From<U64> for BlockId {
174 fn from(num: U64) -> Self {
175 BlockNumber::Number(num).into()
176 }
177}
178
179impl From<BlockNumber> for BlockId {
180 fn from(num: BlockNumber) -> Self {
181 BlockId::Number(num)
182 }
183}
184
185impl From<H256> for BlockId {
186 fn from(hash: H256) -> Self {
187 BlockId::Hash(hash)
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn block_without_miner() {
197 const EXAMPLE_BLOCK: &str = r#"{
198 "number": "0x1b4",
199 "hash": "0x0e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
200 "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5",
201 "mixHash": "0x1010101010101010101010101010101010101010101010101010101010101010",
202 "nonce": "0x0000000000000000",
203 "sealFields": [
204 "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2",
205 "0x0000000000000042"
206 ],
207 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
208 "logsBloom": "0x0e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d15273310e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
209 "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
210 "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
211 "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff",
212 "difficulty": "0x27f07",
213 "totalDifficulty": "0x27f07",
214 "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
215 "size": "0x27f07",
216 "gasLimit": "0x9f759",
217 "minGasPrice": "0x9f759",
218 "gasUsed": "0x9f759",
219 "timestamp": "0x54e34e8e",
220 "transactions": [],
221 "uncles": []
222 }"#;
223
224 let block: Block<()> = serde_json::from_str(&EXAMPLE_BLOCK).unwrap();
225
226 assert_eq!(block.author, Default::default());
227 }
228}