Skip to content

Commit 47fa171

Browse files
authored
feat(trin-execution): replace EraManager with E2HSManager (#1855)
1 parent 7f71cc2 commit 47fa171

File tree

25 files changed

+270
-329
lines changed

25 files changed

+270
-329
lines changed

Cargo.lock

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

bin/e2hs-writer/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ futures.workspace = true
2727
humanize-duration.workspace = true
2828
reqwest.workspace = true
2929
rstest.workspace = true
30+
revm-primitives.workspace = true
3031
serde_yaml.workspace = true
3132
ssz_types.workspace = true
3233
tempfile.workspace = true
3334
tokio.workspace = true
3435
tracing.workspace = true
3536
tree_hash.workspace = true
37+
trin-evm.workspace = true
3638
trin-execution.workspace = true
3739
trin-utils.workspace = true
3840
trin-validation.workspace = true

bin/trin-execution/src/era/binary_search.rs renamed to bin/e2hs-writer/src/subcommands/single_generator/era_binary_search.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ use ethportal_api::consensus::constants::SLOTS_PER_HISTORICAL_ROOT;
88
use reqwest::Client;
99
use revm_primitives::hardfork::SpecId;
1010
use trin_evm::spec_id::get_spec_block_number;
11+
use trin_execution::e2hs::utils::download_raw_e2store_file;
1112

12-
use super::{constants::FIRST_ERA_EPOCH_WITH_EXECUTION_PAYLOAD, utils::download_raw_era};
13+
const FIRST_ERA_EPOCH_WITH_EXECUTION_PAYLOAD: u64 = 574;
1314

14-
pub struct EraBinarySearch {}
15+
pub struct EraBinarySearch;
1516

1617
impl EraBinarySearch {
1718
/// For era files there isn't really a good way to know which era file has the block we want,
@@ -50,7 +51,7 @@ impl EraBinarySearch {
5051
// mid plus 1 so we just manually check the last era file
5152
if mid + 1 > last_epoch_index {
5253
let era_to_check =
53-
download_raw_era(era_links[&(mid)].clone(), http_client.clone()).await?;
54+
download_raw_e2store_file(era_links[&mid].clone(), http_client.clone()).await?;
5455

5556
let decoded_era = Era::deserialize(&era_to_check)?;
5657
if decoded_era.contains(block_number) {
@@ -76,7 +77,7 @@ impl EraBinarySearch {
7677
|| (mid_block_number..mid_plus_one_block_number).contains(&block_number)
7778
{
7879
let era_to_check =
79-
download_raw_era(era_links[&(mid)].clone(), http_client.clone()).await?;
80+
download_raw_e2store_file(era_links[&mid].clone(), http_client.clone()).await?;
8081

8182
let decoded_era = Era::deserialize(&era_to_check)?;
8283
if decoded_era.contains(block_number) {

bin/e2hs-writer/src/subcommands/single_generator/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod e2hs_builder;
2+
mod era_binary_search;
23
mod provider;
34

45
use std::time::Instant;

bin/e2hs-writer/src/subcommands/single_generator/provider.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use reqwest::{
2020
Client,
2121
};
2222
use tracing::info;
23-
use trin_execution::era::binary_search::EraBinarySearch;
23+
24+
use crate::subcommands::single_generator::era_binary_search::EraBinarySearch;
2425

2526
pub enum EraSource {
2627
// processed era1 file

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl StateBridge {
263263
trin_execution: &mut TrinExecution,
264264
) -> anyhow::Result<()> {
265265
let block_hash = trin_execution
266-
.era_manager
266+
.e2hs_manager
267267
.lock()
268268
.await
269269
.last_fetched_block()

bin/trin-execution/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Currently the main priority is executing to the head of the chain so we can goss
99

1010
## How to run
1111
```bash
12-
cargo run -p trin-execution
12+
cargo run --release -p trin-execution
1313
```
1414

1515
### Want to get a trace of the EVM's execution?

bin/trin-execution/src/era/beacon.rs renamed to bin/trin-execution/src/e2hs/beacon.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ mod tests {
137137
};
138138
use ethportal_api::consensus::{beacon_block::SignedBeaconBlock, fork::ForkName};
139139

140-
use crate::era::beacon::ProcessBeaconBlock;
140+
use crate::e2hs::beacon::ProcessBeaconBlock;
141141

142142
#[tokio::test]
143143
async fn process_beacon_block() {
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
use std::collections::HashMap;
2+
3+
use anyhow::{anyhow, bail, ensure};
4+
use e2store::{e2hs::E2HSMemory, utils::get_e2hs_files};
5+
use reqwest::{
6+
header::{HeaderMap, HeaderValue, CONTENT_TYPE},
7+
Client,
8+
};
9+
use tokio::task::JoinHandle;
10+
use tracing::info;
11+
12+
use super::{
13+
types::{ProcessedBlock, ProcessedE2HS},
14+
utils::download_and_processed_e2hs_file,
15+
};
16+
17+
pub struct E2HSManager {
18+
next_block_number: u64,
19+
current_e2hs: Option<ProcessedE2HS>,
20+
next_e2hs: Option<JoinHandle<anyhow::Result<ProcessedE2HS>>>,
21+
http_client: Client,
22+
e2hs_files: HashMap<u64, String>,
23+
}
24+
25+
impl E2HSManager {
26+
pub async fn new(next_block_number: u64) -> anyhow::Result<Self> {
27+
let http_client = Client::builder()
28+
.default_headers(HeaderMap::from_iter([(
29+
CONTENT_TYPE,
30+
HeaderValue::from_static("application/xml"),
31+
)]))
32+
.build()?;
33+
let e2hs_files = get_e2hs_files(&http_client).await?;
34+
35+
let mut e2hs_manager = Self {
36+
next_block_number,
37+
current_e2hs: None,
38+
next_e2hs: None,
39+
http_client,
40+
e2hs_files,
41+
};
42+
43+
// initialize the next e2hs file
44+
// The first time using e2hs_manager we need to find the current e2hs file we are starting
45+
// from If the block is from a e2hs file we will need to binary search to find which
46+
// e2hs file contains the block we want
47+
let e2hs_files = e2hs_manager.e2hs_files.clone();
48+
let http_client = e2hs_manager.http_client.clone();
49+
e2hs_manager.next_e2hs = Some(tokio::spawn(async move {
50+
Self::fetch_processed_e2hs_by_block_number(e2hs_files, http_client, next_block_number)
51+
.await
52+
}));
53+
54+
Ok(e2hs_manager)
55+
}
56+
57+
pub fn next_block_number(&self) -> u64 {
58+
self.next_block_number
59+
}
60+
61+
pub async fn last_fetched_block(&self) -> anyhow::Result<&ProcessedBlock> {
62+
let Some(current_e2hs) = &self.current_e2hs else {
63+
panic!("current_e2hs should always be present, perhaps it wasn't initialized in E2HSManager::new()?");
64+
};
65+
ensure!(
66+
self.next_block_number > 0,
67+
"next_block_number should be greater than 0"
68+
);
69+
current_e2hs
70+
.get_block(self.next_block_number - 1)
71+
.ok_or_else(|| {
72+
anyhow!(
73+
"No block found for next_block_number: {}",
74+
self.next_block_number - 1
75+
)
76+
})
77+
}
78+
79+
pub async fn get_next_block(&mut self) -> anyhow::Result<&ProcessedBlock> {
80+
let processed_e2hs = match &self.current_e2hs {
81+
Some(processed_e2hs) if processed_e2hs.contains_block(self.next_block_number) => {
82+
self.current_e2hs.as_ref().expect("current_e2hs to be some")
83+
}
84+
_ => {
85+
let current_e2hs = self.get_next_processed_e2hs().await?;
86+
self.current_e2hs.insert(current_e2hs)
87+
}
88+
};
89+
ensure!(
90+
processed_e2hs.contains_block(self.next_block_number),
91+
"Block not found in e2hs file"
92+
);
93+
let block = processed_e2hs
94+
.get_block(self.next_block_number)
95+
.ok_or_else(|| {
96+
anyhow!(
97+
"No block found for next_block_number: {}",
98+
self.next_block_number
99+
)
100+
})?;
101+
self.next_block_number += 1;
102+
103+
Ok(block)
104+
}
105+
106+
/// gets the next e2hs file and processes it, and starts fetching the next one in the background
107+
async fn get_next_processed_e2hs(&mut self) -> anyhow::Result<ProcessedE2HS> {
108+
info!("Fetching the next e2hs file");
109+
110+
// Since E2HSManager is initialized in new(), next_e2hs should never be none
111+
let new_current_e2hs = match self.next_e2hs.take() {
112+
Some(e2hs_handle) => e2hs_handle.await??,
113+
None => bail!("The next_e2hs handle can't be None"),
114+
};
115+
116+
// Download the next e2hs file
117+
let next_e2hs_index = new_current_e2hs.index + 1;
118+
let next_e2hs_path = self.e2hs_files.get(&next_e2hs_index).cloned();
119+
let http_client = self.http_client.clone();
120+
let join_handle = tokio::spawn(async move {
121+
let Some(next_e2hs_path) = next_e2hs_path else {
122+
bail!("Unable to find next e2hs file's path: index {next_e2hs_index}");
123+
};
124+
download_and_processed_e2hs_file(next_e2hs_path, http_client.clone()).await
125+
});
126+
self.next_e2hs = Some(join_handle);
127+
128+
Ok(new_current_e2hs)
129+
}
130+
131+
async fn fetch_processed_e2hs_by_block_number(
132+
e2hs_files: HashMap<u64, String>,
133+
http_client: Client,
134+
block_number: u64,
135+
) -> anyhow::Result<ProcessedE2HS> {
136+
let e2hs_index = E2HSMemory::index_from_block_number(block_number);
137+
let Some(e2hs_path) = e2hs_files.get(&e2hs_index).cloned() else {
138+
bail!("Unable to find e2hs file's path during initialization: index {e2hs_index}");
139+
};
140+
download_and_processed_e2hs_file(e2hs_path, http_client.clone()).await
141+
}
142+
}
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
pub mod beacon;
2-
pub mod binary_search;
3-
pub mod constants;
42
pub mod manager;
53
pub mod types;
64
pub mod utils;

0 commit comments

Comments
 (0)