1use super::{Bytes, Bytes8, Bytes256, HashesOrTransactionInfos};
19use alloc::vec::Vec;
20use codec::{Decode, Encode};
21use ethereum_types::*;
22use scale_info::TypeInfo;
23use serde::{Deserialize, Serialize};
24
25#[derive(
27 Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, TypeInfo, Encode, Decode,
28)]
29#[serde(rename_all = "camelCase")]
30#[allow(missing_docs)]
31pub struct Block {
32 pub base_fee_per_gas: U256,
34 pub blob_gas_used: U256,
36 pub difficulty: U256,
38 pub excess_blob_gas: U256,
40 pub extra_data: Bytes,
42 pub gas_limit: U256,
44 pub gas_used: U256,
46 pub hash: H256,
48 pub logs_bloom: Bytes256,
50 pub miner: Address,
52 pub mix_hash: H256,
54 pub nonce: Bytes8,
56 pub number: U256,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub parent_beacon_block_root: Option<H256>,
61 pub parent_hash: H256,
63 pub receipts_root: H256,
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub requests_hash: Option<H256>,
68 pub sha_3_uncles: H256,
70 pub size: U256,
72 pub state_root: H256,
74 pub timestamp: U256,
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub total_difficulty: Option<U256>,
79 pub transactions: HashesOrTransactionInfos,
80 pub transactions_root: H256,
82 pub uncles: Vec<H256>,
84 pub withdrawals: Vec<Withdrawal>,
86 pub withdrawals_root: H256,
88}
89
90#[derive(
92 Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, TypeInfo, Encode, Decode,
93)]
94#[serde(rename_all = "camelCase")]
95pub struct Withdrawal {
96 pub address: Address,
98 pub amount: U256,
100 pub index: U256,
102 pub validator_index: U256,
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::evm::*;
109
110 #[test]
111 fn test_block_serialization_roundtrip() {
112 let json_input = r#"{
113 "baseFeePerGas": "0x126f2347",
114 "blobGasUsed": "0x100000",
115 "difficulty": "0x0",
116 "excessBlobGas": "0x0",
117 "extraData": "0x546974616e2028746974616e6275696c6465722e78797a29",
118 "gasLimit": "0x2aca2c9",
119 "gasUsed": "0x1c06043",
120 "hash": "0xe6064637def8a5a9a90c8a666005975e4a6c46acf8af57e1f2adb20dfced133a",
121 "logsBloom": "0xbf7bf1afcf57ea95fbb5c6fd8db37db9dbffec27cfc6a39b3417e7786defd7e3d6fd577ecddd5676eee8bf79df8faddcefa7e169def77f7e7d6dbbfd1dfef9aebd9e707b4c4ed979fda2cdeeb96b3bfed5d5fabb68ff9e7f2dfb075eff643a93feebbc07877f0dff66fedf4ede0fbcfbf56f98a1626eaed77ed4e6be388f162f9b2deeff1eefa93bdacbf3fbbd7b6757cddb7ae5b3f9b7af9c3bbff7e7f6ddef9f2dff7f17997ea6867675c29fcbe6bf725efbffe1507589bfd47a3bf7b6f5dfde50776fd94fe772d2c7b6b58baf554de55c176f27efa6fdcff7f17689bafa7f7c7bf4fd5fb9b05c2f4ed785f17ac9779feeaf1f5bbdadfc42ebad367fdcf7ad",
122 "miner": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97",
123 "mixHash": "0x7e53d2d6772895d024eb00da80213aec81fb4a15bec34a5a39403ad6162274af",
124 "nonce": "0x0000000000000000",
125 "number": "0x1606672",
126 "parentBeaconBlockRoot": "0xd9ef51c8f4155f238ba66df0d35a4d0a6bb043c0dacb5c5dbd5a231bbd4c8a01",
127 "parentHash": "0x37b527c98c86436f292d4e19fac3aba6d8c7768684ea972f50adc305fd9a1475",
128 "receiptsRoot": "0x2abab67c41b350435eb34f9dc0478dd7d262f35544cecf62a85af2da075bd38d",
129 "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
130 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
131 "size": "0x29e6c",
132 "stateRoot": "0x5159c56472adff9a760275ac63524a71f5645ede822a5547dd9ad333586d5157",
133 "timestamp": "0x6895a93f",
134 "transactions": [],
135 "transactionsRoot": "0xfb0b9f5b28bc927db98d82e18070d2b17434c31bd2773c5dd699e96fa76a34cd",
136 "uncles": [],
137 "withdrawals": [],
138 "withdrawalsRoot": "0x531480435633d56a52433b33f41ac9322f51a2df3364c4c112236fc6ac583118"
139 }"#;
140
141 let block: Block = serde_json::from_str(json_input).expect("Failed to deserialize block");
143
144 let serialized = serde_json::to_string(&block).expect("Failed to serialize block");
146
147 let block_roundtrip: Block =
149 serde_json::from_str(&serialized).expect("Failed to deserialize roundtrip block");
150
151 assert_eq!(block, block_roundtrip);
153 }
154
155 #[test]
156 fn test_block_decode() {
157 let json = r#"{
158 "baseFeePerGas": "0x23cf3fd4",
159 "blobGasUsed": "0x0",
160 "difficulty": "0x0",
161 "excessBlobGas": "0x80000",
162 "extraData": "0x546974616e2028746974616e6275696c6465722e78797a29",
163 "gasLimit": "0x2aea4ea",
164 "gasUsed": "0xe36e2f",
165 "hash": "0xfb8c980d1da1a75e68c2ea4d55cb88d62dedbbb5eaf69df8fe337e9f6922b73a",
166 "logsBloom": "0xb56c514421c05ba024436428e2487b83134983e9c650686421bd10588512e0a9a55d51e8e84c868446517ed5e90609dd43aad1edcc1462b8e8f15763b3ff6e62a506d3d910d0aae829786fac994a6de34860263be47eb8300e91dd2cc3110a22ba0d60008e6a0362c5a3ffd5aa18acc8c22b6fe02c54273b12a841bc958c9ae12378bc0e5881c2d840ff677f8038243216e5c105e58819bc0cbb8c56abb7e490cf919ceb85702e5d54dece9332a00c9e6ade9cb47d42440201ecd7704088236b39037c9ff189286e3e5d6657aa389c2d482e337af5cfc45b0d25ad0e300c2b6bf599bc2007008830226612a4e7e7cae4e57c740205a809dc280825165b98559c",
167 "miner": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97",
168 "mixHash": "0x11b02e97eaa48bc83cbb6f9478f32eaf7e8b67fead4edeef945822612f1854f6",
169 "nonce": "0x0000000000000000",
170 "number": "0x161bd0f",
171 "parentBeaconBlockRoot": "0xd8266eb7bb40e4e5e3beb9caed7ccaa448ce55203a03705c87860deedcf7236d",
172 "parentHash": "0x7c9625cc198af5cf677a15cdc38da3cf64d57b9729de5bd1c96b3c556a84aa7d",
173 "receiptsRoot": "0x758614638725ede86a2f4c8339eb79b84ae346915319dc286643c9324e34f28a",
174 "requestsHash": "0xd9267a5ab4782c4e0bdc5fcd2fefb53c91f92f91b6059c8f13343a0691ba77d1",
175 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
176 "size": "0x14068",
177 "stateRoot": "0x7ed9726e3172886af5301968c2ddb7c38f8adf99c99ec10fdfaab66c610854bb",
178 "timestamp": "0x68a5ce5b",
179 "transactions": [
180 {
181 "blockHash": "0xfb8c980d1da1a75e68c2ea4d55cb88d62dedbbb5eaf69df8fe337e9f6922b73a",
182 "blockNumber": "0x161bd0f",
183 "from": "0x693ca5c6852a7d212dabc98b28e15257465c11f3",
184 "gas": "0x70bdb",
185 "gasPrice": "0x23cf3fd4",
186 "maxPriorityFeePerGas": "0x0",
187 "maxFeePerGas": "0x47ca802f",
188 "hash": "0xf6d8b07ddcf9a9d44c99c3665fd8c78f0ccd32506350ea5a9be1a68ba08bfd1f",
189 "input": "0x09c5eabe000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002a90000cca0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000020000000000000000000000035c9618f600000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002374fed200000000000000000001528fd550bc9a0000000000000000351e55bea6d51900dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000005c0c965e0000000000000000000000000000000000004c00000001000000000000000000000000000000000000002e24cd1d61a63f43658ed73b6ddeba00010002000100000000000000000000000000000000000000000000000039d622818daae62900006602000000000000000000002ff9e9686fa6ac00000000000000000000000000007f88ca000000000000000004caaa5ba8029c920300010000000000000000052319c661ddb06600000000000000000001528fd550bc9a0000000000000000005049606b67676100011c0c00000000000000002ff9e9686fa6ac000000000000000000000000035c16902c0000000000000000000000000000000200000000000000000000000000000002000073d53553ee552c1f2a9722e6407d43e41e19593f1cbc3d63300bfc6e48709f5b5ed98f228c70104e8c5d570b5608b47dca95ce6e371636965b6fdcab3613b6b65f061a44b7132011bb97a768bd238eacb62d7109920b000000000000000005246c56372e6d000000000000000000000000005c0c965e0000000000000000000000002374fed20000000000000000000000002374fed200011cc19621f6edbb9c02b95055b9f52eba0e2cb954c259f42aeca488551ea82b72f2504bbd310eb7145435e258751ab6854ab08b1630b89d6621dc1398c5d0c43b480000000000000000000000000000000000000000000000000000",
190 "nonce": "0x40c6",
191 "to": "0x0000000aa232009084bd71a5797d089aa4edfad4",
192 "transactionIndex": "0x0",
193 "value": "0x0",
194 "type": "0x2",
195 "accessList": [],
196 "chainId": "0x1",
197 "v": "0x1",
198 "yParity": "0x1",
199 "r": "0xb3e71bd95d73e965495b17647f5faaf058e13af7dd21f2af24eac16f7e9d06a1",
200 "s": "0x58775b0c15075fb7f007b88e88605ae5daec1ffbac2771076e081c8c2b005c20"
201 },
202 {
203 "blockHash": "0xfb8c980d1da1a75e68c2ea4d55cb88d62dedbbb5eaf69df8fe337e9f6922b73a",
204 "blockNumber": "0x161bd0f",
205 "from": "0x4791eb2224d272655e8d5da171bb07dd5a805ff6",
206 "hash": "0xda8bc5dc5617758c6af0681d71642f68ce679bb92df4d8cf48493f0cfad14e20",
207 "transactionIndex": "0x19",
208 "gas": "0x186a0",
209 "gasPrice": "0x6a5efc76",
210 "maxPriorityFeePerGas": "0x6a5efc76",
211 "maxFeePerGas": "0x6a5efc76",
212 "input": "0x2c7bddf4",
213 "nonce": "0x6233",
214 "to": "0x62b53c45305d29bbe4b1bfa49dd78766b2f1e624",
215 "value": "0x0",
216 "type": "0x4",
217 "accessList": [],
218 "chainId": "0x1",
219 "authorizationList": [
220 ],
221 "v": "0x1",
222 "yParity": "0x1",
223 "r": "0x3b863c04d39f70e499ffb176376128a57481727116027a92a364b6e1668d13a7",
224 "s": "0x39b13f0597c509de8260c7808057e64126e7d0715044dda908d1f513e1ed79ad"
225 }
226 ],
227 "transactionsRoot": "0xca2e7e6ebe1b08030fe5b9efabee82b95e62f07cff5a4298354002c46b41a216",
228 "uncles": [],
229 "withdrawals": [
230 ],
231 "withdrawalsRoot": "0x7a3ad42fdb774c0e662597141f52a81210ffec9ce0db9dfcd841f747b0909010"
232 }"#;
233
234 let _result: Block = serde_json::from_str(json).unwrap();
235 }
236}