igneum/pool/src/config.rs

141 lines
6.1 KiB
Rust

//! Command line and defaults. No clap: the arguments are few and the miner parses by hand too.
use std::path::PathBuf;
#[derive(Clone, Debug)]
pub struct Config {
/// gRPC nodes; the first builds templates and confirms blocks, every one receives found blocks
pub nodes: Vec<String>,
/// The first node's EVM JSON-RPC (payouts, chain id)
pub evm_rpc: String,
/// Where members connect (spec 9.3: 4461 mainnet, 4462 testnet, 4463 devnet)
pub listen: String,
/// The stats API and the web page
pub http: String,
pub data_dir: PathBuf,
/// The payout key file (JSON, created when missing, mode 0600); its address is the pool's coinbase address
pub payout_key: PathBuf,
pub fee_percent: f64,
pub min_payout_ign: f64,
pub pplns_window_blocks: f64,
pub payout_interval_s: u64,
pub dry_run: bool,
pub network: String,
pub share_interval_s: u64,
pub min_shift: u32,
pub max_shift: u32,
pub stale_grace_ms: u64,
/// A pending block older than this many DAA scores and not blue is an orphan
pub orphan_after_daa: u64,
pub name: String,
/// The address members connect to, shown on the page (host:port)
pub public_url: String,
/// Shares sampled at shifts above this are still verified in v0 (spec sample_shift 8 is an allowance, not a duty)
pub verify_threads: usize,
pub snapshot_interval_s: u64,
}
impl Config {
pub fn usage() -> ! {
eprintln!(
"usage: igneum-pool [--node grpc://127.0.0.1:26610]... [--evm-rpc http://127.0.0.1:26790] [--listen 0.0.0.0:4463]\n\
\x20 [--http 127.0.0.1:4480] [--data-dir ./data] [--payout-key <file>] [--fee-percent 1] [--min-payout 1.0]\n\
\x20 [--pplns-window 2.0] [--payout-interval-s 60] [--dry-run] [--network devnet|testnet|mainnet]\n\
\x20 [--share-interval-s 10] [--min-shift 0] [--max-shift 60] [--stale-grace-ms 2000] [--orphan-after-daa 120]\n\
\x20 [--name \"Igneum pool\"] [--public-url host:4463] [--verify-threads 2] [--snapshot-interval-s 15]"
);
std::process::exit(2)
}
pub fn from_args(args: &[String]) -> Config {
let mut c = Config {
nodes: Vec::new(),
evm_rpc: String::new(),
listen: String::new(),
http: "127.0.0.1:4480".into(),
data_dir: PathBuf::from("data"),
payout_key: PathBuf::new(),
fee_percent: 1.0,
min_payout_ign: 1.0,
pplns_window_blocks: 2.0,
payout_interval_s: 60,
dry_run: false,
network: "devnet".into(),
share_interval_s: 10,
min_shift: 0,
max_shift: 60,
stale_grace_ms: 2000,
orphan_after_daa: 120,
name: "Igneum pool".into(),
public_url: String::new(),
verify_threads: 2,
snapshot_interval_s: 15,
};
let mut i = 0;
while i < args.len() {
let a = args[i].as_str();
let mut val = || -> String {
i += 1;
args.get(i).cloned().unwrap_or_else(|| Config::usage())
};
match a {
"--node" => c.nodes.push(val()),
"--evm-rpc" => c.evm_rpc = val(),
"--listen" => c.listen = val(),
"--http" => c.http = val(),
"--data-dir" => c.data_dir = PathBuf::from(val()),
"--payout-key" => c.payout_key = PathBuf::from(val()),
"--fee-percent" => c.fee_percent = val().parse().unwrap_or_else(|_| Config::usage()),
"--min-payout" => c.min_payout_ign = val().parse().unwrap_or_else(|_| Config::usage()),
"--pplns-window" => c.pplns_window_blocks = val().parse().unwrap_or_else(|_| Config::usage()),
"--payout-interval-s" => c.payout_interval_s = val().parse().unwrap_or_else(|_| Config::usage()),
"--dry-run" => c.dry_run = true,
"--network" => c.network = val(),
"--share-interval-s" => c.share_interval_s = val().parse().unwrap_or_else(|_| Config::usage()),
"--min-shift" => c.min_shift = val().parse().unwrap_or_else(|_| Config::usage()),
"--max-shift" => c.max_shift = val().parse().unwrap_or_else(|_| Config::usage()),
"--stale-grace-ms" => c.stale_grace_ms = val().parse().unwrap_or_else(|_| Config::usage()),
"--orphan-after-daa" => c.orphan_after_daa = val().parse().unwrap_or_else(|_| Config::usage()),
"--name" => c.name = val(),
"--public-url" => c.public_url = val(),
"--verify-threads" => c.verify_threads = val().parse::<usize>().unwrap_or_else(|_| Config::usage()).max(1),
"--snapshot-interval-s" => c.snapshot_interval_s = val().parse().unwrap_or_else(|_| Config::usage()),
"-h" | "--help" => Config::usage(),
_ => Config::usage(),
}
i += 1;
}
if c.nodes.is_empty() {
c.nodes.push("grpc://127.0.0.1:26610".into());
}
let (port, evm_port) = match c.network.as_str() {
"mainnet" => (4461, 8545),
"testnet" => (4462, 26890),
_ => (4463, 26790),
};
if c.listen.is_empty() {
c.listen = format!("0.0.0.0:{port}");
}
if c.evm_rpc.is_empty() {
c.evm_rpc = format!("http://127.0.0.1:{evm_port}");
}
if c.payout_key.as_os_str().is_empty() {
c.payout_key = c.data_dir.join("payout-key.json");
}
if c.public_url.is_empty() {
c.public_url = c.listen.replace("0.0.0.0", "127.0.0.1");
}
if c.fee_percent < 0.0 || c.fee_percent > 100.0 || c.pplns_window_blocks <= 0.0 || c.min_shift > c.max_shift {
Config::usage();
}
c
}
pub fn chain_id(&self) -> u64 {
match self.network.as_str() {
"mainnet" => 4461,
"testnet" => 4462,
_ => 4463,
}
}
}