Skip to content

Commit 4c7897d

Browse files
authored
Add ephemeral history gossiper (#1851)
1 parent aa17f0a commit 4c7897d

File tree

7 files changed

+479
-2
lines changed

7 files changed

+479
-2
lines changed

Cargo.lock

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

bin/portal-bridge/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ ssz_types.workspace = true
3636
thiserror.workspace = true
3737
tokio.workspace = true
3838
tracing.workspace = true
39+
tree_hash.workspace = true
3940
trin.workspace = true
4041
trin-beacon.workspace = true
4142
trin-history.workspace = true

bin/portal-bridge/src/bridge/e2hs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ impl Gossiper {
366366
content_key: HistoryContentKey,
367367
content_value: HistoryContentValue,
368368
) -> JoinHandle<Vec<OfferTrace>> {
369-
let executor = self.clone();
370-
tokio::spawn(async move { executor.gossip_content(content_key, content_value).await })
369+
let gossiper = self.clone();
370+
tokio::spawn(async move { gossiper.gossip_content(content_key, content_value).await })
371371
}
372372

373373
/// Spawn individual offer tasks for each interested enr found in Census.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// todo: remove once ephemeral history bridge is added
2+
#![allow(dead_code)]
3+
4+
use alloy::{
5+
consensus::{BlockBody as AlloyBlockBody, Header},
6+
rpc::types::{Withdrawal, Withdrawals},
7+
};
8+
use anyhow::ensure;
9+
use ethportal_api::{
10+
consensus::beacon_block::BeaconBlockElectra,
11+
types::execution::builders::{block::decode_transactions, header::ExecutionHeaderBuilder},
12+
BlockBody, Receipts,
13+
};
14+
use revm_primitives::B256;
15+
use tree_hash::TreeHash;
16+
17+
/// The container for Ephemeral headers to be gossiped together.
18+
///
19+
/// It's initialized with beacon block root of the head of the chain, and first added block must
20+
/// correspond to it. Afterwards, each added block must be the parent of the previous. This
21+
/// way, we create reverse chain of blocks.
22+
pub struct EphemeralBundle {
23+
pub head_beacon_block_root: B256,
24+
pub blocks: Vec<(Header, BlockBody, Receipts)>,
25+
}
26+
27+
impl EphemeralBundle {
28+
pub fn new(head_beacon_block_root: B256) -> Self {
29+
Self {
30+
head_beacon_block_root,
31+
blocks: vec![],
32+
}
33+
}
34+
35+
fn next_parent_hash(&self) -> B256 {
36+
self.blocks
37+
.last()
38+
.map(|(header, ..)| {
39+
header
40+
.parent_beacon_block_root
41+
.expect("This bridge only supports post Electra")
42+
})
43+
.unwrap_or(self.head_beacon_block_root)
44+
}
45+
46+
pub fn push_parent(
47+
&mut self,
48+
beacon_block: BeaconBlockElectra,
49+
receipts: Receipts,
50+
) -> anyhow::Result<()> {
51+
ensure!(
52+
self.next_parent_hash() == beacon_block.tree_hash_root(),
53+
"Beacon block root does not match the expected parent hash"
54+
);
55+
let payload = &beacon_block.body.execution_payload;
56+
let transactions =
57+
decode_transactions(&payload.transactions).expect("Failed to decode transactions");
58+
let withdrawals = payload
59+
.withdrawals
60+
.iter()
61+
.map(Withdrawal::from)
62+
.collect::<Vec<_>>();
63+
let header = ExecutionHeaderBuilder::electra(
64+
payload,
65+
beacon_block.parent_root,
66+
&transactions,
67+
&withdrawals,
68+
&beacon_block.body.execution_requests,
69+
)
70+
.expect("Failed to build header");
71+
72+
let block_body = BlockBody(AlloyBlockBody {
73+
transactions,
74+
ommers: vec![],
75+
withdrawals: Some(Withdrawals::new(withdrawals)),
76+
});
77+
78+
self.blocks.push((header, block_body, receipts));
79+
80+
Ok(())
81+
}
82+
}

0 commit comments

Comments
 (0)