Skip to content

Commit

Permalink
Move RuntimeConfig to client
Browse files Browse the repository at this point in the history
  • Loading branch information
aterentic-ethernal committed Sep 4, 2024
1 parent 1d7ca61 commit 5de0e77
Show file tree
Hide file tree
Showing 16 changed files with 277 additions and 197 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ color-eyre = { workspace = true }
confy = "0.4.0"
hex = { workspace = true }
libp2p = { workspace = true }
serde = { workspace = true }
strip-ansi-escapes = "0.2.0"
tokio = { workspace = true }
tokio-stream = { workspace = true }
Expand Down
147 changes: 147 additions & 0 deletions client/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
use std::{ops::Range, time::Duration};

use avail_light_core::{
api::configuration::{APIConfig, SharedConfig},
network::{p2p::configuration::LibP2PConfig, rpc::configuration::RPCConfig},
telemetry::otlp::OtelConfig,
types::{
option_duration_seconds_format, tracing_level_format, AppClientConfig, Delay,
LightClientConfig, MaintenanceConfig, Origin, SyncClientConfig,
},
};
use serde::{Deserialize, Serialize};
use tracing::Level;

/// Representation of a configuration used by this project.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(default)]
pub struct RuntimeConfig {
/// Name of the project running the client. (default: "avail")
pub project_name: String,
#[serde(flatten)]
pub api: APIConfig,
#[serde(flatten)]
pub libp2p: LibP2PConfig,
#[serde(flatten)]
pub rpc: RPCConfig,
/// Genesis hash of the network to be connected to. Set to a string beginning with "DEV" to connect to any network.
pub genesis_hash: String,
/// If set, application client is started with given app_id (default: None).
pub app_id: Option<u32>,
/// Confidence threshold, used to calculate how many cells need to be sampled to achieve desired confidence (default: 92.0).
pub confidence: f64,
/// File system path where RocksDB used by light client, stores its data.
pub avail_path: String,
/// Log level, default is `INFO`. See `<https://docs.rs/log/0.4.14/log/enum.LevelFilter.html>` for possible log level values. (default: `INFO`).
#[serde(with = "tracing_level_format")]
pub log_level: Level,
pub origin: Origin,
/// If set to true, logs are displayed in JSON format, which is used for structured logging. Otherwise, plain text format is used (default: false).
pub log_format_json: bool,
#[serde(flatten)]
pub otel: OtelConfig,
pub total_memory_gb_threshold: f64,
pub num_cpus_threshold: usize,
/// Disables fetching of cells from RPC, set to true if client expects cells to be available in DHT (default: false).
pub disable_rpc: bool,
/// Number of seconds to postpone block processing after block finalized message arrives (default: 20).
#[serde(with = "option_duration_seconds_format")]
pub block_processing_delay: Option<Duration>,
/// Fraction and number of the block matrix part to fetch (e.g. 2/20 means second 1/20 part of a matrix) (default: None)
pub sync_start_block: Option<u32>,
/// Enable or disable synchronizing finality. If disabled, finality is assumed to be verified until the starting block at the point the LC is started and is only checked for new blocks. (default: true)
pub sync_finality_enable: bool,
/// Threshold for the number of cells fetched via DHT for the app client (default: 5000)
pub threshold: usize,
/// Client alias for use in logs and metrics
pub client_alias: Option<String>,
}

impl From<&RuntimeConfig> for LightClientConfig {
fn from(val: &RuntimeConfig) -> Self {
let block_processing_delay = val.block_processing_delay;
LightClientConfig {
confidence: val.confidence,
block_processing_delay: Delay(block_processing_delay),
}
}
}

impl From<&RuntimeConfig> for SyncClientConfig {
fn from(val: &RuntimeConfig) -> Self {
SyncClientConfig {
confidence: val.confidence,
disable_rpc: val.disable_rpc,
is_last_step: val.app_id.is_none(),
}
}
}

impl From<&RuntimeConfig> for AppClientConfig {
fn from(val: &RuntimeConfig) -> Self {
AppClientConfig {
disable_rpc: val.disable_rpc,
threshold: val.threshold,
}
}
}

