radicle/config/node: Use newtypes
This commit is contained in:
parent
c4ff0d8eae
commit
9a7c22536b
|
|
@ -36,11 +36,13 @@ pub(crate) mod config {
|
||||||
inbound: RateLimit {
|
inbound: RateLimit {
|
||||||
fill_rate: 1.0,
|
fill_rate: 1.0,
|
||||||
capacity: usize::MAX,
|
capacity: usize::MAX,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
outbound: RateLimit {
|
outbound: RateLimit {
|
||||||
fill_rate: 1.0,
|
fill_rate: 1.0,
|
||||||
capacity: usize::MAX,
|
capacity: usize::MAX,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
..Limits::default()
|
..Limits::default()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ fn execute() -> anyhow::Result<()> {
|
||||||
let config = options.config.unwrap_or_else(|| home.config());
|
let config = options.config.unwrap_or_else(|| home.config());
|
||||||
let mut config = profile::Config::load(&config)?;
|
let mut config = profile::Config::load(&config)?;
|
||||||
|
|
||||||
let level = options.log.unwrap_or(config.node.log);
|
let level = options.log.unwrap_or_else(|| config.node.log.into());
|
||||||
|
|
||||||
let logger = {
|
let logger = {
|
||||||
let journal = {
|
let journal = {
|
||||||
|
|
@ -135,7 +135,7 @@ fn execute() -> anyhow::Result<()> {
|
||||||
config.node.listen.clone()
|
config.node.listen.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = radicle::io::set_file_limit(config.node.limits.max_open_files) {
|
if let Err(e) = radicle::io::set_file_limit::<usize>(config.node.limits.max_open_files.into()) {
|
||||||
log::warn!(target: "node", "Unable to set process open file limit: {e}");
|
log::warn!(target: "node", "Unable to set process open file limit: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ impl Runtime {
|
||||||
cobs_cache,
|
cobs_cache,
|
||||||
db,
|
db,
|
||||||
worker::Config {
|
worker::Config {
|
||||||
capacity: config.workers,
|
capacity: config.workers.into(),
|
||||||
storage: storage.clone(),
|
storage: storage.clone(),
|
||||||
fetch,
|
fetch,
|
||||||
policy,
|
policy,
|
||||||
|
|
|
||||||
|
|
@ -308,8 +308,8 @@ fn test_inventory_pruning() {
|
||||||
// All zero
|
// All zero
|
||||||
Test {
|
Test {
|
||||||
limits: Limits {
|
limits: Limits {
|
||||||
routing_max_size: 0,
|
routing_max_size: 0.into(),
|
||||||
routing_max_age: LocalDuration::from_secs(0),
|
routing_max_age: LocalDuration::from_secs(0).into(),
|
||||||
..Limits::default()
|
..Limits::default()
|
||||||
},
|
},
|
||||||
peer_projects: vec![10; 5],
|
peer_projects: vec![10; 5],
|
||||||
|
|
@ -319,8 +319,8 @@ fn test_inventory_pruning() {
|
||||||
// All entries are too young to expire.
|
// All entries are too young to expire.
|
||||||
Test {
|
Test {
|
||||||
limits: Limits {
|
limits: Limits {
|
||||||
routing_max_size: 0,
|
routing_max_size: 0.into(),
|
||||||
routing_max_age: LocalDuration::from_mins(7 * 24 * 60),
|
routing_max_age: LimitRoutingMaxAge::from(LocalDuration::from_mins(7 * 24 * 60)),
|
||||||
..Limits::default()
|
..Limits::default()
|
||||||
},
|
},
|
||||||
peer_projects: vec![10; 5],
|
peer_projects: vec![10; 5],
|
||||||
|
|
@ -330,8 +330,8 @@ fn test_inventory_pruning() {
|
||||||
// All entries remain because the table is unconstrained.
|
// All entries remain because the table is unconstrained.
|
||||||
Test {
|
Test {
|
||||||
limits: Limits {
|
limits: Limits {
|
||||||
routing_max_size: 50,
|
routing_max_size: 50.into(),
|
||||||
routing_max_age: LocalDuration::from_mins(0),
|
routing_max_age: LocalDuration::from_mins(0).into(),
|
||||||
..Limits::default()
|
..Limits::default()
|
||||||
},
|
},
|
||||||
peer_projects: vec![10; 5],
|
peer_projects: vec![10; 5],
|
||||||
|
|
@ -341,8 +341,8 @@ fn test_inventory_pruning() {
|
||||||
// Some entries are pruned because the table is constrained.
|
// Some entries are pruned because the table is constrained.
|
||||||
Test {
|
Test {
|
||||||
limits: Limits {
|
limits: Limits {
|
||||||
routing_max_size: 25,
|
routing_max_size: 25.into(),
|
||||||
routing_max_age: LocalDuration::from_mins(7 * 24 * 60),
|
routing_max_age: LocalDuration::from_mins(7 * 24 * 60).into(),
|
||||||
..Limits::default()
|
..Limits::default()
|
||||||
},
|
},
|
||||||
peer_projects: vec![10; 5],
|
peer_projects: vec![10; 5],
|
||||||
|
|
|
||||||
|
|
@ -679,7 +679,7 @@ fn test_concurrent_fetches() {
|
||||||
let repos = scale.max(4);
|
let repos = scale.max(4);
|
||||||
let limits = Limits {
|
let limits = Limits {
|
||||||
// Have one fetch be queued.
|
// Have one fetch be queued.
|
||||||
fetch_concurrency: repos - 1,
|
fetch_concurrency: (repos - 1).into(),
|
||||||
..Limits::default()
|
..Limits::default()
|
||||||
};
|
};
|
||||||
let mut bob_repos = HashSet::new();
|
let mut bob_repos = HashSet::new();
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use radicle::node;
|
||||||
use radicle::node::address;
|
use radicle::node::address;
|
||||||
use radicle::node::address::Store as _;
|
use radicle::node::address::Store as _;
|
||||||
use radicle::node::address::{AddressBook, AddressType, KnownAddress};
|
use radicle::node::address::{AddressBook, AddressType, KnownAddress};
|
||||||
use radicle::node::config::PeerConfig;
|
use radicle::node::config::{PeerConfig, RateLimit};
|
||||||
use radicle::node::device::Device;
|
use radicle::node::device::Device;
|
||||||
use radicle::node::refs::Store as _;
|
use radicle::node::refs::Store as _;
|
||||||
use radicle::node::routing::Store as _;
|
use radicle::node::routing::Store as _;
|
||||||
|
|
@ -845,7 +845,7 @@ where
|
||||||
if let Err(err) = self
|
if let Err(err) = self
|
||||||
.db
|
.db
|
||||||
.gossip_mut()
|
.gossip_mut()
|
||||||
.prune((now - self.config.limits.gossip_max_age).into())
|
.prune((now - LocalDuration::from(self.config.limits.gossip_max_age)).into())
|
||||||
{
|
{
|
||||||
error!(target: "service", "Error pruning gossip entries: {err}");
|
error!(target: "service", "Error pruning gossip entries: {err}");
|
||||||
}
|
}
|
||||||
|
|
@ -1302,7 +1302,7 @@ where
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Check for inbound connection limit.
|
// Check for inbound connection limit.
|
||||||
if self.sessions.inbound().count() >= self.config.limits.connection.inbound {
|
if self.sessions.inbound().count() >= self.config.limits.connection.inbound.into() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
match self.db.addresses().is_ip_banned(ip) {
|
match self.db.addresses().is_ip_banned(ip) {
|
||||||
|
|
@ -1315,13 +1315,9 @@ where
|
||||||
Err(e) => error!(target: "service", "Error querying ban status for {ip}: {e}"),
|
Err(e) => error!(target: "service", "Error querying ban status for {ip}: {e}"),
|
||||||
}
|
}
|
||||||
let host: HostName = ip.into();
|
let host: HostName = ip.into();
|
||||||
|
let tokens = RateLimit::from(self.config.limits.rate.inbound.clone());
|
||||||
|
|
||||||
if self.limiter.limit(
|
if self.limiter.limit(host.clone(), None, &tokens, self.clock) {
|
||||||
host.clone(),
|
|
||||||
None,
|
|
||||||
&self.config.limits.rate.inbound,
|
|
||||||
self.clock,
|
|
||||||
) {
|
|
||||||
trace!(target: "service", "Rate limiting inbound connection from {host}..");
|
trace!(target: "service", "Rate limiting inbound connection from {host}..");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1824,13 +1820,13 @@ where
|
||||||
};
|
};
|
||||||
peer.last_active = self.clock;
|
peer.last_active = self.clock;
|
||||||
|
|
||||||
let limit = match peer.link {
|
let limit: RateLimit = match peer.link {
|
||||||
Link::Outbound => &self.config.limits.rate.outbound,
|
Link::Outbound => self.config.limits.rate.outbound.clone().into(),
|
||||||
Link::Inbound => &self.config.limits.rate.inbound,
|
Link::Inbound => self.config.limits.rate.inbound.clone().into(),
|
||||||
};
|
};
|
||||||
if self
|
if self
|
||||||
.limiter
|
.limiter
|
||||||
.limit(peer.addr.clone().into(), Some(remote), limit, self.clock)
|
.limit(peer.addr.clone().into(), Some(remote), &limit, self.clock)
|
||||||
{
|
{
|
||||||
debug!(target: "service", "Rate limiting message from {remote} ({})", peer.addr);
|
debug!(target: "service", "Rate limiting message from {remote} ({})", peer.addr);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
@ -2260,7 +2256,7 @@ where
|
||||||
if self.sessions.contains_key(&nid) {
|
if self.sessions.contains_key(&nid) {
|
||||||
return Err(ConnectError::SessionExists { nid });
|
return Err(ConnectError::SessionExists { nid });
|
||||||
}
|
}
|
||||||
if self.sessions.outbound().count() >= self.config.limits.connection.outbound {
|
if self.sessions.outbound().count() >= self.config.limits.connection.outbound.into() {
|
||||||
return Err(ConnectError::LimitReached { nid, addr });
|
return Err(ConnectError::LimitReached { nid, addr });
|
||||||
}
|
}
|
||||||
let persistent = self.config.is_persistent(&nid);
|
let persistent = self.config.is_persistent(&nid);
|
||||||
|
|
@ -2432,14 +2428,14 @@ where
|
||||||
|
|
||||||
fn prune_routing_entries(&mut self, now: &LocalTime) -> Result<(), routing::Error> {
|
fn prune_routing_entries(&mut self, now: &LocalTime) -> Result<(), routing::Error> {
|
||||||
let count = self.db.routing().len()?;
|
let count = self.db.routing().len()?;
|
||||||
if count <= self.config.limits.routing_max_size {
|
if count <= self.config.limits.routing_max_size.into() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let delta = count - self.config.limits.routing_max_size;
|
let delta = count - usize::from(self.config.limits.routing_max_size);
|
||||||
let nid = self.node_id();
|
let nid = self.node_id();
|
||||||
self.db.routing_mut().prune(
|
self.db.routing_mut().prune(
|
||||||
(*now - self.config.limits.routing_max_age).into(),
|
(*now - LocalDuration::from(self.config.limits.routing_max_age)).into(),
|
||||||
Some(delta),
|
Some(delta),
|
||||||
&nid,
|
&nid,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ impl Session {
|
||||||
|
|
||||||
pub fn is_at_capacity(&self) -> bool {
|
pub fn is_at_capacity(&self) -> bool {
|
||||||
if let State::Connected { fetching, .. } = &self.state {
|
if let State::Connected { fetching, .. } = &self.state {
|
||||||
if fetching.len() >= self.limits.fetch_concurrency {
|
if fetching.len() >= self.limits.fetch_concurrency.into() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,72 +120,35 @@ impl Network {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configuration parameters defining attributes of minima and maxima.
|
/// Configuration parameters defining attributes of minima and maxima.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct Limits {
|
pub struct Limits {
|
||||||
/// Number of routing table entries before we start pruning.
|
/// Number of routing table entries before we start pruning.
|
||||||
#[serde(default = "defaults::limit_routing_max_size")]
|
pub routing_max_size: LimitRoutingMaxSize,
|
||||||
pub routing_max_size: usize,
|
|
||||||
|
|
||||||
/// How long to keep a routing table entry before being pruned.
|
/// How long to keep a routing table entry before being pruned.
|
||||||
#[serde(
|
pub routing_max_age: LimitRoutingMaxAge,
|
||||||
default = "defaults::limit_routing_max_age",
|
|
||||||
with = "crate::serde_ext::localtime::duration"
|
|
||||||
)]
|
|
||||||
#[cfg_attr(
|
|
||||||
feature = "schemars",
|
|
||||||
schemars(with = "crate::schemars_ext::localtime::LocalDuration")
|
|
||||||
)]
|
|
||||||
pub routing_max_age: LocalDuration,
|
|
||||||
|
|
||||||
/// How long to keep a gossip message entry before pruning it.
|
/// How long to keep a gossip message entry before pruning it.
|
||||||
#[serde(
|
pub gossip_max_age: LimitGossipMaxAge,
|
||||||
default = "defaults::limit_gossip_max_age",
|
|
||||||
with = "crate::serde_ext::localtime::duration"
|
|
||||||
)]
|
|
||||||
#[cfg_attr(
|
|
||||||
feature = "schemars",
|
|
||||||
schemars(with = "crate::schemars_ext::localtime::LocalDuration")
|
|
||||||
)]
|
|
||||||
pub gossip_max_age: LocalDuration,
|
|
||||||
|
|
||||||
/// Maximum number of concurrent fetches per peer connection.
|
/// Maximum number of concurrent fetches per peer connection.
|
||||||
#[serde(default = "defaults::limit_fetch_concurrency")]
|
pub fetch_concurrency: LimitFetchConcurrency,
|
||||||
pub fetch_concurrency: usize,
|
|
||||||
|
|
||||||
/// Maximum number of open files.
|
/// Maximum number of open files.
|
||||||
#[serde(default = "defaults::limit_max_open_files")]
|
pub max_open_files: LimitMaxOpenFiles,
|
||||||
pub max_open_files: usize,
|
|
||||||
|
|
||||||
/// Rate limitter settings.
|
/// Rate limitter settings.
|
||||||
#[serde(default)]
|
|
||||||
pub rate: RateLimits,
|
pub rate: RateLimits,
|
||||||
|
|
||||||
/// Connection limits.
|
/// Connection limits.
|
||||||
#[serde(default)]
|
|
||||||
pub connection: ConnectionLimits,
|
pub connection: ConnectionLimits,
|
||||||
|
|
||||||
/// Channel limits.
|
/// Channel limits.
|
||||||
#[serde(default)]
|
|
||||||
pub fetch_pack_receive: FetchPackSizeLimit,
|
pub fetch_pack_receive: FetchPackSizeLimit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Limits {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
routing_max_size: defaults::limit_routing_max_size(),
|
|
||||||
routing_max_age: defaults::limit_routing_max_age(),
|
|
||||||
gossip_max_age: defaults::limit_gossip_max_age(),
|
|
||||||
fetch_concurrency: defaults::limit_fetch_concurrency(),
|
|
||||||
max_open_files: defaults::limit_max_open_files(),
|
|
||||||
rate: RateLimits::default(),
|
|
||||||
connection: ConnectionLimits::default(),
|
|
||||||
fetch_pack_receive: FetchPackSizeLimit::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limiter for byte streams.
|
/// Limiter for byte streams.
|
||||||
///
|
///
|
||||||
/// Default: 500MiB
|
/// Default: 500MiB
|
||||||
|
|
@ -277,30 +240,20 @@ impl Default for FetchPackSizeLimit {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connection limits.
|
/// Connection limits.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct ConnectionLimits {
|
pub struct ConnectionLimits {
|
||||||
/// Max inbound connections.
|
/// Max inbound connections.
|
||||||
#[serde(default = "defaults::limit_connections_inbound")]
|
pub inbound: LimitConnectionsInbound,
|
||||||
pub inbound: usize,
|
|
||||||
|
|
||||||
/// Max outbound connections. Note that this can be higher than the *target* number.
|
/// Max outbound connections. Note that this can be higher than the *target* number.
|
||||||
#[serde(default = "defaults::limit_connections_outbound")]
|
pub outbound: LimitConnectionsOutbound,
|
||||||
pub outbound: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ConnectionLimits {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
inbound: defaults::limit_connections_inbound(),
|
|
||||||
outbound: defaults::limit_connections_outbound(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rate limts for a single connection.
|
/// Rate limts for a single connection.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Display)]
|
||||||
|
#[display("RateLimit(fill_rate={fill_rate}, capacity={capacity})")]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct RateLimit {
|
pub struct RateLimit {
|
||||||
|
|
@ -309,24 +262,13 @@ pub struct RateLimit {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rate limits for inbound and outbound connections.
|
/// Rate limits for inbound and outbound connections.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct RateLimits {
|
pub struct RateLimits {
|
||||||
#[serde(default = "defaults::limit_rate_inbound")]
|
pub inbound: LimitRateInbound,
|
||||||
pub inbound: RateLimit,
|
|
||||||
|
|
||||||
#[serde(default = "defaults::limit_rate_outbound")]
|
pub outbound: LimitRateOutbound,
|
||||||
pub outbound: RateLimit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for RateLimits {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
inbound: defaults::limit_rate_inbound(),
|
|
||||||
outbound: defaults::limit_rate_outbound(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Full address used to connect to a remote node.
|
/// Full address used to connect to a remote node.
|
||||||
|
|
@ -388,22 +330,17 @@ impl Deref for ConnectAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peer configuration.
|
/// Peer configuration.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
#[serde(rename_all = "camelCase", tag = "type")]
|
#[serde(rename_all = "camelCase", tag = "type")]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub enum PeerConfig {
|
pub enum PeerConfig {
|
||||||
/// Static peer set. Connect to the configured peers and maintain the connections.
|
/// Static peer set. Connect to the configured peers and maintain the connections.
|
||||||
Static,
|
Static,
|
||||||
/// Dynamic peer set.
|
/// Dynamic peer set.
|
||||||
|
#[default]
|
||||||
Dynamic,
|
Dynamic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PeerConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Dynamic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Relay configuration.
|
/// Relay configuration.
|
||||||
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
|
@ -505,13 +442,8 @@ pub struct Config {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub network: Network,
|
pub network: Network,
|
||||||
/// Log level.
|
/// Log level.
|
||||||
#[serde(default = "defaults::log")]
|
#[serde(default)]
|
||||||
#[serde(with = "crate::serde_ext::string")]
|
pub log: LogLevel,
|
||||||
#[cfg_attr(
|
|
||||||
feature = "schemars",
|
|
||||||
schemars(with = "crate::schemars_ext::log::Level")
|
|
||||||
)]
|
|
||||||
pub log: log::Level,
|
|
||||||
/// Whether or not our node should relay messages.
|
/// Whether or not our node should relay messages.
|
||||||
#[serde(default, deserialize_with = "crate::serde_ext::ok_or_default")]
|
#[serde(default, deserialize_with = "crate::serde_ext::ok_or_default")]
|
||||||
pub relay: Relay,
|
pub relay: Relay,
|
||||||
|
|
@ -519,8 +451,8 @@ pub struct Config {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub limits: Limits,
|
pub limits: Limits,
|
||||||
/// Number of worker threads to spawn.
|
/// Number of worker threads to spawn.
|
||||||
#[serde(default = "defaults::workers")]
|
#[serde(default)]
|
||||||
pub workers: usize,
|
pub workers: Workers,
|
||||||
/// Default seeding policy.
|
/// Default seeding policy.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub seeding_policy: DefaultSeedingPolicy,
|
pub seeding_policy: DefaultSeedingPolicy,
|
||||||
|
|
@ -549,8 +481,8 @@ impl Config {
|
||||||
onion: None,
|
onion: None,
|
||||||
relay: Relay::default(),
|
relay: Relay::default(),
|
||||||
limits: Limits::default(),
|
limits: Limits::default(),
|
||||||
workers: defaults::workers(),
|
workers: Workers::default(),
|
||||||
log: defaults::log(),
|
log: LogLevel::default(),
|
||||||
seeding_policy: DefaultSeedingPolicy::default(),
|
seeding_policy: DefaultSeedingPolicy::default(),
|
||||||
extra: json::Map::default(),
|
extra: json::Map::default(),
|
||||||
}
|
}
|
||||||
|
|
@ -587,72 +519,129 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defaults as functions, for serde.
|
#[derive(Clone, Copy, Debug, Display, Deserialize, Serialize, From)]
|
||||||
mod defaults {
|
#[serde(transparent)]
|
||||||
/// Default number of workers to spawn.
|
#[display("{0}")]
|
||||||
#[inline]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub const fn workers() -> usize {
|
pub struct LogLevel(
|
||||||
8
|
#[serde(with = "crate::serde_ext::string")]
|
||||||
}
|
#[cfg_attr(
|
||||||
|
feature = "schemars",
|
||||||
|
schemars(with = "crate::schemars_ext::log::Level")
|
||||||
|
)]
|
||||||
|
log::Level,
|
||||||
|
);
|
||||||
|
|
||||||
/// Log level.
|
impl Default for LogLevel {
|
||||||
#[inline]
|
fn default() -> Self {
|
||||||
pub const fn log() -> log::Level {
|
Self(log::Level::Info)
|
||||||
log::Level::Info
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_connections_inbound() -> usize {
|
|
||||||
128
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_connections_outbound() -> usize {
|
|
||||||
16
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_routing_max_size() -> usize {
|
|
||||||
1000
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_routing_max_age() -> localtime::LocalDuration {
|
|
||||||
localtime::LocalDuration::from_mins(7 * 24 * 60) // One week
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_gossip_max_age() -> localtime::LocalDuration {
|
|
||||||
localtime::LocalDuration::from_mins(2 * 7 * 24 * 60) // Two weeks
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_fetch_concurrency() -> usize {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_max_open_files() -> usize {
|
|
||||||
4096
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_rate_inbound() -> super::RateLimit {
|
|
||||||
super::RateLimit {
|
|
||||||
fill_rate: 5.0,
|
|
||||||
capacity: 1024,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn limit_rate_outbound() -> super::RateLimit {
|
|
||||||
super::RateLimit {
|
|
||||||
fill_rate: 10.0,
|
|
||||||
capacity: 2048,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LogLevel> for log::Level {
|
||||||
|
fn from(value: LogLevel) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize, Eq, PartialEq)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
pub struct LimitRoutingMaxAge(
|
||||||
|
#[serde(with = "crate::serde_ext::localtime::duration")]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "schemars",
|
||||||
|
schemars(with = "crate::schemars_ext::localtime::LocalDuration")
|
||||||
|
)]
|
||||||
|
localtime::LocalDuration,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Default for LimitRoutingMaxAge {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(localtime::LocalDuration::from_mins(7 * 24 * 60)) // One week
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LimitRoutingMaxAge> for LocalDuration {
|
||||||
|
fn from(value: LimitRoutingMaxAge) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LocalDuration> for LimitRoutingMaxAge {
|
||||||
|
fn from(value: LocalDuration) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize, Eq, PartialEq)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
pub struct LimitGossipMaxAge(
|
||||||
|
#[serde(with = "crate::serde_ext::localtime::duration")]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "schemars",
|
||||||
|
schemars(with = "crate::schemars_ext::localtime::LocalDuration")
|
||||||
|
)]
|
||||||
|
localtime::LocalDuration,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Default for LimitGossipMaxAge {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(localtime::LocalDuration::from_mins(2 * 7 * 24 * 60)) // Two weeks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LimitGossipMaxAge> for LocalDuration {
|
||||||
|
fn from(value: LimitGossipMaxAge) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! wrapper {
|
||||||
|
($name:ident, $type:ty, $default:expr $(, $derive:ty)*) => {
|
||||||
|
#[derive(Clone, Debug, Deserialize, Display, Serialize, From $(, $derive)*)]
|
||||||
|
#[display("{0}")]
|
||||||
|
#[serde(transparent)]
|
||||||
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
pub struct $name($type);
|
||||||
|
|
||||||
|
impl Default for $name {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self($default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<$name> for $type {
|
||||||
|
fn from(value: $name) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
wrapper!(Workers, usize, 8, Copy);
|
||||||
|
wrapper!(LimitConnectionsInbound, usize, 128, Copy);
|
||||||
|
wrapper!(LimitConnectionsOutbound, usize, 16, Copy);
|
||||||
|
wrapper!(LimitRoutingMaxSize, usize, 1000, Copy);
|
||||||
|
wrapper!(LimitFetchConcurrency, usize, 1, Copy);
|
||||||
|
wrapper!(
|
||||||
|
LimitRateInbound,
|
||||||
|
RateLimit,
|
||||||
|
RateLimit {
|
||||||
|
fill_rate: 5.0,
|
||||||
|
capacity: 1024,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
wrapper!(LimitMaxOpenFiles, usize, 4096, Copy);
|
||||||
|
wrapper!(
|
||||||
|
LimitRateOutbound,
|
||||||
|
RateLimit,
|
||||||
|
RateLimit {
|
||||||
|
fill_rate: 10.0,
|
||||||
|
capacity: 2048,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
@ -671,10 +660,10 @@ mod test {
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(config.limits.connection.inbound, 1337);
|
assert_eq!(config.limits.connection.inbound.0, 1337);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.limits.connection.outbound,
|
config.limits.connection.outbound.0,
|
||||||
super::defaults::limit_connections_outbound()
|
super::LimitConnectionsOutbound::default().0,
|
||||||
);
|
);
|
||||||
|
|
||||||
let config: Config = serde_json::from_value(json!({
|
let config: Config = serde_json::from_value(json!({
|
||||||
|
|
@ -688,9 +677,9 @@ mod test {
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.limits.connection.inbound,
|
config.limits.connection.inbound.0,
|
||||||
super::defaults::limit_connections_inbound()
|
super::LimitConnectionsInbound::default().0,
|
||||||
);
|
);
|
||||||
assert_eq!(config.limits.connection.outbound, 1337);
|
assert_eq!(config.limits.connection.outbound.0, 1337);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue