Skip to content

Commit

Permalink
feat: support multiple network MAINNET/TESTNET etc
Browse files Browse the repository at this point in the history
  • Loading branch information
KolbyML committed Apr 12, 2024
1 parent e221740 commit e34e9b6
Show file tree
Hide file tree
Showing 19 changed files with 254 additions and 99 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ethportal-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ alloy-primitives = { version = "0.7.0", features = ["ssz"] }
alloy-rlp = "0.3.4"
anyhow = "1.0.68"
base64 = "0.13.0"
bimap = "0.6.3"
bytes = "1.3.0"
clap = { version = "4.2.1", features = ["derive"] }
const_format = {version = "0.2.0", features = ["rust_1_64"]}
Expand All @@ -31,6 +32,7 @@ jsonrpsee = {version="0.20.0", features = ["async-client", "client", "macros", "
keccak-hash = "0.10.0"
lazy_static = "1.4.0"
nanotemplate = "0.3.0"
once_cell = "1.17"
quickcheck = "1.0.3"
rand = "0.8.5"
reth-rpc-types = { rev = "8d1d13ef89cf19459adc37ba0c45e7aac6270dc1", git = "https://github.com/paradigmxyz/reth.git"}
Expand Down
30 changes: 25 additions & 5 deletions ethportal-api/src/types/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use clap::{
error::{Error, ErrorKind},
Args, Parser, Subcommand,
};
use std::{env, ffi::OsString, fmt, net::SocketAddr, path::PathBuf, str::FromStr};
use std::{env, ffi::OsString, fmt, net::SocketAddr, path::PathBuf, str::FromStr, sync::Arc};
use trin_utils::build_info;
use url::Url;

Expand All @@ -21,11 +21,14 @@ pub const BEACON_NETWORK: &str = "beacon";
pub const HISTORY_NETWORK: &str = "history";
pub const STATE_NETWORK: &str = "state";
const DEFAULT_SUBNETWORKS: &str = "history";
const DEFAULT_NETWORK: &str = "mainnet";
pub const DEFAULT_STORAGE_CAPACITY_MB: &str = "100";
pub const DEFAULT_WEB3_TRANSPORT: &str = "ipc";

use crate::dashboard::grafana::{GrafanaAPI, DASHBOARD_TEMPLATES};

use super::portal_wire::{NetworkSpec, MAINNET, TESTNET};

#[derive(Debug, PartialEq, Clone)]
pub enum Web3TransportType {
HTTP,
Expand Down Expand Up @@ -147,12 +150,20 @@ pub struct TrinConfig {
pub trusted_block_root: Option<String>,

#[arg(
long = "networks",
long = "portal-subnetworks",
help = "Comma-separated list of which portal subnetworks to activate",
default_value = DEFAULT_SUBNETWORKS,
use_value_delimiter = true
)]
pub networks: Vec<String>,
pub portal_subnetworks: Vec<String>,

#[arg(
long = "network",
help = "Choose mainnet or testnet",
default_value = DEFAULT_NETWORK,
value_parser = network_parser
)]
pub network: Arc<NetworkSpec>,

/// Storage capacity specified in megabytes.
#[arg(
Expand Down Expand Up @@ -225,7 +236,7 @@ impl Default for TrinConfig {
no_upnp: false,
private_key: None,
trusted_block_root: None,
networks: DEFAULT_SUBNETWORKS
portal_subnetworks: DEFAULT_SUBNETWORKS
.split(',')
.map(|n| n.to_string())
.collect(),
Expand All @@ -240,6 +251,7 @@ impl Default for TrinConfig {
ws_port: DEFAULT_WEB3_WS_PORT,
command: None,
utp_transfer_limit: DEFAULT_UTP_TRANSFER_LIMIT,
network: MAINNET.clone(),
}
}
}
Expand Down Expand Up @@ -299,6 +311,14 @@ pub fn check_private_key_length(private_key: &str) -> Result<B256, String> {
))
}

fn network_parser(network_string: &str) -> Result<Arc<NetworkSpec>, String> {
match network_string {
"mainnet" => Ok(MAINNET.clone()),
"testnet" => Ok(TESTNET.clone()),
_ => Err(format!("Not a valid network: {network_string}")),
}
}

