Skip to content

Commit eb04d28

Browse files
committed
feat: add census with peer scoring to downloader
1 parent 3d94460 commit eb04d28

File tree

7 files changed

+82
-22
lines changed

7 files changed

+82
-22
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ethportal-api/src/types/query_trace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl QueryTrace {
123123
}
124124

125125
/// Returns milliseconds since the time provided.
126-
fn timestamp_millis_u64(since: u64) -> u64 {
126+
pub fn timestamp_millis_u64(since: u64) -> u64 {
127127
// Convert `since` (milliseconds) to a `SystemTime`
128128
let since_time = UNIX_EPOCH + Duration::from_millis(since);
129129

portal-bridge/src/census/mod.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use thiserror::Error;
1111
use tokio::task::JoinHandle;
1212
use tracing::{error, info, Instrument};
1313

14-
use crate::cli::BridgeConfig;
14+
use crate::cli::ClientType;
1515

1616
mod network;
1717
mod peer;
@@ -51,11 +51,30 @@ impl Census {
5151
const SUPPORTED_SUBNETWORKS: [Subnetwork; 3] =
5252
[Subnetwork::Beacon, Subnetwork::History, Subnetwork::State];
5353

54-
pub fn new(client: HttpClient, bridge_config: &BridgeConfig) -> Self {
54+
pub fn new(
55+
client: HttpClient,
56+
enr_offer_limit: usize,
57+
filter_clients: Vec<ClientType>,
58+
) -> Self {
5559
Self {
56-
history: Network::new(client.clone(), Subnetwork::History, bridge_config),
57-
state: Network::new(client.clone(), Subnetwork::State, bridge_config),
58-
beacon: Network::new(client.clone(), Subnetwork::Beacon, bridge_config),
60+
history: Network::new(
61+
client.clone(),
62+
Subnetwork::History,
63+
enr_offer_limit,
64+
filter_clients.clone(),
65+
),
66+
state: Network::new(
67+
client.clone(),
68+
Subnetwork::State,
69+
enr_offer_limit,
70+
filter_clients.clone(),
71+
),
72+
beacon: Network::new(
73+
client.clone(),
74+
Subnetwork::Beacon,
75+
enr_offer_limit,
76+
filter_clients,
77+
),
5978
initialized: false,
6079
}
6180
}

portal-bridge/src/census/network.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ use super::{
2020
peers::Peers,
2121
scoring::{AdditiveWeight, PeerSelector},
2222
};
23-
use crate::{
24-
census::CensusError,
25-
cli::{BridgeConfig, ClientType},
26-
};
23+
use crate::{census::CensusError, cli::ClientType};
2724

2825
/// The result of the liveness check.
2926
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -78,7 +75,12 @@ pub(super) struct Network {
7875
}
7976

8077
impl Network {
81-
pub fn new(client: HttpClient, subnetwork: Subnetwork, bridge_config: &BridgeConfig) -> Self {
78+
pub fn new(
79+
client: HttpClient,
80+
subnetwork: Subnetwork,
81+
enr_offer_limit: usize,
82+
filter_clients: Vec<ClientType>,
83+
) -> Self {
8284
if !matches!(
8385
subnetwork,
8486
Subnetwork::History | Subnetwork::Beacon | Subnetwork::State
@@ -89,11 +91,11 @@ impl Network {
8991
Self {
9092
peers: Peers::new(PeerSelector::new(
9193
AdditiveWeight::default(),
92-
bridge_config.enr_offer_limit,
94+
enr_offer_limit,
9395
)),
9496
client,
9597
subnetwork,
96-
filter_clients: bridge_config.filter_clients.to_vec(),
98+
filter_clients,
9799
}
98100
}
99101

portal-bridge/src/main.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
4949
.contains(&Subnetwork::State)
5050
{
5151
// Create and initialize the census to acquire critical view of network before gossiping
52-
let mut census = Census::new(portal_client.clone(), &bridge_config);
52+
let mut census = Census::new(
53+
portal_client.clone(),
54+
bridge_config.enr_offer_limit,
55+
bridge_config.filter_clients,
56+
);
5357
census_handle = Some(census.init([Subnetwork::State]).await?);
5458

5559
let state_bridge = StateBridge::new(

trin-history/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ tree_hash.workspace = true
2626
trin-storage.workspace = true
2727
trin-validation.workspace = true
2828
utp-rs.workspace = true
29+
portal-bridge.workspace = true
2930
futures = "0.3.31"
3031

3132
[dev-dependencies]

trin-history/src/downloader.rs

+41-8
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,49 @@ use std::fs::File;
77
use std::{
88
io::{self, BufRead},
99
path::Path,
10+
time::Duration,
1011
};
1112

1213
use anyhow::anyhow;
1314
use ethportal_api::{
14-
utils::bytes::hex_decode, BlockBodyKey, BlockReceiptsKey, ContentValue, HistoryContentKey,
15-
HistoryContentValue,
15+
jsonrpsee::http_client::{HttpClient, HttpClientBuilder},
16+
types::{cli::DEFAULT_WEB3_HTTP_ADDRESS, network::Subnetwork, query_trace::QueryTrace},
17+
utils::bytes::hex_decode,
18+
BlockBodyKey, BlockReceiptsKey, ContentValue, HistoryContentKey, HistoryContentValue,
1619
};
1720
use futures::{channel::oneshot, future::join_all};
18-
use portalnet::overlay::command::OverlayCommand;
21+
use portal_bridge::census::Census;
22+
use portalnet::overlay::{command::OverlayCommand, config::FindContentConfig};
1923
use tokio::sync::mpsc::UnboundedSender;
2024
use tracing::{error, info, warn};
2125

2226
/// The number of blocks to download in a single batch.
23-
const BATCH_SIZE: usize = 40;
27+
const BATCH_SIZE: usize = 3;
2428
/// The path to the CSV file with block numbers and block hashes.
2529
const CSV_PATH: &str = "ethereum_blocks_14000000_merge.csv";
2630

2731
#[derive(Clone)]
2832
pub struct Downloader {
33+
pub census: Census,
2934
pub overlay_tx: UnboundedSender<OverlayCommand<HistoryContentKey>>,
3035
}
3136

3237
impl Downloader {
3338
pub fn new(overlay_tx: UnboundedSender<OverlayCommand<HistoryContentKey>>) -> Self {
34-
Self { overlay_tx }
39+
let http_client: HttpClient = HttpClientBuilder::default()
40+
// increase default timeout to allow for trace_gossip requests that can take a long
41+
// time
42+
.request_timeout(Duration::from_secs(120))
43+
.build(DEFAULT_WEB3_HTTP_ADDRESS)
44+
.map_err(|e| e.to_string())
45+
.expect("Failed to build http client");
46+
47+
// BUild hhtp client binded to the current node web3rpc
48+
let census = Census::new(http_client, 0, vec![]);
49+
Self { overlay_tx, census }
3550
}
3651

37-
pub async fn start(self) -> io::Result<()> {
52+
pub async fn start(mut self) -> io::Result<()> {
3853
// set the csv path to a file in the root trin-history directory
3954
info!("Opening CSV file");
4055
let csv_path = Path::new(CSV_PATH);
@@ -47,6 +62,14 @@ impl Downloader {
4762
// skip the header of the csv file
4863
let lines = &lines[1..];
4964
let blocks: Vec<(u64, String)> = lines.iter().map(|line| parse_line(line)).collect();
65+
// Initialize the census with the history subnetwork
66+
let _ = Some(
67+
self.census
68+
.init([Subnetwork::History])
69+
.await
70+
.expect("Failed to initialize Census"),
71+
);
72+
5073
info!("Processing blocks");
5174
let batches = blocks.chunks(BATCH_SIZE);
5275

@@ -91,7 +114,10 @@ impl Downloader {
91114
let overlay_command = OverlayCommand::FindContentQuery {
92115
target: content_key.clone(),
93116
callback: tx,
94-
config: Default::default(),
117+
config: FindContentConfig {
118+
is_trace: true,
119+
..Default::default()
120+
},
95121
};
96122

97123
if let Err(err) = self.overlay_tx.send(overlay_command) {
@@ -104,7 +130,14 @@ impl Downloader {
104130
Ok(result) => match result {
105131
Ok(result) => {
106132
HistoryContentValue::decode(&content_key, &result.0)?;
107-
info!(block_number = block_number, "Downloaded content for block");
133+
let duration_ms = QueryTrace::timestamp_millis_u64(
134+
result.2.expect("QueryTrace not found").started_at_ms,
135+
);
136+
info!(
137+
block_number = block_number,
138+
query_duration = duration_ms,
139+
"Downloaded content for block"
140+
);
108141
Ok(())
109142
}
110143
Err(err) => {

0 commit comments

Comments
 (0)