Skip to content

Commit

Permalink
standardize roles CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
plebhash committed May 26, 2024
1 parent 5fef39e commit 50fc30e
Show file tree
Hide file tree
Showing 46 changed files with 1,032 additions and 821 deletions.
338 changes: 310 additions & 28 deletions roles/Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion roles/jd-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ roles_logic_sv2 = { version = "^1.0.0", path = "../../protocols/v2/roles-logic-s
serde = { version = "1.0.89", default-features = false, features = ["derive", "alloc"] }
futures = "0.3.25"
tokio = { version = "1", features = ["full"] }
toml = { version = "0.5.6", git = "https://github.com/diondokter/toml-rs", default-features = false, rev = "c4161aa" }
tracing = { version = "0.1" }
tracing-subscriber = { version = "0.3" }
error_handling = { version = "1.0.0", path = "../../utils/error-handling" }
nohash-hasher = "0.2.0"
key-utils = { version = "^1.0.0", path = "../../utils/key-utils" }
clap = { version = "^4.5.4", features = ["derive"] }
config = { version = "0.14.0", features = ["toml"] }
81 changes: 21 additions & 60 deletions roles/jd-client/src/args.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,29 @@
use std::path::PathBuf;
use crate::lib::{error::JdcResult, jdc_config::JdcConfig};

#[derive(Debug)]
pub struct Args {
pub config_path: PathBuf,
}

enum ArgsState {
Next,
ExpectPath,
Done,
}
use clap::Parser;

enum ArgsResult {
Config(PathBuf),
None,
Help(String),
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[arg(short, long, help = "Path to TOML configuration file")]
config_path: String,
}

impl Args {
const DEFAULT_CONFIG_PATH: &'static str = "jdc-config.toml";
const HELP_MSG: &'static str = "Usage: -h/--help, -c/--config <path|default jdc-config.toml>";

pub fn from_args() -> Result<Self, String> {
let cli_args = std::env::args();

if cli_args.len() == 1 {
println!("Using default config path: {}", Self::DEFAULT_CONFIG_PATH);
println!("{}\n", Self::HELP_MSG);
#[allow(clippy::result_large_err)]
pub fn process_cli_args<'a>() -> JdcResult<'a, JdcConfig> {
let args = Args::parse();
let config = match config::Config::builder()
.add_source(config::File::with_name(&args.config_path))
.build()
{
Ok(cfg) => cfg,
Err(e) => {
tracing::error!("{:?}", e);
std::process::exit(1)
}
};

let config_path = cli_args
.scan(ArgsState::Next, |state, item| {
match std::mem::replace(state, ArgsState::Done) {
ArgsState::Next => match item.as_str() {
"-c" | "--config" => {
*state = ArgsState::ExpectPath;
Some(ArgsResult::None)
}
"-h" | "--help" => Some(ArgsResult::Help(Self::HELP_MSG.to_string())),
_ => {
*state = ArgsState::Next;
let jdc_config: JdcConfig = config.try_deserialize()?;

Some(ArgsResult::None)
}
},
ArgsState::ExpectPath => {
let path = PathBuf::from(item.clone());
if !path.exists() {
return Some(ArgsResult::Help(format!(
"Error: File '{}' does not exist!",
path.display()
)));
}
Some(ArgsResult::Config(path))
}
ArgsState::Done => None,
}
})
.last();
let config_path = match config_path {
Some(ArgsResult::Config(p)) => p,
Some(ArgsResult::Help(h)) => return Err(h),
_ => PathBuf::from(Self::DEFAULT_CONFIG_PATH),
};
Ok(Self { config_path })
}
Ok(jdc_config)
}
96 changes: 46 additions & 50 deletions roles/jd-client/src/lib/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt;
use roles_logic_sv2::mining_sv2::{ExtendedExtranonce, NewExtendedMiningJob, SetCustomMiningJob};
use stratum_common::bitcoin::util::uint::ParseLengthError;

pub type ProxyResult<'a, T> = core::result::Result<T, Error<'a>>;
pub type JdcResult<'a, T> = core::result::Result<T, JdcError<'a>>;

#[derive(Debug)]
pub enum ChannelSendError<'a> {
Expand All @@ -26,12 +26,9 @@ pub enum ChannelSendError<'a> {
}

#[derive(Debug)]
pub enum Error<'a> {
pub enum JdcError<'a> {
VecToSlice32(Vec<u8>),
/// Errors on bad CLI argument input.
BadCliArgs,
/// Errors on bad `toml` deserialize.
BadTomlDeserialize(toml::de::Error),
ConfigError(config::ConfigError),
/// Errors from `binary_sv2` crate.
BinarySv2(binary_sv2::Error),
/// Errors on bad noise handshake.
Expand All @@ -58,12 +55,11 @@ pub enum Error<'a> {
Infallible(std::convert::Infallible),
}

impl<'a> fmt::Display for Error<'a> {
impl<'a> fmt::Display for JdcError<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use Error::*;
use JdcError::*;
match self {
BadCliArgs => write!(f, "Bad CLI arg input"),
BadTomlDeserialize(ref e) => write!(f, "Bad `toml` deserialize: `{:?}`", e),
ConfigError(e) => write!(f, "Config error: {:?}", e),
BinarySv2(ref e) => write!(f, "Binary SV2 error: `{:?}`", e),
CodecNoise(ref e) => write!(f, "Noise error: `{:?}", e),
FramingSv2(ref e) => write!(f, "Framing SV2 error: `{:?}`", e),
Expand All @@ -83,57 +79,57 @@ impl<'a> fmt::Display for Error<'a> {
}
}

impl<'a> From<binary_sv2::Error> for Error<'a> {
impl<'a> From<config::ConfigError> for JdcError<'a> {
fn from(e: config::ConfigError) -> JdcError<'a> {
JdcError::ConfigError(e)
}
}

impl<'a> From<binary_sv2::Error> for JdcError<'a> {
fn from(e: binary_sv2::Error) -> Self {
Error::BinarySv2(e)
JdcError::BinarySv2(e)
}
}

impl<'a> From<codec_sv2::noise_sv2::Error> for Error<'a> {
impl<'a> From<codec_sv2::noise_sv2::Error> for JdcError<'a> {
fn from(e: codec_sv2::noise_sv2::Error) -> Self {
Error::CodecNoise(e)
JdcError::CodecNoise(e)
}
}

impl<'a> From<framing_sv2::Error> for Error<'a> {
impl<'a> From<framing_sv2::Error> for JdcError<'a> {
fn from(e: framing_sv2::Error) -> Self {
Error::FramingSv2(e)
JdcError::FramingSv2(e)
}
}

impl<'a> From<std::io::Error> for Error<'a> {
impl<'a> From<std::io::Error> for JdcError<'a> {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
JdcError::Io(e)
}
}

impl<'a> From<std::num::ParseIntError> for Error<'a> {
impl<'a> From<std::num::ParseIntError> for JdcError<'a> {
fn from(e: std::num::ParseIntError) -> Self {
Error::ParseInt(e)
JdcError::ParseInt(e)
}
}

impl<'a> From<roles_logic_sv2::errors::Error> for Error<'a> {
impl<'a> From<roles_logic_sv2::errors::Error> for JdcError<'a> {
fn from(e: roles_logic_sv2::errors::Error) -> Self {
Error::RolesSv2Logic(e)
}
}

impl<'a> From<toml::de::Error> for Error<'a> {
fn from(e: toml::de::Error) -> Self {
Error::BadTomlDeserialize(e)
JdcError::RolesSv2Logic(e)
}
}

impl<'a> From<async_channel::RecvError> for Error<'a> {
impl<'a> From<async_channel::RecvError> for JdcError<'a> {
fn from(e: async_channel::RecvError) -> Self {
Error::ChannelErrorReceiver(e)
JdcError::ChannelErrorReceiver(e)
}
}

impl<'a> From<tokio::sync::broadcast::error::RecvError> for Error<'a> {
impl<'a> From<tokio::sync::broadcast::error::RecvError> for JdcError<'a> {
fn from(e: tokio::sync::broadcast::error::RecvError) -> Self {
Error::TokioChannelErrorRecv(e)
JdcError::TokioChannelErrorRecv(e)
}
}

Expand All @@ -156,38 +152,38 @@ impl<'a> From<tokio::sync::broadcast::error::RecvError> for Error<'a> {

// *** CHANNEL SENDER ERRORS ***
impl<'a> From<async_channel::SendError<roles_logic_sv2::mining_sv2::SubmitSharesExtended<'a>>>
for Error<'a>
for JdcError<'a>
{
fn from(
e: async_channel::SendError<roles_logic_sv2::mining_sv2::SubmitSharesExtended<'a>>,
) -> Self {
Error::ChannelErrorSender(ChannelSendError::SubmitSharesExtended(e))
JdcError::ChannelErrorSender(ChannelSendError::SubmitSharesExtended(e))
}
}

impl<'a> From<async_channel::SendError<roles_logic_sv2::mining_sv2::SetNewPrevHash<'a>>>
for Error<'a>
for JdcError<'a>
{
fn from(e: async_channel::SendError<roles_logic_sv2::mining_sv2::SetNewPrevHash<'a>>) -> Self {
Error::ChannelErrorSender(ChannelSendError::SetNewPrevHash(e))
JdcError::ChannelErrorSender(ChannelSendError::SetNewPrevHash(e))
}
}

impl<'a> From<async_channel::SendError<(ExtendedExtranonce, u32)>> for Error<'a> {
impl<'a> From<async_channel::SendError<(ExtendedExtranonce, u32)>> for JdcError<'a> {
fn from(e: async_channel::SendError<(ExtendedExtranonce, u32)>) -> Self {
Error::ChannelErrorSender(ChannelSendError::Extranonce(e))
JdcError::ChannelErrorSender(ChannelSendError::Extranonce(e))
}
}

impl<'a> From<async_channel::SendError<NewExtendedMiningJob<'a>>> for Error<'a> {
impl<'a> From<async_channel::SendError<NewExtendedMiningJob<'a>>> for JdcError<'a> {
fn from(e: async_channel::SendError<NewExtendedMiningJob<'a>>) -> Self {
Error::ChannelErrorSender(ChannelSendError::NewExtendedMiningJob(e))
JdcError::ChannelErrorSender(ChannelSendError::NewExtendedMiningJob(e))
}
}

impl<'a> From<async_channel::SendError<SetCustomMiningJob<'a>>> for Error<'a> {
impl<'a> From<async_channel::SendError<SetCustomMiningJob<'a>>> for JdcError<'a> {
fn from(e: async_channel::SendError<SetCustomMiningJob<'a>>) -> Self {
Error::ChannelErrorSender(ChannelSendError::SetCustomMiningJob(e))
JdcError::ChannelErrorSender(ChannelSendError::SetCustomMiningJob(e))
}
}

Expand All @@ -197,32 +193,32 @@ impl<'a>
roles_logic_sv2::template_distribution_sv2::SetNewPrevHash<'a>,
Vec<u8>,
)>,
> for Error<'a>
> for JdcError<'a>
{
fn from(
e: async_channel::SendError<(
roles_logic_sv2::template_distribution_sv2::SetNewPrevHash<'a>,
Vec<u8>,
)>,
) -> Self {
Error::ChannelErrorSender(ChannelSendError::NewTemplate(e))
JdcError::ChannelErrorSender(ChannelSendError::NewTemplate(e))
}
}

impl<'a> From<Vec<u8>> for Error<'a> {
impl<'a> From<Vec<u8>> for JdcError<'a> {
fn from(e: Vec<u8>) -> Self {
Error::VecToSlice32(e)
JdcError::VecToSlice32(e)
}
}

impl<'a> From<ParseLengthError> for Error<'a> {
impl<'a> From<ParseLengthError> for JdcError<'a> {
fn from(e: ParseLengthError) -> Self {
Error::Uint256Conversion(e)
JdcError::Uint256Conversion(e)
}
}

impl<'a> From<std::convert::Infallible> for Error<'a> {
impl<'a> From<std::convert::Infallible> for JdcError<'a> {
fn from(e: std::convert::Infallible) -> Self {
Error::Infallible(e)
JdcError::Infallible(e)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl TryFrom<&CoinbaseOutput> for CoinbaseOutput_ {
}

#[derive(Debug, Deserialize, Clone)]
pub struct ProxyConfig {
pub struct JdcConfig {
pub downstream_address: String,
pub downstream_port: u16,
pub max_supported_version: u16,
Expand Down Expand Up @@ -82,7 +82,7 @@ where
}
}

pub fn get_coinbase_output(config: &ProxyConfig) -> Result<Vec<TxOut>, Error> {
pub fn get_coinbase_output(config: &JdcConfig) -> Result<Vec<TxOut>, Error> {
let mut result = Vec::new();
for coinbase_output_pool in &config.coinbase_outputs {
let coinbase_output: CoinbaseOutput_ = coinbase_output_pool.try_into()?;
Expand Down
6 changes: 3 additions & 3 deletions roles/jd-client/src/lib/job_declarator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub type StdFrame = StandardSv2Frame<Message>;
mod setup_connection;
use setup_connection::SetupConnectionHandler;

use super::{error::Error, proxy_config::ProxyConfig, upstream_sv2::Upstream};
use super::{error::JdcError, jdc_config::JdcConfig, upstream_sv2::Upstream};

#[derive(Debug, Clone)]
pub struct LastDeclareJob {
Expand Down Expand Up @@ -80,10 +80,10 @@ impl JobDeclarator {
pub async fn new(
address: SocketAddr,
authority_public_key: [u8; 32],
config: ProxyConfig,
config: JdcConfig,
up: Arc<Mutex<Upstream>>,
task_collector: Arc<Mutex<Vec<AbortHandle>>>,
) -> Result<Arc<Mutex<Self>>, Error<'static>> {
) -> Result<Arc<Mutex<Self>>, JdcError<'static>> {
let stream = tokio::net::TcpStream::connect(address).await?;
let initiator = Initiator::from_raw_k(authority_public_key)?;
let (mut receiver, mut sender, _, _) =
Expand Down
2 changes: 1 addition & 1 deletion roles/jd-client/src/lib/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod downstream;
pub mod error;
pub mod jdc_config;
pub mod job_declarator;
pub mod proxy_config;
pub mod status;
pub mod template_receiver;
pub mod upstream_sv2;
Expand Down
Loading

0 comments on commit 50fc30e

Please sign in to comment.