diff --git a/Cargo.lock b/Cargo.lock index 178d71897..68f3255b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7014,6 +7014,7 @@ dependencies = [ "ethportal-api", "ethportal-peertest", "jsonrpsee", + "lazy_static", "parking_lot 0.11.2", "portalnet", "prometheus_exporter", diff --git a/Cargo.toml b/Cargo.toml index 7705f769e..f4432178d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ eth2_ssz = "0.4.0" ethereum-types = "0.12.1" ethportal-api = { path = "ethportal-api" } jsonrpsee = "0.20.0" +lazy_static = "1.4.0" parking_lot = "0.11.2" portalnet = { path = "portalnet" } prometheus_exporter = "0.8.4" diff --git a/book/src/users/monitoring.md b/book/src/users/monitoring.md index e639f88d8..d7dc0ea06 100644 --- a/book/src/users/monitoring.md +++ b/book/src/users/monitoring.md @@ -266,6 +266,12 @@ cargo run -p trin -- \ --web3-transport http ``` +### Updating metrics dashboard +If there are new changes to the metrics dashboard template that you want to view in +an already-existing dashboard. The simplest way to update your dashboard is to delete +your `prometheus` datasource and `Trin App metrics` dashboard, and re-run the +`create-dashboard` command. + ### View metrics remotely Trin metrics on a remote machine can be monitored by listening to the grafana address on a local machine. diff --git a/ethportal-api/src/dashboard/grafana.rs b/ethportal-api/src/dashboard/grafana.rs index 38f5cc2eb..45f5ce24a 100644 --- a/ethportal-api/src/dashboard/grafana.rs +++ b/ethportal-api/src/dashboard/grafana.rs @@ -12,6 +12,8 @@ pub struct GrafanaAPI { address: String, } +// todo: automatically update datasource/dashboard via `create-dashboard` command +// rather than deleting and recreating them impl GrafanaAPI { pub fn new(username: String, password: String, address: String) -> Self { let basic_auth_string = format!("{username}:{password}"); diff --git a/portalnet/src/config.rs b/portalnet/src/config.rs new file mode 100644 index 000000000..e6666704a --- /dev/null +++ b/portalnet/src/config.rs @@ -0,0 +1,52 @@ +use std::net::SocketAddr; + +use ethereum_types::H256; + +use ethportal_api::types::bootnodes::Bootnodes; +use ethportal_api::types::cli::TrinConfig; +use ethportal_api::types::distance::Distance; + +/// Capacity of the cache for observed `NodeAddress` values. +/// Provides capacity for 32 full k-buckets. This capacity will be shared among all active portal +/// subnetworks. +const NODE_ADDR_CACHE_CAPACITY: usize = discv5::kbucket::MAX_NODES_PER_BUCKET * 32; + +#[derive(Clone)] +pub struct PortalnetConfig { + pub external_addr: Option, + pub private_key: H256, + pub listen_port: u16, + pub bootnodes: Bootnodes, + pub data_radius: Distance, + pub internal_ip: bool, + pub no_stun: bool, + pub node_addr_cache_capacity: usize, +} + +impl Default for PortalnetConfig { + fn default() -> Self { + Self { + external_addr: None, + private_key: H256::random(), + listen_port: 4242, + bootnodes: Bootnodes::default(), + data_radius: Distance::MAX, + internal_ip: false, + no_stun: false, + node_addr_cache_capacity: NODE_ADDR_CACHE_CAPACITY, + } + } +} + +impl PortalnetConfig { + pub fn new(trin_config: &TrinConfig, private_key: H256) -> Self { + Self { + external_addr: trin_config.external_addr, + private_key, + listen_port: trin_config.discovery_port, + no_stun: trin_config.no_stun, + bootnodes: trin_config.bootnodes.clone(), + ..Default::default() + } + } +} diff --git a/portalnet/src/discovery.rs b/portalnet/src/discovery.rs index c28df5b25..38a7df530 100644 --- a/portalnet/src/discovery.rs +++ b/portalnet/src/discovery.rs @@ -1,5 +1,9 @@ -use super::types::messages::{PortalnetConfig, ProtocolId}; -use crate::socket; +use std::hash::{Hash, Hasher}; +use std::net::Ipv4Addr; +use std::path::PathBuf; +use std::str::FromStr; +use std::{convert::TryFrom, fmt, fs, io, net::SocketAddr, sync::Arc}; + use anyhow::anyhow; use async_trait::async_trait; use bytes::BytesMut; @@ -7,23 +11,22 @@ use discv5::{ enr::{CombinedKey, EnrBuilder, NodeId}, ConfigBuilder, Discv5, Event, ListenConfig, RequestError, TalkRequest, }; -use ethportal_api::types::enr::Enr; -use ethportal_api::utils::bytes::hex_encode; -use ethportal_api::NodeInfo; use lru::LruCache; use parking_lot::RwLock; use rlp::RlpStream; use serde_json::{json, Value}; -use std::hash::{Hash, Hasher}; -use std::net::Ipv4Addr; -use std::path::PathBuf; -use std::str::FromStr; -use std::{convert::TryFrom, fmt, fs, io, net::SocketAddr, sync::Arc}; use tokio::sync::mpsc; use tracing::{debug, info, warn}; -use trin_utils::version::get_trin_version; use utp_rs::{cid::ConnectionPeer, udp::AsyncUdpSocket}; +use super::config::PortalnetConfig; +use super::types::messages::ProtocolId; +use crate::socket; +use ethportal_api::types::enr::Enr; +use ethportal_api::utils::bytes::hex_encode; +use ethportal_api::NodeInfo; +use trin_utils::version::get_trin_version; + /// Size of the buffer of the Discv5 TALKREQ channel. const TALKREQ_CHANNEL_BUFFER: usize = 100; diff --git a/portalnet/src/lib.rs b/portalnet/src/lib.rs index 8a30c1b68..aca96fedf 100644 --- a/portalnet/src/lib.rs +++ b/portalnet/src/lib.rs @@ -1,5 +1,6 @@ #![warn(clippy::unwrap_used)] +pub mod config; pub mod discovery; pub mod events; pub mod find; diff --git a/portalnet/src/metrics/mod.rs b/portalnet/src/metrics/mod.rs index f88d1a3ef..5c7887cb2 100644 --- a/portalnet/src/metrics/mod.rs +++ b/portalnet/src/metrics/mod.rs @@ -1,2 +1,4 @@ pub mod labels; pub mod overlay; +pub mod portalnet; +pub mod storage; diff --git a/portalnet/src/metrics/overlay.rs b/portalnet/src/metrics/overlay.rs index d720fe1bc..c1dca6fab 100644 --- a/portalnet/src/metrics/overlay.rs +++ b/portalnet/src/metrics/overlay.rs @@ -1,217 +1,209 @@ use prometheus_exporter::{ self, prometheus::{ - opts, register_int_counter_vec, register_int_counter_vec_with_registry, - register_int_gauge_vec, register_int_gauge_vec_with_registry, IntCounterVec, IntGaugeVec, - Opts, Registry, + opts, register_int_counter_vec_with_registry, register_int_gauge_vec_with_registry, + IntCounterVec, IntGaugeVec, Registry, }, }; -use tracing::error; use crate::metrics::labels::{ - MessageDirectionLabel, MessageLabel, ProtocolLabel, UtpDirectionLabel, UtpOutcomeLabel, + MessageDirectionLabel, MessageLabel, UtpDirectionLabel, UtpOutcomeLabel, }; -use crate::types::messages::{ProtocolId, Request, Response}; +use crate::types::messages::{Request, Response}; -/// General Metrics Strategy (wip) -/// - Each module should maintain its own metrics reporter -/// - When possible, use the lazy_static! approach -/// - - https://romankudryashov.com/blog/2021/11/monitoring-rust-web-application/ -/// - - https://github.com/sigp/lighthouse/blob/c3a793fd73a3b11b130b82032904d39c952869e4/beacon_node/lighthouse_network/src/metrics.rs - -/// Overlay Service Metrics Reporter -#[derive(Clone, Debug)] +/// Contains metrics reporters for use in the overlay network +/// (eg. `portalnet/src/overlay.rs` & `portalnet/src/overlay_service.rs`). +/// Metric types reported here include protocol messages, utp transfers, +/// and content validation. +#[derive(Clone)] pub struct OverlayMetrics { - protocol: ProtocolLabel, - message_count: IntCounterVec, - utp_outcome_count: IntCounterVec, - utp_active_count: IntGaugeVec, - validation_count: IntCounterVec, + pub message_total: IntCounterVec, + pub utp_outcome_total: IntCounterVec, + pub utp_active_gauge: IntGaugeVec, + pub validation_total: IntCounterVec, } impl OverlayMetrics { - pub fn new(protocol: &ProtocolId) -> Self { - let message_count_options = opts!( - "trin_message_total", - "count all network messages sent and received" - ); - let message_count_labels = &["protocol", "direction", "type"]; - let message_count = - OverlayMetrics::register_counter_metric(message_count_options, message_count_labels); - - let utp_outcome_count_options = opts!( - "trin_utp_outcome", - "track success rate for all utp transfers outbound and inbound" - ); - let utp_outcome_count_labels = &["protocol", "direction", "outcome"]; - let utp_outcome_count = OverlayMetrics::register_counter_metric( - utp_outcome_count_options, - utp_outcome_count_labels, - ); - - let utp_active_count_options = opts!( - "trin_utp_active", - "count all active utp transfers outbound and inbound" - ); - let utp_active_count_labels = &["protocol", "direction"]; - let utp_active_count = OverlayMetrics::register_gauge_metric( - utp_active_count_options, - utp_active_count_labels, - ); - - let validation_count_options = opts!( - "trin_validation_total", - "count all content validations successful and failed" - ); - let validation_count_labels = &["protocol", "success"]; - let validation_count = OverlayMetrics::register_counter_metric( - validation_count_options, - validation_count_labels, - ); - - Self { - protocol: protocol.into(), - message_count, - utp_outcome_count, - utp_active_count, - validation_count, - } + pub fn new(registry: &Registry) -> anyhow::Result { + let message_total = register_int_counter_vec_with_registry!( + opts!( + "trin_message_total", + "count all network messages sent and received" + ), + &["protocol", "direction", "type"], + registry + )?; + let utp_outcome_total = register_int_counter_vec_with_registry!( + opts!( + "trin_utp_outcome_total", + "track success rate for all utp transfers outbound and inbound" + ), + &["protocol", "direction", "outcome"], + registry + )?; + let utp_active_gauge = register_int_gauge_vec_with_registry!( + opts!( + "trin_utp_active_streams", + "count all active utp transfers outbound and inbound" + ), + &["protocol", "direction"], + registry + )?; + let validation_total = register_int_counter_vec_with_registry!( + opts!( + "trin_validation_total", + "count all content validations successful and failed" + ), + &["protocol", "success"], + registry + )?; + Ok(Self { + message_total, + utp_outcome_total, + utp_active_gauge, + validation_total, + }) } +} + +#[derive(Clone)] +pub struct OverlayMetricsReporter { + pub protocol: String, + pub overlay_metrics: OverlayMetrics, +} +impl OverlayMetricsReporter { // // Message Count // /// Returns the value of the given metric with the specified labels. - pub fn message_count_by_labels( + fn message_total_by_labels( &self, direction: MessageDirectionLabel, message_name: MessageLabel, ) -> u64 { - let labels = [self.protocol.into(), direction.into(), message_name.into()]; - self.message_count.with_label_values(&labels).get() + let labels: [&str; 3] = [&self.protocol, direction.into(), message_name.into()]; + self.overlay_metrics + .message_total + .with_label_values(&labels) + .get() } pub fn report_outbound_request(&self, request: &Request) { - self.increment_message_count(MessageDirectionLabel::Sent, request.into()); + self.increment_message_total(MessageDirectionLabel::Sent, request.into()); } pub fn report_inbound_request(&self, request: &Request) { - self.increment_message_count(MessageDirectionLabel::Received, request.into()); + self.increment_message_total(MessageDirectionLabel::Received, request.into()); } pub fn report_outbound_response(&self, response: &Response) { - self.increment_message_count(MessageDirectionLabel::Sent, response.into()); + self.increment_message_total(MessageDirectionLabel::Sent, response.into()); } pub fn report_inbound_response(&self, response: &Response) { - self.increment_message_count(MessageDirectionLabel::Received, response.into()); + self.increment_message_total(MessageDirectionLabel::Received, response.into()); } - fn increment_message_count(&self, direction: MessageDirectionLabel, message: MessageLabel) { - let labels = [self.protocol.into(), direction.into(), message.into()]; - self.message_count.with_label_values(&labels).inc(); + fn increment_message_total(&self, direction: MessageDirectionLabel, message: MessageLabel) { + let labels: [&str; 3] = [&self.protocol, direction.into(), message.into()]; + self.overlay_metrics + .message_total + .with_label_values(&labels) + .inc(); } // // uTP metrics // - fn utp_active_count(&self, direction: UtpDirectionLabel) -> u64 { - let labels: [&str; 2] = [self.protocol.into(), direction.into()]; - self.utp_active_count.with_label_values(&labels).get() as u64 + fn utp_active_streams(&self, direction: UtpDirectionLabel) -> u64 { + let labels: [&str; 2] = [&self.protocol, direction.into()]; + self.overlay_metrics + .utp_active_gauge + .with_label_values(&labels) + .get() as u64 } - fn utp_outcome_count(&self, direction: UtpDirectionLabel, outcome: UtpOutcomeLabel) -> u64 { - let labels: [&str; 3] = [self.protocol.into(), direction.into(), outcome.into()]; - self.utp_outcome_count.with_label_values(&labels).get() + fn utp_outcome_total(&self, direction: UtpDirectionLabel, outcome: UtpOutcomeLabel) -> u64 { + let labels: [&str; 3] = [&self.protocol, direction.into(), outcome.into()]; + self.overlay_metrics + .utp_outcome_total + .with_label_values(&labels) + .get() } pub fn report_utp_outcome(&self, direction: UtpDirectionLabel, outcome: UtpOutcomeLabel) { - let labels: [&str; 3] = [self.protocol.into(), direction.into(), outcome.into()]; - self.utp_outcome_count.with_label_values(&labels).inc(); + let labels: [&str; 3] = [&self.protocol, direction.into(), outcome.into()]; + self.overlay_metrics + .utp_outcome_total + .with_label_values(&labels) + .inc(); self.report_utp_active_dec(direction); } pub fn report_utp_active_inc(&self, direction: UtpDirectionLabel) { - let labels: [&str; 2] = [self.protocol.into(), direction.into()]; - self.utp_active_count.with_label_values(&labels).inc(); + let labels: [&str; 2] = [&self.protocol, direction.into()]; + self.overlay_metrics + .utp_active_gauge + .with_label_values(&labels) + .inc(); } pub fn report_utp_active_dec(&self, direction: UtpDirectionLabel) { - let labels: [&str; 2] = [self.protocol.into(), direction.into()]; - self.utp_active_count.with_label_values(&labels).dec(); + let labels: [&str; 2] = [&self.protocol, direction.into()]; + self.overlay_metrics + .utp_active_gauge + .with_label_values(&labels) + .dec(); } // // Validations // /// Returns the value of the given metric with the specified labels. - pub fn validation_count_by_outcome(&self, outcome: bool) -> u64 { + fn validation_total_by_outcome(&self, outcome: bool) -> u64 { let outcome = outcome.to_string(); - let labels = [self.protocol.into(), outcome.as_str()]; - self.validation_count.with_label_values(&labels).get() + let labels: [&str; 2] = [&self.protocol, outcome.as_str()]; + self.overlay_metrics + .validation_total + .with_label_values(&labels) + .get() } pub fn report_validation(&self, success: bool) { let success = success.to_string(); - let labels: [&str; 2] = [self.protocol.into(), success.as_str()]; - self.validation_count.with_label_values(&labels).inc(); - } - - fn register_counter_metric(options: Opts, labels: &[&str]) -> IntCounterVec { - // Register the metric with the default registry, or if that fails, register with a - // newly-created registry. - register_int_counter_vec!(options.clone(), labels).unwrap_or_else(|_| { - // Trying to register the same metric multiple times in the process should only happen - // in testing situations. In regular usage, it should be reported as an error: - error!("Failed to register prometheus metrics with default registry, creating new"); - - let custom_registry = Registry::new_custom(None, None) - .expect("Prometheus docs don't explain when it might fail to create a custom registry, so... hopefully never"); - register_int_counter_vec_with_registry!(options, labels, custom_registry) - .expect("a counter can always be added to a new custom registry, without conflict") - }) - } - - fn register_gauge_metric(options: Opts, labels: &[&str]) -> IntGaugeVec { - // Register the metric with the default registry, or if that fails, register with a - // newly-created registry. - register_int_gauge_vec!(options.clone(), labels).unwrap_or_else(|_| { - // Trying to register the same metric multiple times in the process should only happen - // in testing situations. In regular usage, it should be reported as an error: - error!("Failed to register prometheus metrics with default registry, creating new"); - - let custom_registry = Registry::new_custom(None, None) - .expect("Prometheus docs don't explain when it might fail to create a custom registry, so... hopefully never"); - register_int_gauge_vec_with_registry!(options, labels, custom_registry) - .expect("a gauge can always be added to a new custom registry, without conflict") - }) + let labels: [&str; 2] = [&self.protocol, success.as_str()]; + self.overlay_metrics + .validation_total + .with_label_values(&labels) + .inc(); } pub fn get_utp_summary(&self) -> String { let inbound_success = - self.utp_outcome_count(UtpDirectionLabel::Inbound, UtpOutcomeLabel::Success); - let inbound_failed_connection = self.utp_outcome_count( + self.utp_outcome_total(UtpDirectionLabel::Inbound, UtpOutcomeLabel::Success); + let inbound_failed_connection = self.utp_outcome_total( UtpDirectionLabel::Inbound, UtpOutcomeLabel::FailedConnection, ); let inbound_failed_data_tx = - self.utp_outcome_count(UtpDirectionLabel::Inbound, UtpOutcomeLabel::FailedDataTx); + self.utp_outcome_total(UtpDirectionLabel::Inbound, UtpOutcomeLabel::FailedDataTx); let inbound_failed_shutdown = - self.utp_outcome_count(UtpDirectionLabel::Inbound, UtpOutcomeLabel::FailedShutdown); + self.utp_outcome_total(UtpDirectionLabel::Inbound, UtpOutcomeLabel::FailedShutdown); let outbound_success = - self.utp_outcome_count(UtpDirectionLabel::Outbound, UtpOutcomeLabel::Success); - let outbound_failed_connection = self.utp_outcome_count( + self.utp_outcome_total(UtpDirectionLabel::Outbound, UtpOutcomeLabel::Success); + let outbound_failed_connection = self.utp_outcome_total( UtpDirectionLabel::Outbound, UtpOutcomeLabel::FailedConnection, ); let outbound_failed_data_tx = - self.utp_outcome_count(UtpDirectionLabel::Outbound, UtpOutcomeLabel::FailedDataTx); + self.utp_outcome_total(UtpDirectionLabel::Outbound, UtpOutcomeLabel::FailedDataTx); let outbound_failed_shutdown = - self.utp_outcome_count(UtpDirectionLabel::Outbound, UtpOutcomeLabel::FailedShutdown); - let active_inbound = self.utp_active_count(UtpDirectionLabel::Inbound); - let active_outbound = self.utp_active_count(UtpDirectionLabel::Outbound); + self.utp_outcome_total(UtpDirectionLabel::Outbound, UtpOutcomeLabel::FailedShutdown); + let active_inbound = self.utp_active_streams(UtpDirectionLabel::Inbound); + let active_outbound = self.utp_active_streams(UtpDirectionLabel::Outbound); format!( "(in/out): active={} ({}/{}), success={} ({}/{}), failed={} ({}/{}) \ failed_connection={} ({}/{}), failed_data_tx={} ({}/{}), failed_shutdown={} ({}/{})", @@ -244,14 +236,14 @@ impl OverlayMetrics { pub fn get_message_summary(&self) -> String { // for every offer you made, how many accepts did you receive // for every offer you received, how many accepts did you make - let successful_validations = self.validation_count_by_outcome(true); - let failed_validations = self.validation_count_by_outcome(false); + let successful_validations = self.validation_total_by_outcome(true); + let failed_validations = self.validation_total_by_outcome(false); format!( "offers={}/{}, accepts={}/{}, validations={}/{}", - self.message_count_by_labels(MessageDirectionLabel::Received, MessageLabel::Accept), - self.message_count_by_labels(MessageDirectionLabel::Sent, MessageLabel::Offer), - self.message_count_by_labels(MessageDirectionLabel::Sent, MessageLabel::Accept), - self.message_count_by_labels(MessageDirectionLabel::Received, MessageLabel::Offer), + self.message_total_by_labels(MessageDirectionLabel::Received, MessageLabel::Accept), + self.message_total_by_labels(MessageDirectionLabel::Sent, MessageLabel::Offer), + self.message_total_by_labels(MessageDirectionLabel::Sent, MessageLabel::Accept), + self.message_total_by_labels(MessageDirectionLabel::Received, MessageLabel::Offer), successful_validations, successful_validations + failed_validations, ) diff --git a/portalnet/src/metrics/portalnet.rs b/portalnet/src/metrics/portalnet.rs new file mode 100644 index 000000000..6371ce716 --- /dev/null +++ b/portalnet/src/metrics/portalnet.rs @@ -0,0 +1,38 @@ +use crate::metrics::overlay::OverlayMetrics; +use crate::metrics::storage::StorageMetrics; +use lazy_static::lazy_static; +use prometheus_exporter::prometheus::default_registry; + +// We use lazy_static to ensure that the metrics registry is initialized only once, for each +// runtime. This is important because the registry is a global singleton, and if it is +// initialized more than once, it will panic when trying to register the same metric for each +// subnetwork. +lazy_static! { + pub static ref PORTALNET_METRICS: PortalnetMetrics = initialize_metrics_registry(); +} + +fn initialize_metrics_registry() -> PortalnetMetrics { + PortalnetMetrics::new().expect("failed to initialize metrics") +} + +pub struct PortalnetMetrics { + overlay: OverlayMetrics, + storage: StorageMetrics, +} + +impl PortalnetMetrics { + pub fn new() -> anyhow::Result { + let registry = default_registry(); + let overlay = OverlayMetrics::new(registry)?; + let storage = StorageMetrics::new(registry)?; + Ok(Self { overlay, storage }) + } + + pub fn overlay(&self) -> OverlayMetrics { + self.overlay.clone() + } + + pub fn storage(&self) -> StorageMetrics { + self.storage.clone() + } +} diff --git a/portalnet/src/metrics/storage.rs b/portalnet/src/metrics/storage.rs new file mode 100644 index 000000000..1a35ffbc4 --- /dev/null +++ b/portalnet/src/metrics/storage.rs @@ -0,0 +1,180 @@ +use ethportal_api::types::distance::Distance; +use prometheus_exporter::{ + self, + prometheus::{ + opts, register_gauge_vec_with_registry, register_int_gauge_vec_with_registry, GaugeVec, + IntGaugeVec, Registry, + }, +}; + +/// Contains metrics reporters for portalnet storage. +#[derive(Clone, Debug)] +pub struct StorageMetrics { + pub content_storage_usage_bytes: GaugeVec, + pub total_storage_usage_bytes: GaugeVec, + pub storage_capacity_bytes: GaugeVec, + pub radius_ratio: GaugeVec, + pub entry_count: IntGaugeVec, +} + +const BYTES_IN_MB_F64: f64 = 1000.0 * 1000.0; + +impl StorageMetrics { + pub fn new(registry: &Registry) -> anyhow::Result { + let content_storage_usage_bytes = register_gauge_vec_with_registry!( + opts!( + "trin_content_storage_usage_bytes", + "sum of size of individual content stored, in bytes" + ), + &["protocol"], + registry + )?; + let total_storage_usage_bytes = register_gauge_vec_with_registry!( + opts!( + "trin_total_storage_usage_bytes", + "full on-disk database size, in bytes" + ), + &["protocol"], + registry + )?; + let storage_capacity_bytes = register_gauge_vec_with_registry!( + opts!( + "trin_storage_capacity_bytes", + "user-defined limit on storage usage, in bytes" + ), + &["protocol"], + registry + )?; + let radius_ratio = register_gauge_vec_with_registry!( + opts!( + "trin_radius_ratio", + "the fraction of the whole data ring covered by the data radius" + ), + &["protocol"], + registry + )?; + let entry_count = register_int_gauge_vec_with_registry!( + opts!("trin_entry_count", "total number of storage entries"), + &["protocol"], + registry + )?; + Ok(Self { + content_storage_usage_bytes, + total_storage_usage_bytes, + storage_capacity_bytes, + radius_ratio, + entry_count, + }) + } +} + +#[derive(Clone, Debug)] +pub struct StorageMetricsReporter { + pub protocol: String, + pub storage_metrics: StorageMetrics, +} + +impl StorageMetricsReporter { + pub fn report_content_data_storage_bytes(&self, bytes: f64) { + self.storage_metrics + .content_storage_usage_bytes + .with_label_values(&[&self.protocol]) + .set(bytes); + } + + pub fn report_total_storage_usage_bytes(&self, bytes: f64) { + self.storage_metrics + .total_storage_usage_bytes + .with_label_values(&[&self.protocol]) + .set(bytes); + } + + pub fn report_storage_capacity_bytes(&self, bytes: f64) { + self.storage_metrics + .storage_capacity_bytes + .with_label_values(&[&self.protocol]) + .set(bytes); + } + + pub fn report_radius(&self, radius: Distance) { + let radius_high_bytes = [ + radius.byte(31), + radius.byte(30), + radius.byte(29), + radius.byte(28), + ]; + let radius_int = u32::from_be_bytes(radius_high_bytes); + let coverage_ratio = radius_int as f64 / u32::MAX as f64; + self.storage_metrics + .radius_ratio + .with_label_values(&[&self.protocol]) + .set(coverage_ratio); + } + + pub fn report_entry_count(&self, count: u64) { + let count: i64 = count + .try_into() + .expect("Number of db entries will be small enough to fit in i64"); + self.storage_metrics + .entry_count + .with_label_values(&[&self.protocol]) + .set(count); + } + + pub fn increase_entry_count(&self) { + self.storage_metrics + .entry_count + .with_label_values(&[&self.protocol]) + .inc(); + } + + pub fn decrease_entry_count(&self) { + self.storage_metrics + .entry_count + .with_label_values(&[&self.protocol]) + .dec(); + } + + pub fn get_summary(&self) -> String { + let radius_percent = self + .storage_metrics + .radius_ratio + .with_label_values(&[&self.protocol]) + .get() + * 100.0; + format!( + "radius={:.*}% content={:.1}/{}mb #={} disk={:.1}mb", + Self::precision_for_percentage(radius_percent), + radius_percent, + self.storage_metrics + .content_storage_usage_bytes + .with_label_values(&[&self.protocol]) + .get() + / BYTES_IN_MB_F64, + self.storage_metrics + .storage_capacity_bytes + .with_label_values(&[&self.protocol]) + .get() + / BYTES_IN_MB_F64, + self.storage_metrics + .entry_count + .with_label_values(&[&self.protocol]) + .get(), + self.storage_metrics + .total_storage_usage_bytes + .with_label_values(&[&self.protocol]) + .get() + / BYTES_IN_MB_F64, + ) + } + + pub fn precision_for_percentage(percent: f64) -> usize { + match percent { + x if x >= 10.0 => 0, + x if x >= 1.0 => 1, + x if x >= 0.1 => 2, + x if x >= 0.01 => 3, + _ => 4, + } + } +} diff --git a/portalnet/src/overlay.rs b/portalnet/src/overlay.rs index 00e0f5467..135a559d8 100644 --- a/portalnet/src/overlay.rs +++ b/portalnet/src/overlay.rs @@ -26,7 +26,8 @@ use utp_rs::socket::UtpSocket; use crate::{ discovery::{Discovery, UtpEnr}, find::query_info::{FindContentResult, RecursiveFindContentResult}, - metrics::overlay::OverlayMetrics, + metrics::overlay::OverlayMetricsReporter, + metrics::portalnet::PORTALNET_METRICS, overlay_service::{ OverlayCommand, OverlayRequest, OverlayRequestError, OverlayService, RequestDirection, UTP_CONN_CFG, @@ -113,7 +114,7 @@ pub struct OverlayProtocol { /// Accepted content validator that makes requests to this/other overlay networks validator: Arc, /// Runtime telemetry metrics for the overlay network. - metrics: Arc, + metrics: OverlayMetricsReporter, } impl< @@ -140,10 +141,11 @@ where config.table_filter, config.bucket_filter, ))); - // Initialize metrics, keep a reference in order to build metrics summaries for logging - let metrics = Arc::new(OverlayMetrics::new(&protocol)); - + let metrics = OverlayMetricsReporter { + overlay_metrics: PORTALNET_METRICS.overlay(), + protocol: protocol.to_string(), + }; let command_tx = OverlayService::::spawn( Arc::clone(&discovery), Arc::clone(&store), @@ -152,7 +154,7 @@ where config.ping_queue_interval, protocol.clone(), Arc::clone(&utp_socket), - Arc::clone(&metrics), + metrics.clone(), Arc::clone(&validator), config.query_timeout, config.query_peer_timeout, diff --git a/portalnet/src/overlay_service.rs b/portalnet/src/overlay_service.rs index 84a66f4dd..32c8a4a9c 100644 --- a/portalnet/src/overlay_service.rs +++ b/portalnet/src/overlay_service.rs @@ -49,7 +49,7 @@ use crate::{ }, metrics::{ labels::{UtpDirectionLabel, UtpOutcomeLabel}, - overlay::OverlayMetrics, + overlay::OverlayMetricsReporter, }, storage::ContentStore, types::{ @@ -302,7 +302,7 @@ pub struct OverlayService { /// Phantom metric (distance function). phantom_metric: PhantomData, /// Metrics reporting component - metrics: Arc, + metrics: OverlayMetricsReporter, /// Validator for overlay network content. validator: Arc, /// A channel that the overlay service emits events on. @@ -332,7 +332,7 @@ where ping_queue_interval: Option, protocol: ProtocolId, utp_socket: Arc>, - metrics: Arc, + metrics: OverlayMetricsReporter, validator: Arc, query_timeout: Duration, query_peer_timeout: Duration, @@ -1112,7 +1112,7 @@ where // Wait for an incoming connection with the given CID. Then, write the data // over the uTP stream. let utp = Arc::clone(&self.utp_socket); - let metrics = Arc::clone(&self.metrics); + let metrics = self.metrics.clone(); tokio::spawn(async move { metrics.report_utp_active_inc(UtpDirectionLabel::Outbound); let stream = match utp.accept_with_cid(cid.clone(), *UTP_CONN_CFG).await { @@ -1237,7 +1237,7 @@ where let kbuckets = Arc::clone(&self.kbuckets); let command_tx = self.command_tx.clone(); let utp = Arc::clone(&self.utp_socket); - let metrics = Arc::clone(&self.metrics); + let metrics = self.metrics.clone(); tokio::spawn(async move { // Wait for an incoming connection with the given CID. Then, read the data from the uTP @@ -1503,7 +1503,7 @@ where let response_clone = response.clone(); let utp = Arc::clone(&self.utp_socket); - let metrics = Arc::clone(&self.metrics); + let metrics = self.metrics.clone(); tokio::spawn(async move { metrics.report_utp_active_inc(UtpDirectionLabel::Outbound); @@ -1584,7 +1584,7 @@ where async fn process_accept_utp_payload( validator: Arc, store: Arc>, - metrics: Arc, + metrics: OverlayMetricsReporter, kbuckets: Arc>>, command_tx: UnboundedSender>, content_keys: Vec, @@ -1612,7 +1612,7 @@ where // - Propagate all validated content let validator = Arc::clone(&validator); let store = Arc::clone(&store); - let metrics = Arc::clone(&metrics); + let metrics = metrics.clone(); tokio::spawn(async move { // Validated received content if let Err(err) = validator @@ -1680,7 +1680,7 @@ where async fn send_utp_content( mut stream: UtpStream, content: &[u8], - metrics: Arc, + metrics: OverlayMetricsReporter, ) -> anyhow::Result<()> { match stream.write(content).await { Ok(write_size) => { @@ -1824,7 +1824,7 @@ where responder: Option>, trace: Option, nodes_to_poke: Vec, - metrics: Arc, + metrics: OverlayMetricsReporter, ) { let mut content = content; // Operate under assumption that all content in the store is valid @@ -2684,27 +2684,27 @@ fn pop_while_ssz_bytes_len_gt(enrs: &mut Vec, max_size: usize) { mod tests { use super::*; + use std::net::SocketAddr; use std::time::Instant; - use rstest::rstest; + use discv5::kbucket::Entry; + use ethereum_types::U256; + use rstest::*; + use serial_test::serial; + use tokio::sync::mpsc::unbounded_channel; + use tokio_test::{assert_pending, assert_ready, task}; use crate::{ + config::PortalnetConfig, discovery::{Discovery, NodeAddress}, + metrics::portalnet::PORTALNET_METRICS, overlay::OverlayConfig, storage::{DistanceFunction, MemoryContentStore}, - types::messages::PortalnetConfig, + utils::db::setup_temp_dir, }; - - use crate::utils::db::setup_temp_dir; - use discv5::kbucket::Entry; - use ethereum_types::U256; use ethportal_api::types::content_key::overlay::IdentityContentKey; use ethportal_api::types::distance::XorMetric; use ethportal_api::types::enr::generate_random_remote_enr; - use serial_test::serial; - use std::net::SocketAddr; - use tokio::sync::mpsc::unbounded_channel; - use tokio_test::{assert_pending, assert_ready, task}; use trin_validation::validator::MockValidator; macro_rules! poll_command_rx { @@ -2746,7 +2746,10 @@ mod tests { let peers_to_ping = HashSetDelay::default(); let (command_tx, command_rx) = mpsc::unbounded_channel(); let (response_tx, response_rx) = mpsc::unbounded_channel(); - let metrics = Arc::new(OverlayMetrics::new(&protocol)); + let metrics = OverlayMetricsReporter { + overlay_metrics: PORTALNET_METRICS.overlay(), + protocol: "test".to_string(), + }; let validator = Arc::new(MockValidator {}); OverlayService { diff --git a/portalnet/src/storage.rs b/portalnet/src/storage.rs index e7dd38cc5..d881ec9af 100644 --- a/portalnet/src/storage.rs +++ b/portalnet/src/storage.rs @@ -8,13 +8,6 @@ use std::{ use anyhow::anyhow; use discv5::enr::NodeId; use ethportal_api::types::portal::PaginateLocalContentInfo; -use prometheus_exporter::{ - self, - prometheus::{ - default_registry, opts, register_gauge, register_gauge_with_registry, - register_int_gauge_with_registry, Gauge, IntGauge, Registry, - }, -}; use r2d2::Pool; use r2d2_sqlite::SqliteConnectionManager; use rocksdb::{Options, DB}; @@ -22,13 +15,14 @@ use rusqlite::params; use thiserror::Error; use tracing::{debug, error, info}; +use crate::metrics::portalnet::PORTALNET_METRICS; +use crate::metrics::storage::StorageMetricsReporter; use crate::types::messages::ProtocolId; use ethportal_api::types::distance::{Distance, Metric, XorMetric}; use ethportal_api::utils::bytes::{hex_decode, hex_encode, ByteUtilsError}; use ethportal_api::{ContentKeyError, HistoryContentKey, OverlayContentKey}; const BYTES_IN_MB_U64: u64 = 1000 * 1000; -const BYTES_IN_MB_F64: f64 = 1000.0 * 1000.0; // TODO: Replace enum with generic type parameter. This will require that we have a way to // associate a "find farthest" query with the generic Metric. @@ -42,14 +36,17 @@ pub enum DistanceFunction { pub enum ContentStoreError { #[error("An error from the underlying database: {0:?}")] Database(String), + #[error("IO error: {0:?}")] Io(#[from] std::io::Error), + /// Unable to store content because it does not fall within the store's radius. #[error("radius {radius} insufficient to store content at distance {distance}")] InsufficientRadius { radius: Distance, distance: Distance, }, + /// Unable to store or retrieve data because it is invalid. #[error("data invalid {message}")] InvalidData { message: String }, @@ -211,7 +208,7 @@ pub struct PortalStorage { db: Arc, sql_connection_pool: Pool, distance_fn: DistanceFunction, - metrics: StorageMetrics, + metrics: StorageMetricsReporter, } impl ContentStore for PortalStorage { @@ -255,6 +252,10 @@ impl PortalStorage { protocol: ProtocolId, ) -> Result { // Initialize the instance + let metrics = StorageMetricsReporter { + storage_metrics: PORTALNET_METRICS.storage(), + protocol: protocol.to_string(), + }; let mut storage = Self { node_id: config.node_id, node_data_dir: config.node_data_dir, @@ -263,7 +264,7 @@ impl PortalStorage { db: config.db, sql_connection_pool: config.sql_connection_pool, distance_fn: config.distance_fn, - metrics: StorageMetrics::new(&protocol), + metrics, }; // Set the metrics to the default radius, to start @@ -751,146 +752,6 @@ impl PortalStorage { } } -#[derive(Debug)] -struct StorageMetrics { - content_storage_usage_bytes: Gauge, - total_storage_usage_bytes: Gauge, - storage_capacity_bytes: Gauge, - radius_ratio: Gauge, - entry_count: IntGauge, -} - -impl StorageMetrics { - pub fn new(protocol: &ProtocolId) -> Self { - let content_storage_usage_bytes_options = opts!( - format!("trin_content_storage_usage_bytes_{protocol:?}"), - "sum of size of individual content stored, in bytes" - ); - // Keep a reference to the registry. Make mutable, because we may have to switch to a new - // one if the default registry is already using a metric of the same name (which should - // only happen during tests). - let mut registry = default_registry(); - - // Always create a custom registry, so that we can use it in the error case - // It's just an easy way to throw away duplicate metrics. - let custom_registry = Registry::default(); - - let content_storage_usage_bytes = - match register_gauge!(content_storage_usage_bytes_options.clone()) { - Ok(gauge) => gauge, - Err(_) => { - error!( - "Failed to register prometheus gauge with default registry, creating new" - ); - - // Assign the new registry to the outer variable, so it can be used by all metrics - registry = &custom_registry; - - // Reattempt to register the gauge with the empty registry - register_gauge_with_registry!(content_storage_usage_bytes_options, registry) - .expect( - "a gauge can always be added to a new custom registry, without conflict", - ) - } - }; - - let total_storage_usage_bytes = register_gauge_with_registry!( - format!("trin_total_storage_usage_bytes_{protocol:?}"), - "full on-disk database size, in bytes", - registry, - ) - .unwrap(); - let storage_capacity_bytes = register_gauge_with_registry!( - format!("trin_storage_capacity_bytes_{protocol:?}"), - "user-defined limit on storage usage, in bytes", - registry - ) - .unwrap(); - let radius_ratio = register_gauge_with_registry!( - format!("trin_radius_ratio_{protocol:?}"), - "the fraction of the whole data ring covered by the data radius", - registry, - ) - .unwrap(); - let entry_count = register_int_gauge_with_registry!( - format!("trin_entry_count_{protocol:?}"), - "total number of storage entries", - registry, - ) - .unwrap(); - - Self { - content_storage_usage_bytes, - total_storage_usage_bytes, - storage_capacity_bytes, - radius_ratio, - entry_count, - } - } - - pub fn report_content_data_storage_bytes(&self, bytes: f64) { - self.content_storage_usage_bytes.set(bytes); - } - - pub fn report_total_storage_usage_bytes(&self, bytes: f64) { - self.total_storage_usage_bytes.set(bytes); - } - - pub fn report_storage_capacity_bytes(&self, bytes: f64) { - self.storage_capacity_bytes.set(bytes); - } - - pub fn report_radius(&self, radius: Distance) { - let radius_high_bytes = [ - radius.byte(31), - radius.byte(30), - radius.byte(29), - radius.byte(28), - ]; - let radius_int = u32::from_be_bytes(radius_high_bytes); - let coverage_ratio = radius_int as f64 / u32::MAX as f64; - self.radius_ratio.set(coverage_ratio); - } - - pub fn report_entry_count(&self, count: u64) { - let count: i64 = count - .try_into() - .expect("Number of db entries will be small enough to fit in i64"); - self.entry_count.set(count); - } - - pub fn increase_entry_count(&self) { - self.entry_count.inc(); - } - - pub fn decrease_entry_count(&self) { - self.entry_count.dec(); - } - - pub fn get_summary(&self) -> String { - let radius_percent = self.radius_ratio.get() * 100.0; - format!( - "radius={:.*}% content={:.1}/{}mb #={} disk={:.1}mb", - Self::precision_for_percentage(radius_percent), - radius_percent, - self.content_storage_usage_bytes.get() / BYTES_IN_MB_F64, - self.storage_capacity_bytes.get() / BYTES_IN_MB_F64, - self.entry_count.get(), - self.total_storage_usage_bytes.get() / BYTES_IN_MB_F64, - ) - } - - fn precision_for_percentage(percent: f64) -> usize { - match percent { - x if x >= 10.0 => 0, - x if x >= 1.0 => 1, - x if x >= 0.1 => 2, - x if x >= 0.01 => 3, - _ => 4, - } - } -} - // SQLite Statements const CREATE_QUERY: &str = "CREATE TABLE IF NOT EXISTS content_metadata ( content_id_long TEXT PRIMARY KEY, @@ -1334,7 +1195,7 @@ pub mod test { #[test] fn test_precision_for_percentage() { fn formatted_percent(ratio: f64) -> String { - let precision = StorageMetrics::precision_for_percentage(ratio * 100.0); + let precision = StorageMetricsReporter::precision_for_percentage(ratio * 100.0); format!("{:.*}%", precision, ratio * 100.0) } assert_eq!(formatted_percent(1.0), "100%"); @@ -1371,9 +1232,9 @@ pub mod test { // We mostly care that values outside of [0.0, 1.0] do not crash, but // for now we also check that they pin to 0 or 4. - assert_eq!(StorageMetrics::precision_for_percentage(101.0), 0); - assert_eq!(StorageMetrics::precision_for_percentage(-0.001), 4); - assert_eq!(StorageMetrics::precision_for_percentage(-1000.0), 4); + assert_eq!(StorageMetricsReporter::precision_for_percentage(101.0), 0); + assert_eq!(StorageMetricsReporter::precision_for_percentage(-0.001), 4); + assert_eq!(StorageMetricsReporter::precision_for_percentage(-1000.0), 4); } fn get_active_node_id(temp_dir: PathBuf) -> NodeId { diff --git a/portalnet/src/types/messages.rs b/portalnet/src/types/messages.rs index 216a2bcd3..4e71ecf1a 100644 --- a/portalnet/src/types/messages.rs +++ b/portalnet/src/types/messages.rs @@ -1,12 +1,11 @@ use std::{ convert::{TryFrom, TryInto}, fmt, - net::SocketAddr, ops::Deref, str::FromStr, }; -use ethereum_types::{H256, U256}; +use ethereum_types::U256; use rlp::Encodable; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; @@ -16,7 +15,6 @@ use ssz_types::{typenum, BitList}; use thiserror::Error; use validator::ValidationError; -use ethportal_api::types::bootnodes::Bootnodes; use ethportal_api::types::bytes::ByteList; use ethportal_api::types::distance::Distance; use ethportal_api::types::enr::{Enr, SszEnr}; @@ -153,38 +151,6 @@ pub enum DiscoveryRequestError { InvalidMessage, } -/// Capacity of the cache for observed `NodeAddress` values. -/// Provides capacity for 32 full k-buckets. This capacity will be shared among all active portal -/// subnetworks. -const NODE_ADDR_CACHE_CAPACITY: usize = discv5::kbucket::MAX_NODES_PER_BUCKET * 32; - -#[derive(Clone)] -pub struct PortalnetConfig { - pub external_addr: Option, - pub private_key: H256, - pub listen_port: u16, - pub bootnodes: Bootnodes, - pub data_radius: Distance, - pub internal_ip: bool, - pub no_stun: bool, - pub node_addr_cache_capacity: usize, -} - -impl Default for PortalnetConfig { - fn default() -> Self { - Self { - external_addr: None, - private_key: H256::random(), - listen_port: 4242, - bootnodes: Bootnodes::default(), - data_radius: Distance::MAX, - internal_ip: false, - no_stun: false, - node_addr_cache_capacity: NODE_ADDR_CACHE_CAPACITY, - } - } -} - #[derive(Error, Debug)] pub enum ProtocolIdError { #[error("Unable to decode protocol id to bytes")] diff --git a/portalnet/tests/overlay.rs b/portalnet/tests/overlay.rs index 400d0d557..6f76bbdf4 100644 --- a/portalnet/tests/overlay.rs +++ b/portalnet/tests/overlay.rs @@ -1,17 +1,6 @@ use std::net::{IpAddr, Ipv4Addr}; use std::{net::SocketAddr, str::FromStr, sync::Arc}; -use ethportal_api::types::content_key::overlay::IdentityContentKey; -use ethportal_api::types::distance::XorMetric; -use ethportal_api::types::enr::{Enr, SszEnr}; -use portalnet::{ - discovery::{Discovery, Discv5UdpSocket}, - overlay::{OverlayConfig, OverlayProtocol}, - storage::{ContentStore, DistanceFunction, MemoryContentStore}, - types::messages::{Content, Message, PortalnetConfig, ProtocolId}, -}; -use trin_validation::validator::MockValidator; - use discv5::TalkRequest; use parking_lot::RwLock; use tokio::{ @@ -20,8 +9,19 @@ use tokio::{ }; use utp_rs::socket::UtpSocket; +use ethportal_api::types::content_key::overlay::IdentityContentKey; +use ethportal_api::types::distance::XorMetric; +use ethportal_api::types::enr::{Enr, SszEnr}; use ethportal_api::utils::bytes::hex_encode_upper; use portalnet::utils::db::setup_temp_dir; +use portalnet::{ + config::PortalnetConfig, + discovery::{Discovery, Discv5UdpSocket}, + overlay::{OverlayConfig, OverlayProtocol}, + storage::{ContentStore, DistanceFunction, MemoryContentStore}, + types::messages::{Content, Message, ProtocolId}, +}; +use trin_validation::validator::MockValidator; async fn init_overlay( discovery: Arc, diff --git a/src/lib.rs b/src/lib.rs index cf41a7b0f..984bbcf72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,10 +12,10 @@ use utp_rs::socket::UtpSocket; use ethportal_api::types::cli::Web3TransportType; use ethportal_api::types::cli::{TrinConfig, BEACON_NETWORK, HISTORY_NETWORK, STATE_NETWORK}; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, Discv5UdpSocket}, events::PortalnetEvents, storage::PortalStorageConfig, - types::messages::PortalnetConfig, utils::db::{configure_node_data_dir, configure_trin_data_dir}, }; use trin_beacon::initialize_beacon_network; @@ -45,14 +45,7 @@ pub async fn run_trin( let (node_data_dir, private_key) = configure_node_data_dir(trin_data_dir, trin_config.private_key)?; - let portalnet_config = PortalnetConfig { - external_addr: trin_config.external_addr, - private_key, - listen_port: trin_config.discovery_port, - no_stun: trin_config.no_stun, - bootnodes: trin_config.bootnodes.clone(), - ..Default::default() - }; + let portalnet_config = PortalnetConfig::new(&trin_config, private_key); // Initialize base discovery protocol let mut discovery = Discovery::new(portalnet_config.clone(), node_data_dir.clone())?; diff --git a/trin-beacon/src/lib.rs b/trin-beacon/src/lib.rs index fa8a3fcda..6db752010 100644 --- a/trin-beacon/src/lib.rs +++ b/trin-beacon/src/lib.rs @@ -21,9 +21,9 @@ use crate::{events::BeaconEvents, jsonrpc::BeaconRequestHandler}; use ethportal_api::types::enr::Enr; use ethportal_api::types::jsonrpc::request::BeaconJsonRpcRequest; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, UtpEnr}, storage::PortalStorageConfig, - types::messages::PortalnetConfig, }; use trin_validation::oracle::HeaderOracle; diff --git a/trin-beacon/src/network.rs b/trin-beacon/src/network.rs index bb746036a..d2a73fe3b 100644 --- a/trin-beacon/src/network.rs +++ b/trin-beacon/src/network.rs @@ -9,10 +9,11 @@ use ethportal_api::types::distance::XorMetric; use ethportal_api::types::enr::Enr; use ethportal_api::BeaconContentKey; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, UtpEnr}, overlay::{OverlayConfig, OverlayProtocol}, storage::{PortalStorage, PortalStorageConfig}, - types::messages::{PortalnetConfig, ProtocolId}, + types::messages::ProtocolId, }; use trin_validation::oracle::HeaderOracle; diff --git a/trin-history/src/lib.rs b/trin-history/src/lib.rs index f1bc5fee1..408d56e0a 100644 --- a/trin-history/src/lib.rs +++ b/trin-history/src/lib.rs @@ -22,9 +22,9 @@ use crate::{events::HistoryEvents, jsonrpc::HistoryRequestHandler}; use ethportal_api::types::enr::Enr; use ethportal_api::types::jsonrpc::request::HistoryJsonRpcRequest; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, UtpEnr}, storage::PortalStorageConfig, - types::messages::PortalnetConfig, }; use trin_validation::oracle::HeaderOracle; diff --git a/trin-history/src/network.rs b/trin-history/src/network.rs index 2f190b1d2..8d73a94ce 100644 --- a/trin-history/src/network.rs +++ b/trin-history/src/network.rs @@ -8,10 +8,11 @@ use ethportal_api::types::distance::XorMetric; use ethportal_api::types::enr::Enr; use ethportal_api::HistoryContentKey; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, UtpEnr}, overlay::{OverlayConfig, OverlayProtocol}, storage::{PortalStorage, PortalStorageConfig}, - types::messages::{PortalnetConfig, ProtocolId}, + types::messages::ProtocolId, }; use trin_validation::oracle::HeaderOracle; diff --git a/trin-state/src/lib.rs b/trin-state/src/lib.rs index 1d99dd539..ca7d8fea5 100644 --- a/trin-state/src/lib.rs +++ b/trin-state/src/lib.rs @@ -15,9 +15,9 @@ use crate::{events::StateEvents, jsonrpc::StateRequestHandler}; use ethportal_api::types::enr::Enr; use ethportal_api::types::jsonrpc::request::StateJsonRpcRequest; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, UtpEnr}, storage::PortalStorageConfig, - types::messages::PortalnetConfig, }; use trin_validation::oracle::HeaderOracle; diff --git a/trin-state/src/network.rs b/trin-state/src/network.rs index a6a29d69c..fbdc95fc1 100644 --- a/trin-state/src/network.rs +++ b/trin-state/src/network.rs @@ -9,10 +9,11 @@ use ethportal_api::types::distance::XorMetric; use ethportal_api::types::enr::Enr; use ethportal_api::StateContentKey; use portalnet::{ + config::PortalnetConfig, discovery::{Discovery, UtpEnr}, overlay::{OverlayConfig, OverlayProtocol}, storage::{PortalStorage, PortalStorageConfig}, - types::messages::{PortalnetConfig, ProtocolId}, + types::messages::ProtocolId, }; use trin_validation::oracle::HeaderOracle; @@ -36,7 +37,6 @@ impl StateNetwork { let db = PortalStorage::setup_triedb(&storage_config.node_data_dir)?; let triedb = TrieDB::new(Arc::new(db)); let trie = EthTrie::new(Arc::new(triedb)); - let storage = Arc::new(PLRwLock::new(PortalStorage::new( storage_config, ProtocolId::State, diff --git a/utp-testing/src/lib.rs b/utp-testing/src/lib.rs index e8da914aa..951d38f02 100644 --- a/utp-testing/src/lib.rs +++ b/utp-testing/src/lib.rs @@ -10,8 +10,9 @@ use ethportal_api::utils::bytes::{hex_encode, hex_encode_upper}; use jsonrpsee::core::{async_trait, RpcResult}; use jsonrpsee::proc_macros::rpc; use jsonrpsee::server::{Server, ServerHandle}; +use portalnet::config::PortalnetConfig; use portalnet::discovery::{Discovery, UtpEnr}; -use portalnet::types::messages::{PortalnetConfig, ProtocolId}; +use portalnet::types::messages::ProtocolId; use portalnet::utils::db::setup_temp_dir; use std::net::SocketAddr; use std::str::FromStr;