impl From<&RuntimeConfig> for MaintenanceConfig {
fn from(val: &RuntimeConfig) -> Self {
MaintenanceConfig {
block_confidence_treshold: val.confidence,
replication_factor: val.libp2p.kademlia.record_replication_factor.get() as u16,
query_timeout: val.libp2p.kademlia.query_timeout,
pruning_interval: val.libp2p.kademlia.store_pruning_interval,
telemetry_flush_interval: val.otel.ot_flush_block_interval,
automatic_server_mode: val.libp2p.kademlia.automatic_server_mode,
total_memory_gb_threshold: val.total_memory_gb_threshold,
num_cpus_threshold: val.num_cpus_threshold,
}
}
}

impl From<&RuntimeConfig> for SharedConfig {
fn from(value: &RuntimeConfig) -> Self {
Self {
app_id: value.app_id,
confidence: value.confidence,
sync_start_block: value.sync_start_block,
}
}
}

impl Default for RuntimeConfig {
fn default() -> Self {
RuntimeConfig {
project_name: "avail".to_string(),
api: Default::default(),
libp2p: Default::default(),
rpc: Default::default(),
genesis_hash: "DEV".to_owned(),
app_id: None,
confidence: 99.9,
avail_path: "avail_path".to_owned(),
log_level: Level::INFO,
log_format_json: false,
otel: Default::default(),
total_memory_gb_threshold: 16.0,
num_cpus_threshold: 4,
disable_rpc: false,
block_processing_delay: Some(Duration::from_secs(20)),
sync_start_block: None,
sync_finality_enable: false,
threshold: 5000,
origin: Origin::External,
client_alias: None,
}
}
}