fn check_trusted_block_root(trusted_root: &str) -> Result<String, String> {
if !trusted_root.starts_with("0x") {
return Err("Trusted block root must be prefixed with 0x".to_owned());
Expand All @@ -324,7 +344,7 @@ impl fmt::Display for TrinConfig {
write!(
f,
"TrinConfig {{ networks: {:?}, capacity_mb: {}, ephemeral: {}, json_rpc_url: {}, metrics_enabled: {} }}",
self.networks, self.mb, self.ephemeral, json_rpc_url, self.enable_metrics_with_url.is_some()
self.portal_subnetworks, self.mb, self.ephemeral, json_rpc_url, self.enable_metrics_with_url.is_some()
)
}
}
Expand Down
66 changes: 43 additions & 23 deletions ethportal-api/src/types/portal_wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ use std::{
convert::{TryFrom, TryInto},
fmt,
ops::Deref,
str::FromStr,
sync::Arc,
};

use alloy_primitives::U256;
use bimap::BiHashMap;
use once_cell::sync::Lazy;
use rlp::Encodable;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
Expand Down Expand Up @@ -164,7 +166,7 @@ pub enum ProtocolIdError {
}

/// Protocol identifiers
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum ProtocolId {
State,
History,
Expand All @@ -174,22 +176,41 @@ pub enum ProtocolId {
Utp,
}

/// Encode hex string to protocol id
impl FromStr for ProtocolId {
type Err = ProtocolIdError;

fn from_str(input: &str) -> Result<ProtocolId, Self::Err> {
match input {
"0x500A" => Ok(ProtocolId::State),
"0x500B" => Ok(ProtocolId::History),
"0x500C" => Ok(ProtocolId::TransactionGossip),
"0x500D" => Ok(ProtocolId::CanonicalIndices),
"0x501A" => Ok(ProtocolId::Beacon),
"0x757470" => Ok(ProtocolId::Utp),
_ => Err(ProtocolIdError::Invalid),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct NetworkSpec {
pub network_name: String,
pub portal_networks: BiHashMap<ProtocolId, String>,
}

pub static MAINNET: Lazy<Arc<NetworkSpec>> = Lazy::new(|| {
let mut portal_networks = BiHashMap::new();
portal_networks.insert(ProtocolId::State, "0x500A".to_string());
portal_networks.insert(ProtocolId::History, "0x500B".to_string());
portal_networks.insert(ProtocolId::TransactionGossip, "0x500C".to_string());
portal_networks.insert(ProtocolId::CanonicalIndices, "0x500D".to_string());
portal_networks.insert(ProtocolId::Beacon, "0x501A".to_string());
portal_networks.insert(ProtocolId::Utp, "0x757470".to_string());
NetworkSpec {
portal_networks,
network_name: "mainnet".to_string(),
}
.into()
});

pub static TESTNET: Lazy<Arc<NetworkSpec>> = Lazy::new(|| {
let mut portal_networks = BiHashMap::new();
portal_networks.insert(ProtocolId::State, "0x501A".to_string());
portal_networks.insert(ProtocolId::History, "0x501B".to_string());
portal_networks.insert(ProtocolId::TransactionGossip, "0x501C".to_string());
portal_networks.insert(ProtocolId::CanonicalIndices, "0x501D".to_string());
portal_networks.insert(ProtocolId::Beacon, "0x502A".to_string());
portal_networks.insert(ProtocolId::Utp, "0x757470".to_string());
NetworkSpec {
portal_networks,
network_name: "testnet".to_string(),
}
.into()
});

impl fmt::Display for ProtocolId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -590,21 +611,20 @@ impl From<Accept> for Value {
#[allow(clippy::unwrap_used)]
mod test {
use super::*;
use crate::utils::bytes::hex_encode_upper;
use std::str::FromStr;
use test_log::test;

#[test]
#[should_panic]
fn protocol_id_invalid() {
let hex = "0x500F";
ProtocolId::from_str(hex).unwrap();
assert!(!MAINNET.portal_networks.contains_right(hex));
}

#[test]
fn protocol_id_encoding() {
let hex = "0x500A";
let protocol_id = ProtocolId::from_str(hex).unwrap();
let expected_hex = hex_encode_upper(Vec::try_from(protocol_id).unwrap());
let protocol_id = MAINNET.portal_networks.get_by_right(hex).unwrap();
let expected_hex = MAINNET.portal_networks.get_by_left(protocol_id).unwrap();
assert_eq!(hex, expected_hex);
}

Expand Down
4 changes: 2 additions & 2 deletions ethportal-peertest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn generate_trin_config(id: u16, bootnode_enr: Option<&Enr>) -> TrinConfig {
let web3_ipc_path_str = web3_ipc_path.as_path().display().to_string();
let trin_config_args = vec![
"trin",
"--networks",
"--portal-subnetworks",
"history,beacon,state",
"--external-address",
external_addr.as_str(),
Expand All @@ -101,7 +101,7 @@ fn generate_trin_config(id: u16, bootnode_enr: Option<&Enr>) -> TrinConfig {
let web3_ipc_path_str = web3_ipc_path.as_path().display().to_string();
let trin_config_args = vec![
"trin",
"--networks",
"--portal-subnetworks",
"history,beacon,state",
"--external-address",
external_addr.as_str(),
Expand Down
8 changes: 8 additions & 0 deletions ethportal-peertest/src/scenarios/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ pub async fn test_ping(protocol: ProtocolId, target: &Client, peertest: &Peertes
assert_eq!(result.enr_seq, 1);
}

pub async fn test_ping_cross_network(target: &Client, peertest: &Peertest) {
info!("Testing ping for history cross mainnet and testnet discv5 protocol id");
let bootnode_enr = peertest.bootnode.enr.clone();
if let Ok(pong) = HistoryNetworkApiClient::ping(target, bootnode_enr).await {
panic!("Expected ping to fail as mainnet/testnet history nodes shouldn't be able to communicate {pong:?}");
};
}

pub async fn test_find_nodes(protocol: ProtocolId, target: &Client, peertest: &Peertest) {
info!("Testing find_nodes for {protocol}");
let bootnode_enr = peertest.bootnode.enr.clone();
Expand Down
2 changes: 1 addition & 1 deletion ethportal-peertest/src/scenarios/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub async fn test_gossip_with_trace(peertest: &Peertest, target: &Client) {
let trin_config = TrinConfig::new_from(
[
"trin",
"--networks",
"--portal-subnetworks",
"history,state",
"--external-address",
external_addr.as_str(),
Expand Down
2 changes: 1 addition & 1 deletion portal-bridge/src/client_handles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn trin_handle(
.args(["--ephemeral"])
.args(["--mb", "0"])
.args(["--web3-transport", "http"])
.args(["--networks", &networks])
.args(["--portal-subnetworks", &networks])
.args(["--unsafe-private-key", &private_key])
.args([
"--web3-http-address",
Expand Down
Loading

0 comments on commit e34e9b6

Please sign in to comment.