use std::{
net::SocketAddr,
path::{Path, PathBuf},
};
pub use jd_server_sv2::config::{JDSConfig, JDSPartialConfig};
use stratum_apps::{
config_helpers::{opt_path_from_toml, CoinbaseRewardScript},
key_utils::{Secp256k1PublicKey, Secp256k1SecretKey},
stratum_core::bitcoin::{Amount, TxOut},
tp_type::TemplateProviderType,
utils::types::{SharesBatchSize, SharesPerMinute},
};
use crate::error::PoolErrorKind;
#[derive(Clone, Debug, serde::Deserialize)]
pub struct PoolConfig {
listen_address: SocketAddr,
template_provider_type: TemplateProviderType,
authority_public_key: Secp256k1PublicKey,
authority_secret_key: Secp256k1SecretKey,
cert_validity_sec: u64,
coinbase_reward_script: CoinbaseRewardScript,
pool_signature: String,
shares_per_minute: SharesPerMinute,
share_batch_size: SharesBatchSize,
#[serde(default, deserialize_with = "opt_path_from_toml")]
log_file: Option<PathBuf>,
#[serde(default)]
server_id: u16,
#[serde(default)]
supported_extensions: Vec<u16>,
#[serde(default)]
required_extensions: Vec<u16>,
#[serde(default)]
monitoring_address: Option<SocketAddr>,
#[serde(default)]
jds: Option<JDSPartialConfig>,
#[serde(default)]
monitoring_cache_refresh_secs: Option<u64>,
}
impl PoolConfig {
#[allow(clippy::too_many_arguments)]
pub fn new(
pool_connection: ConnectionConfig,
template_provider_type: TemplateProviderType,
authority_config: AuthorityConfig,
coinbase_reward_script: CoinbaseRewardScript,
shares_per_minute: SharesPerMinute,
share_batch_size: SharesBatchSize,
server_id: u16,
supported_extensions: Vec<u16>,
required_extensions: Vec<u16>,
monitoring_address: Option<SocketAddr>,
monitoring_cache_refresh_secs: Option<u64>,
jds: Option<JDSPartialConfig>,
) -> Self {
Self {
listen_address: pool_connection.listen_address,
template_provider_type,
authority_public_key: authority_config.public_key,
authority_secret_key: authority_config.secret_key,
cert_validity_sec: pool_connection.cert_validity_sec,
coinbase_reward_script,
pool_signature: pool_connection.signature,
shares_per_minute,
share_batch_size,
log_file: None,
server_id,
supported_extensions,
required_extensions,
monitoring_address,
monitoring_cache_refresh_secs,
jds,
}
}
pub fn coinbase_reward_script(&self) -> &CoinbaseRewardScript {
&self.coinbase_reward_script
}
pub fn listen_address(&self) -> &SocketAddr {
&self.listen_address
}
pub fn authority_public_key(&self) -> &Secp256k1PublicKey {
&self.authority_public_key
}
pub fn authority_secret_key(&self) -> &Secp256k1SecretKey {
&self.authority_secret_key
}
pub fn cert_validity_sec(&self) -> u64 {
self.cert_validity_sec
}
pub fn pool_signature(&self) -> &String {
&self.pool_signature
}
pub fn template_provider_type(&self) -> &TemplateProviderType {
&self.template_provider_type
}
pub fn share_batch_size(&self) -> usize {
self.share_batch_size
}
pub fn set_coinbase_reward_script(&mut self, coinbase_output: CoinbaseRewardScript) {
self.coinbase_reward_script = coinbase_output;
}
pub fn shares_per_minute(&self) -> f32 {
self.shares_per_minute
}
pub fn supported_extensions(&self) -> &[u16] {
&self.supported_extensions
}
pub fn required_extensions(&self) -> &[u16] {
&self.required_extensions
}
pub fn set_log_dir(&mut self, log_dir: Option<PathBuf>) {
if let Some(dir) = log_dir {
self.log_file = Some(dir);
}
}
pub fn log_dir(&self) -> Option<&Path> {
self.log_file.as_deref()
}
pub fn server_id(&self) -> u16 {
self.server_id
}
pub fn get_txout(&self) -> TxOut {
TxOut {
value: Amount::from_sat(0),
script_pubkey: self.coinbase_reward_script.script_pubkey().to_owned(),
}
}
pub fn monitoring_address(&self) -> Option<SocketAddr> {
self.monitoring_address
}
pub fn monitoring_cache_refresh_secs(&self) -> Option<u64> {
self.monitoring_cache_refresh_secs
}
#[allow(clippy::result_large_err)]
pub fn build_jds_config(&self) -> Result<Option<JDSConfig>, PoolErrorKind> {
let Some(jds_partial) = self.jds.clone() else {
return Ok(None);
};
let jds_config = JDSConfig::from_partial(
jds_partial,
self.authority_public_key,
self.authority_secret_key,
self.cert_validity_sec,
self.coinbase_reward_script.clone(),
);
Ok(Some(jds_config))
}
}
pub struct AuthorityConfig {
pub public_key: Secp256k1PublicKey,
pub secret_key: Secp256k1SecretKey,
}
impl AuthorityConfig {
pub fn new(public_key: Secp256k1PublicKey, secret_key: Secp256k1SecretKey) -> Self {
Self {
public_key,
secret_key,
}
}
}
pub struct ConnectionConfig {
listen_address: SocketAddr,
cert_validity_sec: u64,
signature: String,
}
impl ConnectionConfig {
pub fn new(listen_address: SocketAddr, cert_validity_sec: u64, signature: String) -> Self {
Self {
listen_address,
cert_validity_sec,
signature,
}
}
}