Skip to content

Commit c532b7b

Browse files
committed
feat: add deneb proofs
1 parent 22b31a9 commit c532b7b

File tree

6 files changed

+244
-92
lines changed

6 files changed

+244
-92
lines changed

Diff for: bin/e2hs-writer/src/reader.rs

+44-13
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,16 @@ impl EpochReader {
282282

283283
#[cfg(test)]
284284
mod tests {
285-
use ethportal_api::types::{
286-
consensus::{
287-
beacon_block::{BeaconBlockBellatrix, BeaconBlockCapella},
288-
beacon_state::BeaconState,
289-
fork::ForkName,
290-
},
291-
execution::header_with_proof::{
292-
build_historical_roots_proof, build_historical_summaries_proof,
293-
BlockProofHistoricalRoots, BlockProofHistoricalSummaries,
285+
use ethportal_api::{
286+
consensus::beacon_block::BeaconBlock,
287+
types::{
288+
consensus::{
289+
beacon_block::BeaconBlockBellatrix, beacon_state::BeaconState, fork::ForkName,
290+
},
291+
execution::header_with_proof::{
292+
build_block_proof_historical_roots, build_historical_summaries_proof,
293+
BlockProofHistoricalRoots, BlockProofHistoricalSummaries,
294+
},
294295
},
295296
};
296297
use serde_yaml::Value;
@@ -336,7 +337,7 @@ mod tests {
336337
let block_path = format!("{test_assets_dir}/block.ssz");
337338
let block_raw = std::fs::read(block_path).unwrap();
338339
let block = BeaconBlockBellatrix::from_ssz_bytes(&block_raw).unwrap();
339-
let proof = build_historical_roots_proof(slot, &historical_batch, block);
340+
let proof = build_block_proof_historical_roots(slot, &historical_batch, &block);
340341

341342
assert_eq!(actual_proof, proof);
342343
}
@@ -388,11 +389,41 @@ mod tests {
388389
let state_path = format!("{test_assets_dir}/beacon_state.ssz");
389390
let state_raw = std::fs::read(state_path).unwrap();
390391
let beacon_state = BeaconState::from_ssz_bytes(&state_raw, ForkName::Capella).unwrap();
391-
let beacon_state = beacon_state.as_capella().unwrap();
392392
let block_path = format!("{test_assets_dir}/block.ssz");
393393
let block_raw = std::fs::read(block_path).unwrap();
394-
let block = BeaconBlockCapella::from_ssz_bytes(&block_raw).unwrap();
395-
let proof = build_historical_summaries_proof(slot, beacon_state, block);
394+
let block = BeaconBlock::from_ssz_bytes(&block_raw, ForkName::Capella).unwrap();
395+
let proof = build_historical_summaries_proof(slot, &beacon_state, &block);
396+
397+
assert_eq!(actual_proof, proof);
398+
}
399+
#[tokio::test]
400+
async fn test_pre_pectra_proof_generation() {
401+
let test_vector = std::fs::read_to_string(
402+
"../../portal-spec-tests/tests/mainnet/history/headers_with_proof/block_proofs_deneb/beacon_block_proof-22162263.yaml"
403+
)
404+
.unwrap();
405+
let test_vector: Value = serde_yaml::from_str(&test_vector).unwrap();
406+
let actual_proof = BlockProofHistoricalSummaries {
407+
beacon_block_proof: serde_yaml::from_value(test_vector["beacon_block_proof"].clone())
408+
.unwrap(),
409+
beacon_block_root: serde_yaml::from_value(test_vector["beacon_block_root"].clone())
410+
.unwrap(),
411+
execution_block_proof: serde_yaml::from_value(
412+
test_vector["execution_block_proof"].clone(),
413+
)
414+
.unwrap(),
415+
slot: serde_yaml::from_value(test_vector["slot"].clone()).unwrap(),
416+
};
417+
418+
let test_assets_dir =
419+
"../../portal-spec-tests/tests/mainnet/history/headers_with_proof/beacon_data/22162263";
420+
let state_path = format!("{test_assets_dir}/beacon_state.ssz");
421+
let state_raw = std::fs::read(state_path).unwrap();
422+
let beacon_state = BeaconState::from_ssz_bytes(&state_raw, ForkName::Deneb).unwrap();
423+
let block_path = format!("{test_assets_dir}/block.ssz");
424+
let block_raw = std::fs::read(block_path).unwrap();
425+
let block = BeaconBlock::from_ssz_bytes(&block_raw, ForkName::Deneb).unwrap();
426+
let proof = build_historical_summaries_proof(11378687, &beacon_state, &block);
396427

397428
assert_eq!(actual_proof, proof);
398429
}

Diff for: crates/ethportal-api/src/types/consensus/beacon_block.rs

+45-18
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,58 @@ impl BeaconBlock {
6969
}
7070
}
7171

72+
/// Helper function to build a body root proof for a beacon block
73+
fn build_beacon_block_body_root_proof(
74+
slot: u64,
75+
proposer_index: u64,
76+
parent_root: &B256,
77+
state_root: &B256,
78+
body_root: &B256,
79+
) -> Vec<B256> {
80+
let leaves = vec![
81+
slot.tree_hash_root().0,
82+
proposer_index.tree_hash_root().0,
83+
parent_root.tree_hash_root().0,
84+
state_root.tree_hash_root().0,
85+
body_root.tree_hash_root().0,
86+
];
87+
// We want to prove the body root, which is the 5th leaf
88+
build_merkle_proof_for_index(leaves, 4)
89+
}
90+
7291
impl BeaconBlockCapella {
7392
pub fn build_body_root_proof(&self) -> Vec<B256> {
74-
let leaves = vec![
75-
self.slot.tree_hash_root().0,
76-
self.proposer_index.tree_hash_root().0,
77-
self.parent_root.tree_hash_root().0,
78-
self.state_root.tree_hash_root().0,
79-
self.body.tree_hash_root().0,
80-
];
81-
// We want to prove the body root, which is the 5th leaf
82-
build_merkle_proof_for_index(leaves, 4)
93+
build_beacon_block_body_root_proof(
94+
self.slot,
95+
self.proposer_index,
96+
&self.parent_root,
97+
&self.state_root,
98+
&self.body.tree_hash_root(),
99+
)
83100
}
84101
}
85102

86103
impl BeaconBlockBellatrix {
87104
pub fn build_body_root_proof(&self) -> Vec<B256> {
88-
let leaves = vec![
89-
self.slot.tree_hash_root().0,
90-
self.proposer_index.tree_hash_root().0,
91-
self.parent_root.tree_hash_root().0,
92-
self.state_root.tree_hash_root().0,
93-
self.body.tree_hash_root().0,
94-
];
95-
// We want to prove the body root, which is the 5th leaf
96-
build_merkle_proof_for_index(leaves, 4)
105+
build_beacon_block_body_root_proof(
106+
self.slot,
107+
self.proposer_index,
108+
&self.parent_root,
109+
&self.state_root,
110+
&self.body.tree_hash_root(),
111+
)
112+
}
113+
}
114+
115+
impl BeaconBlockDeneb {
116+
pub fn build_body_root_proof(&self) -> Vec<B256> {
117+
build_beacon_block_body_root_proof(
118+
self.slot,
119+
self.proposer_index,
120+
&self.parent_root,
121+
&self.state_root,
122+
&self.body.tree_hash_root(),
123+
)
97124
}
98125
}
99126

Diff for: crates/ethportal-api/src/types/consensus/beacon_state.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,29 @@ impl BeaconState {
162162
}
163163
}
164164

165+
/// Helper function to build a block root proof from block roots
166+
fn build_block_root_proof_from_roots(
167+
block_roots: &FixedVector<B256, SlotsPerHistoricalRoot>,
168+
block_root_index: usize,
169+
) -> Vec<B256> {
170+
let leaves: Vec<[u8; 32]> = block_roots
171+
.iter()
172+
.map(|root| root.tree_hash_root().0)
173+
.collect();
174+
build_merkle_proof_for_index(leaves, block_root_index)
175+
}
176+
165177
impl BeaconStateCapella {
166178
pub fn build_block_root_proof(&self, block_root_index: usize) -> Vec<B256> {
167-
// Build block hash proof for self.block_roots
168-
let leaves: Vec<[u8; 32]> = self
169-
.block_roots
170-
.iter()
171-
.map(|root| root.tree_hash_root().0)
172-
.collect();
173-
build_merkle_proof_for_index(leaves, block_root_index)
179+
build_block_root_proof_from_roots(&self.block_roots, block_root_index)
174180
}
175181
}
176182

177183
impl BeaconStateDeneb {
184+
pub fn build_block_root_proof(&self, block_root_index: usize) -> Vec<B256> {
185+
build_block_root_proof_from_roots(&self.block_roots, block_root_index)
186+
}
187+
178188
pub fn build_historical_summaries_proof(&self) -> Vec<B256> {
179189
let leaves = vec![
180190
self.genesis_time.tree_hash_root().0,

Diff for: crates/ethportal-api/src/types/consensus/body.rs

+28
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,34 @@ impl BeaconBlockBody {
8787
}
8888
}
8989

90+
impl BeaconBlockBodyDeneb {
91+
pub fn build_execution_payload_proof(&self) -> Vec<B256> {
92+
let leaves = vec![
93+
self.randao_reveal.tree_hash_root().0,
94+
self.eth1_data.tree_hash_root().0,
95+
self.graffiti.tree_hash_root().0,
96+
self.proposer_slashings.tree_hash_root().0,
97+
self.attester_slashings.tree_hash_root().0,
98+
self.attestations.tree_hash_root().0,
99+
self.deposits.tree_hash_root().0,
100+
self.voluntary_exits.tree_hash_root().0,
101+
self.sync_aggregate.tree_hash_root().0,
102+
self.execution_payload.tree_hash_root().0,
103+
self.bls_to_execution_changes.tree_hash_root().0,
104+
self.blob_kzg_commitments.tree_hash_root().0,
105+
];
106+
// We want to prove the 10th leaf
107+
build_merkle_proof_for_index(leaves, 9)
108+
}
109+
110+
pub fn build_execution_block_hash_proof(&self) -> Vec<B256> {
111+
let mut block_hash_proof = self.execution_payload.build_block_hash_proof();
112+
let execution_payload_proof = self.build_execution_payload_proof();
113+
block_hash_proof.extend(execution_payload_proof);
114+
block_hash_proof
115+
}
116+
}
117+
90118
impl BeaconBlockBodyCapella {
91119
pub fn build_execution_payload_proof(&self) -> Vec<B256> {
92120
let leaves = vec![

Diff for: crates/ethportal-api/src/types/consensus/execution_payload.rs

+25
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,31 @@ impl ExecutionPayload {
9292
}
9393
}
9494

95+
impl ExecutionPayloadDeneb {
96+
pub fn build_block_hash_proof(&self) -> Vec<B256> {
97+
let leaves = vec![
98+
self.parent_hash.tree_hash_root().0,
99+
self.fee_recipient.tree_hash_root().0,
100+
self.state_root.tree_hash_root().0,
101+
self.receipts_root.tree_hash_root().0,
102+
self.logs_bloom.tree_hash_root().0,
103+
self.prev_randao.tree_hash_root().0,
104+
self.block_number.tree_hash_root().0,
105+
self.gas_limit.tree_hash_root().0,
106+
self.gas_used.tree_hash_root().0,
107+
self.timestamp.tree_hash_root().0,
108+
self.extra_data.tree_hash_root().0,
109+
self.base_fee_per_gas.tree_hash_root().0,
110+
self.block_hash.tree_hash_root().0,
111+
self.transactions.tree_hash_root().0,
112+
self.withdrawals.tree_hash_root().0,
113+
self.blob_gas_used.tree_hash_root().0,
114+
self.excess_blob_gas.tree_hash_root().0,
115+
];
116+
build_merkle_proof_for_index(leaves, 12)
117+
}
118+
}
119+
95120
impl ExecutionPayloadCapella {
96121
pub fn build_block_hash_proof(&self) -> Vec<B256> {
97122
let leaves = vec![

0 commit comments

Comments
 (0)