impl RuntimeConfig {
/// A range bounded inclusively below and exclusively above
pub fn sync_range(&self, end: u32) -> Range<u32> {
let start = self.sync_start_block.unwrap_or(end);
Range { start, end }
}
}
9 changes: 5 additions & 4 deletions client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use avail_light_core::{
sync_finality::SyncFinality,
telemetry::{self, MetricCounter, Metrics},
types::{
load_or_init_suri, IdentityConfig, MaintenanceConfig, MultiaddrConfig, RuntimeConfig,
SecretKey, Uuid,
load_or_init_suri, IdentityConfig, MaintenanceConfig, MultiaddrConfig, SecretKey, Uuid,
},
utils::{default_subscriber, install_panic_hooks, json_subscriber, spawn_in_span},
};
Expand All @@ -31,6 +30,7 @@ use color_eyre::{
eyre::{eyre, WrapErr},
Result,
};
use config::RuntimeConfig;
use std::{fs, path::Path, sync::Arc};
use tokio::sync::{broadcast, mpsc};
use tracing::{error, info, span, trace, warn, Level};
Expand Down Expand Up @@ -205,7 +205,7 @@ async fn run(
// Spawn tokio task which runs one http server for handling RPC
let server = api::server::Server {
db: db.clone(),
cfg: cfg.clone(),
cfg: (&cfg).into(),
identity_cfg,
version: format!("v{}", clap::crate_version!()),
network_version: EXPECTED_SYSTEM_VERSION[0].to_string(),
Expand All @@ -214,7 +214,7 @@ async fn run(
shutdown: shutdown.clone(),
p2p_client: p2p_client.clone(),
};
spawn_in_span(shutdown.with_cancel(server.bind()));
spawn_in_span(shutdown.with_cancel(server.bind(cfg.api.clone())));

let (block_tx, block_rx) = broadcast::channel::<avail_light_core::types::BlockVerified>(1 << 7);

Expand Down Expand Up @@ -322,6 +322,7 @@ async fn run(
}

mod cli;
mod config;

pub fn load_runtime_config(opts: &CliOpts) -> Result<RuntimeConfig> {
let mut cfg = if let Some(config_path) = &opts.config {
Expand Down
17 changes: 17 additions & 0 deletions core/src/api/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,20 @@ impl Default for APIConfig {
}
}
}

#[derive(Clone)]
pub struct SharedConfig {
pub app_id: Option<u32>,
pub confidence: f64,
pub sync_start_block: Option<u32>,
}

impl Default for SharedConfig {
fn default() -> Self {
Self {
app_id: Default::default(),
confidence: 99.9,
sync_start_block: Default::default(),
}
}
}
13 changes: 7 additions & 6 deletions core/src/api/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@ use crate::types::IdentityConfig;
use crate::{
api::v1,
network::rpc::{self},
types::RuntimeConfig,
};
use color_eyre::eyre::WrapErr;
use futures::{Future, FutureExt};
use std::{net::SocketAddr, str::FromStr};
use tracing::info;
use warp::{Filter, Reply};

use super::configuration::{APIConfig, SharedConfig};

pub struct Server<T: Database> {
pub db: T,
pub cfg: RuntimeConfig,
pub cfg: SharedConfig,
pub identity_cfg: IdentityConfig,
pub version: String,
pub network_version: String,
Expand All @@ -45,10 +46,10 @@ fn health_route() -> impl Filter<Extract = impl Reply, Error = warp::Rejection>

impl<T: Database + Clone + Send + Sync + 'static> Server<T> {
/// Creates a HTTP server that needs to be spawned into a runtime
pub fn bind(self) -> impl Future<Output = ()> {
let host = self.cfg.api.http_server_host.clone();
let port = self.cfg.api.http_server_port;
let v1_api = v1::routes(self.db.clone(), self.cfg.app_id, self.cfg.clone());
pub fn bind(self, cfg: APIConfig) -> impl Future<Output = ()> {
let host = cfg.http_server_host.clone();
let port = cfg.http_server_port;
let v1_api = v1::routes(self.db.clone(), self.cfg.clone());
let v2_api = v2::routes(
self.version.clone(),
self.network_version.clone(),
Expand Down
9 changes: 6 additions & 3 deletions core/src/api/v1/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use super::types::{AppDataQuery, ClientResponse, ConfidenceResponse, LatestBlockResponse, Status};
use crate::{
api::v1::types::{Extrinsics, ExtrinsicsDataResponse},
api::{
configuration::SharedConfig,
v1::types::{Extrinsics, ExtrinsicsDataResponse},
},
data::{AchievedConfidenceKey, AppDataKey, Database, VerifiedCellCountKey},
network::rpc::cell_count_for_confidence,
types::{BlockRange, Mode, RuntimeConfig},
types::{BlockRange, Mode},
utils::calculate_confidence,
};
use avail_rust::{
Expand Down Expand Up @@ -34,7 +37,7 @@ pub fn mode(app_id: Option<u32>) -> ClientResponse<Mode> {
pub fn confidence(
block_num: u32,
db: impl Database,
cfg: RuntimeConfig,
cfg: SharedConfig,
) -> ClientResponse<ConfidenceResponse> {
fn is_synced(block_num: u32, db: impl Database) -> bool {
get_achived_confidence(&db).map_or(false, |range| block_num <= range.last)
Expand Down
19 changes: 10 additions & 9 deletions core/src/api/v1/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::{data::Database, types::RuntimeConfig};
use crate::data::Database;

use self::types::AppDataQuery;
use std::convert::Infallible;
use warp::{Filter, Rejection, Reply};

use super::configuration::SharedConfig;

mod handlers;
mod types;

Expand All @@ -20,18 +22,17 @@ fn with_app_id(
}

fn with_cfg(
cfg: RuntimeConfig,
) -> impl Filter<Extract = (RuntimeConfig,), Error = Infallible> + Clone {
cfg: SharedConfig,
) -> impl Filter<Extract = (SharedConfig,), Error = Infallible> + Clone {
warp::any().map(move || cfg.clone())
}

pub fn routes(
db: impl Database + Clone + Send,
app_id: Option<u32>,
cfg: RuntimeConfig,
cfg: SharedConfig,
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone {
let mode = warp::path!("v1" / "mode")
.and(with_app_id(app_id))
.and(with_app_id(cfg.app_id))
.map(handlers::mode);

let latest_block = warp::path!("v1" / "latest_block")
Expand All @@ -40,17 +41,17 @@ pub fn routes(

let confidence = warp::path!("v1" / "confidence" / u32)
.and(with_db(db.clone()))
.and(with_cfg(cfg))
.and(with_cfg(cfg.clone()))
.map(handlers::confidence);

let appdata = (warp::path!("v1" / "appdata" / u32))
.and(warp::query::<AppDataQuery>())
.and(with_db(db.clone()))
.and(with_app_id(app_id))
.and(with_app_id(cfg.app_id))
.map(handlers::appdata);

let status = warp::path!("v1" / "status")
.and(with_app_id(app_id))
.and(with_app_id(cfg.app_id))
.and(with_db(db))
.map(handlers::status);

Expand Down
Loading

0 comments on commit 5de0e77

Please sign in to comment.