use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use super::secret::SecretString;
use crate::cli::common::{LogFormat, LogLevel};
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FileConfig {
pub identity: Option<IdentityConfig>,
pub network: Option<NetworkConfig>,
pub blockchain: Option<BlockchainConfig>,
pub cache: Option<CacheConfig>,
pub payment: Option<PaymentConfig>,
pub observability: Option<ObservabilityConfig>,
pub security: Option<SecurityConfig>,
pub load_shed: Option<LoadShedConfig>,
pub dht: Option<DhtConfig>,
pub probe: Option<ProbeConfig>,
pub receipts: Option<ReceiptsConfig>,
pub content: Option<ContentConfig>,
pub client: Option<ClientConfig>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct IdentityConfig {
pub data_dir: Option<PathBuf>,
pub region: Option<String>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ClientConfig {
pub region_allowlist: Option<Vec<String>>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct NetworkConfig {
pub bind_port: Option<u16>,
pub relay_urls: Option<Vec<String>>,
pub discovery: Option<DiscoveryConfig>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DiscoveryConfig {
pub pkarr_url: Option<String>,
pub dns_origin: Option<String>,
pub peers: Option<std::collections::HashMap<String, DiscoveryPeer>>,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DiscoveryPeer {
pub relay_url: Option<String>,
#[serde(default)]
pub addrs: Vec<String>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct BlockchainConfig {
pub rpc_url: Option<String>,
pub eth_keystore: Option<PathBuf>,
pub payment_pool_address: Option<String>,
pub capacity_bond_address: Option<String>,
pub origin_assignment_address: Option<String>,
pub origin_directory_positive_ttl_sec: Option<u64>,
pub origin_directory_negative_ttl_sec: Option<u64>,
pub origin_directory_cache_capacity: Option<usize>,
pub publisher_registry_address: Option<String>,
pub slash_judge_address: Option<String>,
pub slash_appeal_address: Option<String>,
pub content_blacklist_address: Option<String>,
pub content_blacklist_poll_interval_sec: Option<u64>,
pub chain_staleness_grace_sec: Option<u64>,
pub chain_id: Option<u64>,
pub rpc_watchdog_interval_sec: Option<u64>,
pub event_poll_interval_ms: Option<u64>,
pub get_logs_max_block_span: Option<u64>,
pub fee_shares_poll_interval_sec: Option<u64>,
pub redeem_threshold_micro_usdc: Option<u64>,
pub redeem_max_vouchers_per_tx: Option<u64>,
pub redeem_interval_secs: Option<u64>,
pub buyer_working_deposit_micro_usdc: Option<u64>,
pub buyer_max_approve: Option<bool>,
pub pool_min_remaining_deposit_micro_usdc: Option<u64>,
pub pool_floor_signer_live_windows: Option<u64>,
pub usdc_address: Option<String>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CacheConfig {
pub cache_dir: Option<PathBuf>,
pub cache_size_mb: Option<u64>,
pub disk_headroom_mb: Option<u64>,
pub max_blob_size_mb: Option<u64>,
pub max_rate_per_mb: Option<u64>,
pub origin: Option<OriginConfig>,
pub origins: Option<Vec<OriginConfig>>,
pub pinned_hashes: Option<Vec<String>>,
pub origin_retry: Option<decdn_config_types::RetryPolicy>,
pub circuit_breaker: Option<decdn_config_types::CircuitBreakerPolicy>,
pub user_agent: Option<String>,
pub gc_interval_sec: Option<u64>,
pub fs_rescan_interval_sec: Option<u64>,
pub origin_probe_ttl_sec: Option<u64>,
pub origin_probe_negative_ttl_sec: Option<u64>,
pub origin_probe_fault_ttl_sec: Option<u64>,
pub origin_probe_timeout_ms: Option<u64>,
pub origin_probe_memo_capacity: Option<u64>,
pub eviction_high_water_pct: Option<u64>,
pub eviction_target_pct: Option<u64>,
pub eviction_per_sweep_budget: Option<u64>,
pub eviction_tick_secs: Option<u64>,
pub max_probe_holds: Option<u64>,
pub stake_lane_reserved_holds: Option<u64>,
pub node_to_node_pull_through_enabled: Option<bool>,
pub relay_foreign_namespaces: Option<bool>,
pub node_pull_probe_fanout: Option<usize>,
pub node_pull_timeout_sec: Option<u64>,
pub node_pull_stall_window_sec: Option<u64>,
pub node_pull_min_throughput_bps: Option<u64>,
pub eviction_policy: Option<String>,
pub admission_policy: Option<String>,
pub tinylfu: Option<TinyLfuConfig>,
pub serve_economics: Option<ServeEconomicsConfig>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TinyLfuConfig {
pub sketch_bytes: Option<usize>,
pub promotion_threshold: Option<u32>,
pub probation_target_pct: Option<u64>,
pub aging_halflife_sec: Option<u64>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ServeEconomicsConfig {
pub policy: Option<String>,
pub discount: Option<f64>,
pub n_max: Option<u32>,
pub warming_budget: Option<u64>,
pub warming_refill: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "lowercase", deny_unknown_fields)]
pub enum OriginConfig {
Http {
url: String,
decompress: Option<decdn_config_types::DecompressMode>,
},
Fs {
path: PathBuf,
},
S3(S3OriginConfig),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct S3OriginConfig {
pub bucket: String,
pub region: String,
pub endpoint_url: Option<String>,
pub path_style: Option<bool>,
pub prefix: Option<String>,
pub credentials: Option<S3Credentials>,
pub decompress: Option<decdn_config_types::DecompressMode>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "source", rename_all = "kebab-case", deny_unknown_fields)]
pub enum S3Credentials {
Static {
access_key_id: SecretString,
secret_access_key: SecretString,
session_token: Option<SecretString>,
},
DefaultChain {
profile: Option<String>,
},
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PaymentConfig {
pub rate_per_mb: Option<u64>,
pub credit_max: Option<decdn_config_types::Bytes>,
pub credit_ramp_divisor: Option<u64>,
pub frame_target_bytes: Option<decdn_config_types::Bytes>,
pub voucher_commit_interval_ms: Option<u64>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SecurityConfig {
pub max_concurrent_handlers: Option<u32>,
pub per_source_rate_per_sec: Option<f64>,
pub per_source_burst: Option<u32>,
pub max_tracked_sources: Option<usize>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LoadShedConfig {
pub policy: Option<String>,
pub egress_budget_mbps: Option<u64>,
pub max_concurrent_serves_high: Option<u32>,
pub max_concurrent_serves_low: Option<u32>,
pub per_client_serve_cap: Option<u32>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DhtConfig {
pub rate_limit: Option<DhtRateLimitConfig>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DhtRateLimitConfig {
pub per_peer_rate_per_sec: Option<f64>,
pub per_peer_burst: Option<u32>,
pub per_ip_rate_per_sec: Option<f64>,
pub per_ip_burst: Option<u32>,
pub global_rate_per_sec: Option<f64>,
pub global_burst: Option<u32>,
pub max_tracked_per_ip: Option<usize>,
pub max_tracked_per_peer: Option<usize>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ProbeConfig {
pub rate_limit: Option<ProbeRateLimitConfig>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ProbeRateLimitConfig {
pub per_peer_rate_per_sec: Option<f64>,
pub per_peer_burst: Option<u32>,
pub per_ip_rate_per_sec: Option<f64>,
pub per_ip_burst: Option<u32>,
pub global_rate_per_sec: Option<f64>,
pub global_burst: Option<u32>,
pub max_tracked_per_ip: Option<usize>,
pub max_tracked_per_peer: Option<usize>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ObservabilityConfig {
pub log_level: Option<LogLevel>,
pub log_format: Option<LogFormat>,
pub metrics_port: Option<u16>,
pub metrics_bind: Option<std::net::IpAddr>,
pub admin_port: Option<u16>,
pub otlp_endpoint: Option<String>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ReceiptsConfig {
pub max_file_bytes: Option<u64>,
pub retained_files: Option<u32>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ContentConfig {
pub denied_hashes: Option<Vec<String>>,
pub denied_origins: Option<Vec<String>>,
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] mod tests;