referrerpolicy=no-referrer-when-downgrade

pallet_revive/evm/api/
block.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10//  http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use 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/// Block object
26#[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	/// Base fee per gas
33	pub base_fee_per_gas: U256,
34	/// Blob gas used
35	pub blob_gas_used: U256,
36	/// Difficulty
37	pub difficulty: U256,
38	/// Excess blob gas
39	pub excess_blob_gas: U256,
40	/// Extra data
41	pub extra_data: Bytes,
42	/// Gas limit
43	pub gas_limit: U256,
44	/// Gas used
45	pub gas_used: U256,
46	/// Hash
47	pub hash: H256,
48	/// Bloom filter
49	pub logs_bloom: Bytes256,
50	/// Coinbase
51	pub miner: Address,
52	/// Mix hash
53	pub mix_hash: H256,
54	/// Nonce
55	pub nonce: Bytes8,
56	/// Number
57	pub number: U256,
58	/// Parent Beacon Block Root
59	#[serde(skip_serializing_if = "Option::is_none")]
60	pub parent_beacon_block_root: Option<H256>,
61	/// Parent block hash
62	pub parent_hash: H256,
63	/// Receipts root
64	pub receipts_root: H256,
65	/// Requests root
66	#[serde(skip_serializing_if = "Option::is_none")]
67	pub requests_hash: Option<H256>,
68	/// Ommers hash
69	pub sha_3_uncles: H256,
70	/// Block size
71	pub size: U256,
72	/// State root
73	pub state_root: H256,
74	/// Timestamp
75	pub timestamp: U256,
76	/// Total difficulty
77	#[serde(skip_serializing_if = "Option::is_none")]
78	pub total_difficulty: Option<U256>,
79	pub transactions: HashesOrTransactionInfos,
80	/// Transactions root
81	pub transactions_root: H256,
82	/// Uncles
83	pub uncles: Vec<H256>,
84	/// Withdrawals
85	pub withdrawals: Vec<Withdrawal>,
86	/// Withdrawals root
87	pub withdrawals_root: H256,
88}
89
90/// Validator withdrawal
91#[derive(
92	Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, TypeInfo, Encode, Decode,
93)]
94#[serde(rename_all = "camelCase")]
95pub struct Withdrawal {
96	/// recipient address for withdrawal value
97	pub address: Address,
98	/// value contained in withdrawal
99	pub amount: U256,
100	/// index of withdrawal
101	pub index: U256,
102	/// index of validator that generated withdrawal
103	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		// Deserialize the JSON into a Block
142		let block: Block = serde_json::from_str(json_input).expect("Failed to deserialize block");
143
144		// Serialize it back to JSON
145		let serialized = serde_json::to_string(&block).expect("Failed to serialize block");
146
147		// Deserialize again to ensure roundtrip consistency
148		let block_roundtrip: Block =
149			serde_json::from_str(&serialized).expect("Failed to deserialize roundtrip block");
150
151		// Verify that deserializing and serializing leads to the same result
152		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}