Skip to content

Commit e40343a

Browse files
authored
feat: Implemented the is_valid_block_hash, is_valid_versioned_hashes functions (#63)
* feat: implementing execution engine * fix: fixed requested changes * fix: requested changes
1 parent e487d53 commit e40343a

File tree

8 files changed

+389
-2
lines changed

8 files changed

+389
-2
lines changed

Cargo.lock

Lines changed: 117 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ rust-version = "1.81.0"
2525
version = "0.1.0"
2626

2727
[workspace.dependencies]
28+
alloy-consensus = { version = "0.11.1", default-features = false }
2829
alloy-primitives = { version = "0.8", features = ['serde'] }
30+
alloy-rlp = { version = "0.3.8", default-features = false, features = ["derive"] }
2931
anyhow = "1.0"
3032
blst = "0.3"
3133
kzg = { git = "https://github.com/grandinetech/rust-kzg" }

crates/common/consensus/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ rust-version.workspace = true
1010
version.workspace = true
1111

1212
[dependencies]
13+
alloy-consensus.workspace = true
1314
alloy-primitives.workspace = true
15+
alloy-rlp.workspace = true
1416
anyhow.workspace = true
1517
blst.workspace = true
1618
kzg.workspace = true

crates/common/consensus/src/deneb/execution_payload.rs

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use alloy_primitives::{Address, B256, U256};
1+
use alloy_consensus::proofs::{ordered_trie_root, ordered_trie_root_with_encoder};
2+
use alloy_primitives::{b256, bytes, keccak256, Address, Bytes, B256, B64, U256};
3+
use alloy_rlp::Encodable;
24
use serde::{Deserialize, Serialize};
35
use ssz_derive::{Decode, Encode};
46
use ssz_types::{
@@ -9,6 +11,9 @@ use tree_hash_derive::TreeHash;
911

1012
use crate::withdrawal::Withdrawal;
1113

14+
const EMPTY_UNCLE_ROOT_HASH: B256 =
15+
b256!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347");
16+
1217
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)]
1318
pub struct ExecutionPayload {
1419
// Execution block header fields
@@ -36,3 +41,94 @@ pub struct ExecutionPayload {
3641
pub blob_gas_used: u64,
3742
pub excess_blob_gas: u64,
3843
}
44+
45+
impl ExecutionPayload {
46+
pub fn header_hash(&self, parent_beacon_block_root: B256) -> B256 {
47+
let mut buf = vec![];
48+
self.encode(&mut buf, parent_beacon_block_root);
49+
keccak256(buf)
50+
}
51+
52+
fn encode(&self, out: &mut dyn bytes::BufMut, parent_beacon_block_root: B256) {
53+
let transactions = self
54+
.transactions
55+
.clone()
56+
.into_iter()
57+
.map(|transaction| Bytes::from(transaction.to_vec()))
58+
.collect::<Vec<_>>();
59+
let transactions_root = calculate_transactions_root(&transactions);
60+
let withdrawals_root = calculate_withdrawals_root(&self.withdrawals);
61+
alloy_rlp::Header {
62+
list: true,
63+
payload_length: self.rlp_payload_length(
64+
parent_beacon_block_root,
65+
transactions_root,
66+
withdrawals_root,
67+
),
68+
}
69+
.encode(out);
70+
71+
self.parent_hash.encode(out);
72+
EMPTY_UNCLE_ROOT_HASH.encode(out);
73+
self.fee_recipient.encode(out);
74+
self.state_root.encode(out);
75+
transactions_root.encode(out);
76+
self.receipts_root.encode(out);
77+
self.logs_bloom.encode(out);
78+
U256::ZERO.encode(out);
79+
self.block_number.encode(out);
80+
self.gas_limit.encode(out);
81+
self.gas_used.encode(out);
82+
self.timestamp.encode(out);
83+
self.extra_data.to_vec().as_slice().encode(out);
84+
self.prev_randao.encode(out);
85+
B64::ZERO.encode(out);
86+
self.base_fee_per_gas.encode(out);
87+
withdrawals_root.encode(out);
88+
self.blob_gas_used.encode(out);
89+
self.excess_blob_gas.encode(out);
90+
parent_beacon_block_root.encode(out);
91+
}
92+
93+
fn rlp_payload_length(
94+
&self,
95+
parent_beacon_block_root: B256,
96+
transactions_root: B256,
97+
withdrawals_root: B256,
98+
) -> usize {
99+
self.parent_hash.length()
100+
+ EMPTY_UNCLE_ROOT_HASH.length() // ommers_hash
101+
+ self.fee_recipient.length()
102+
+ self.state_root.length()
103+
+ transactions_root.length()
104+
+ self.receipts_root.length()
105+
+ self.logs_bloom.length()
106+
+ U256::ZERO.length() // difficulty
107+
+ self.block_number.length()
108+
+ self.gas_limit.length()
109+
+ self.gas_used.length()
110+
+ self.timestamp.length()
111+
+ self.extra_data.to_vec().as_slice().length()
112+
+ self.prev_randao.length()
113+
+ B64::ZERO.length() // nonce
114+
+ self.base_fee_per_gas.length()
115+
+ withdrawals_root.length()
116+
+ self.blob_gas_used.length()
117+
+ self.excess_blob_gas.length()
118+
+ parent_beacon_block_root.length()
119+
}
120+
}
121+
122+
/// Calculate the Merkle Patricia Trie root hash from a list of items
123+
/// `(rlp(index), encoded(item))` pairs.
124+
pub fn calculate_transactions_root<T>(transactions: &[T]) -> B256
125+
where
126+
T: Encodable,
127+
{
128+
ordered_trie_root_with_encoder(transactions, |tx: &T, buf| tx.encode(buf))
129+
}
130+
131+
/// Calculates the root hash of the withdrawals.
132+
pub fn calculate_withdrawals_root(withdrawals: &[Withdrawal]) -> B256 {
133+
ordered_trie_root(withdrawals)
134+
}

0 commit comments

Comments
 (0)