From 7430fea0f5985e9b154544677472c440d77abf21 Mon Sep 17 00:00:00 2001 From: fi3 Date: Mon, 9 Mar 2026 16:44:03 +0100 Subject: [PATCH 1/4] Upgrade add limit to how many time a dowstream can change the proxy token. Add a configurable limit for proxy token changes, with a default value of 1, so token rotation is controlled instead of being effectively unbounded. Load the new setting from the existing configuration pipeline and keep the enforcement state in a shared translator-side tracker rather than inside each SV1 downstream object. This is important because the limit must apply across all downstream connections handled by the same proxy/upstream session, not restart from zero for every new downstream connection. When a downstream sends `mining.authorize` with a password different from the current proxy token, increment the shared counter and update the shared token state only while the change is still within the configured limit. Once the counter reaches `limit + 1`, do not send the special `SetCustomMiningJob` message upstream and immediately close the offending downstream connection. Also keep each downstream's local token view synchronized with the shared token state, preserve normal behavior for unchanged tokens and duplicate authorize calls, and add tests covering allowed token updates, unchanged authorize flows, and cross-downstream limit enforcement. --- src/config.rs | 20 + src/ingress/sv1_ingress.rs | 15 +- src/lib.rs | 2 + .../downstream/accept_connection.rs | 2 + src/translator/downstream/diff_management.rs | 2 + src/translator/downstream/downstream.rs | 435 +++++++++++++++++- .../downstream/receive_from_downstream.rs | 18 +- src/translator/error.rs | 2 + 8 files changed, 466 insertions(+), 30 deletions(-) diff --git a/src/config.rs b/src/config.rs index 1317376a..03e05986 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,6 +43,8 @@ struct Args { adjustment_interval: Option, #[clap(long)] token: Option, + #[clap(long = "max-token-changes-per-connection")] + max_token_changes_per_connection: Option, #[clap(long)] tp_address: Option, #[clap(long)] @@ -64,6 +66,7 @@ struct Args { #[derive(Serialize, Deserialize)] struct ConfigFile { token: Option, + max_token_changes_per_connection: Option, tp_address: Option, interval: Option, delay: Option, @@ -85,6 +88,7 @@ impl ConfigFile { pub fn default() -> Self { ConfigFile { token: None, + max_token_changes_per_connection: None, tp_address: None, interval: None, delay: None, @@ -107,6 +111,7 @@ impl ConfigFile { #[derive(Debug)] pub struct Configuration { token: Option, + max_token_changes_per_connection: u32, tp_address: Option, interval: u64, delay: u64, @@ -217,6 +222,10 @@ impl Configuration { Self::cfg().token.clone() } + pub fn max_token_changes_per_connection() -> u32 { + CONFIG.max_token_changes_per_connection + } + pub fn tp_address() -> Option { Self::cfg().tp_address.clone() } @@ -349,6 +358,16 @@ impl Configuration { .or_else(|| std::env::var("TOKEN").ok()); println!("User Token: {token:?}"); + let max_token_changes_per_connection = args + .max_token_changes_per_connection + .or(config.max_token_changes_per_connection) + .or_else(|| { + std::env::var("MAX_TOKEN_CHANGES_PER_CONNECTION") + .ok() + .and_then(|s| s.parse().ok()) + }) + .unwrap_or(1); + let signature = match args.signature { Some(s) => { if s.len() == 2 { @@ -469,6 +488,7 @@ impl Configuration { Configuration { token, + max_token_changes_per_connection, tp_address, interval, delay, diff --git a/src/ingress/sv1_ingress.rs b/src/ingress/sv1_ingress.rs index 196b29e6..6ed0a12d 100644 --- a/src/ingress/sv1_ingress.rs +++ b/src/ingress/sv1_ingress.rs @@ -26,11 +26,7 @@ pub fn start_listen_for_downstream( let down_addr: String = Configuration::downstream_listening_addr() .unwrap_or(crate::DEFAULT_LISTEN_ADDRESS.to_string()); let downstream_addr: SocketAddr = down_addr.parse().expect("Invalid listen address"); - info!( - "Trying to bind to address {} for downstream(miner) connections", - downstream_addr - ); - let downstream_listener = TcpListener::bind(downstream_addr) + let downstream_listener = bind_downstream_listener(downstream_addr) .await .expect("impossible to bind downstream"); info!( @@ -49,6 +45,15 @@ pub fn start_listen_for_downstream( }) .into() } + +pub async fn bind_downstream_listener(downstream_addr: SocketAddr) -> std::io::Result { + info!( + "Trying to bind to address {} for downstream(miner) connections", + downstream_addr + ); + TcpListener::bind(downstream_addr).await +} + struct Downstream {} impl Downstream { diff --git a/src/lib.rs b/src/lib.rs index 6174e270..6354ad1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,8 @@ mod shared; mod shutdown; mod translator; +pub use ingress::sv1_ingress::bind_downstream_listener; + const TRANSLATOR_BUFFER_SIZE: usize = 32; const MIN_EXTRANONCE_SIZE: u16 = 6; const MIN_EXTRANONCE2_SIZE: u16 = 5; diff --git a/src/translator/downstream/accept_connection.rs b/src/translator/downstream/accept_connection.rs index d84f878d..07079b5a 100644 --- a/src/translator/downstream/accept_connection.rs +++ b/src/translator/downstream/accept_connection.rs @@ -26,6 +26,7 @@ pub async fn start_accept_connection( upstream_difficulty_config: Arc>, mut downstreams: Receiver<(Sender, Receiver, IpAddr)>, stats_sender: crate::api::stats::StatsSender, + shared_token_state: Arc>, tx_update_token: Sender, ) -> Result<(), Error<'static>> { let handle = { @@ -102,6 +103,7 @@ pub async fn start_accept_connection( task_manager.clone(), initial_difficulty, stats_sender.clone(), + shared_token_state.clone(), tx_update_token.clone(), ) .await diff --git a/src/translator/downstream/diff_management.rs b/src/translator/downstream/diff_management.rs index 1d1606ec..ed2661dd 100644 --- a/src/translator/downstream/diff_management.rs +++ b/src/translator/downstream/diff_management.rs @@ -470,6 +470,8 @@ mod test { Arc::new(Mutex::new(upstream_config)), crate::api::stats::StatsSender::new(), first_job, + String::new(), + 1, tx_update_token, ); downstream.difficulty_mgmt.estimated_downstream_hash_rate = start_hashrate as f32; diff --git a/src/translator/downstream/downstream.rs b/src/translator/downstream/downstream.rs index 938a6ed2..707203de 100644 --- a/src/translator/downstream/downstream.rs +++ b/src/translator/downstream/downstream.rs @@ -33,6 +33,7 @@ use roles_logic_sv2::{ use rand::Rng; use server_to_client::Notify; use std::{ + cell::Cell, collections::{hash_map::Entry, HashMap, VecDeque}, net::IpAddr, sync::Arc, @@ -124,12 +125,28 @@ pub struct Downstream { pub user_agent: std::cell::RefCell, // RefCell is used here because `handle_subscribe` and `handle_authorize` take &self not &mut self and we need to mutate user_agent pub token: Arc>, tx_update_token: Sender, + disconnect_requested: Cell, + shared_token_state: Arc>, +} + +#[derive(Debug)] +pub(super) struct TokenChangeTracker { + current_token: String, + change_count: u32, + max_token_changes_per_connection: u32, +} + +#[derive(Debug, PartialEq, Eq)] +enum AuthorizeTokenAction { + KeepCurrent(String), + Update(String), + Disconnect, } impl Downstream { /// Instantiate a new `Downstream`. #[allow(clippy::too_many_arguments)] - pub async fn new_downstream( + pub(super) async fn new_downstream( connection_id: u32, tx_sv1_bridge: Sender, rx_sv1_notify: broadcast::Receiver>, @@ -143,6 +160,7 @@ impl Downstream { task_manager: Arc>, initial_difficulty: f32, stats_sender: StatsSender, + shared_token_state: Arc>, tx_update_token: Sender, ) { assert!(last_notify.is_some()); @@ -190,7 +208,9 @@ impl Downstream { }; let token = Arc::new(Mutex::new( - Configuration::token().expect("Token is not set"), + shared_token_state + .safe_lock(|state| state.current_token.clone()) + .unwrap_or_else(|_| Configuration::token().expect("Token is not set")), )); let downstream = Arc::new(Mutex::new(Downstream { @@ -212,6 +232,8 @@ impl Downstream { user_agent: std::cell::RefCell::new(String::new()), token, tx_update_token, + disconnect_requested: Cell::new(false), + shared_token_state, })); if let Err(e) = start_receive_downstream( @@ -289,6 +311,10 @@ impl Downstream { stats_sender: StatsSender, tx_update_token: Sender, ) -> Result> { + let shared_token_state = Arc::new(Mutex::new(TokenChangeTracker::new( + Configuration::token().expect("Token is not set"), + Configuration::max_token_changes_per_connection(), + ))); let task_manager = TaskManager::initialize(); let abortable = task_manager .safe_lock(|t| t.get_aborter()) @@ -302,6 +328,7 @@ impl Downstream { upstream_difficulty_config, downstreams, stats_sender, + shared_token_state, tx_update_token, ) .await @@ -323,7 +350,14 @@ impl Downstream { // `handle_message` in `IsServer` trait + calls `handle_request` // TODO: Map err from V1Error to Error::V1Error - let response = self_.safe_lock(|s| s.handle_message(message_sv1.clone()))?; + let (response, disconnect_requested) = self_.safe_lock(|s| { + let response = s.handle_message(message_sv1.clone()); + let disconnect_requested = s.take_disconnect_request(); + (response, disconnect_requested) + })?; + if disconnect_requested { + return Err(Error::DisconnectDownstream); + } match response { Ok(res) => { if let Some(r) = res { @@ -382,6 +416,27 @@ impl Downstream { ProxyState::update_downstream_state(DownstreamType::TranslatorDownstream); } } + + fn handle_authorize_token(&self, new_token: &str) -> AuthorizeTokenAction { + let action = self + .shared_token_state + .safe_lock(|state| state.handle_authorize_token(new_token)) + // Here we can not update the token so downstream risk to mine for someone else, we + // could do unwrap_or_else and return Discconnect that will discconnect the downstream + // but if the mutex is poisoned this will keep happening for all the new downstream do + // we are keeping up a non fully functional proxy. Better to fail. + .unwrap(); + if let AuthorizeTokenAction::Update(_) = action { + self.token + .safe_lock(|token| *token = new_token.to_string()) + .unwrap(); + } + action + } + + fn take_disconnect_request(&self) -> bool { + self.disconnect_requested.replace(false) + } #[cfg(test)] #[allow(clippy::too_many_arguments)] pub fn new( @@ -397,11 +452,55 @@ impl Downstream { upstream_difficulty_config: Arc>, stats_sender: StatsSender, first_job: Notify<'static>, + initial_token: String, + max_token_changes_per_connection: u32, + tx_update_token: Sender, + ) -> Self { + let shared_token_state = Arc::new(Mutex::new(TokenChangeTracker::new( + initial_token.clone(), + max_token_changes_per_connection, + ))); + let token = Arc::new(Mutex::new(initial_token)); + Self::new_with_shared_token_state( + connection_id, + authorized_names, + extranonce1, + version_rolling_mask, + version_rolling_min_bit, + tx_sv1_bridge, + tx_outgoing, + extranonce2_len, + difficulty_mgmt, + upstream_difficulty_config, + stats_sender, + first_job, + token, + shared_token_state, + tx_update_token, + ) + } + + #[cfg(test)] + #[allow(clippy::too_many_arguments)] + fn new_with_shared_token_state( + connection_id: u32, + authorized_names: Vec, + extranonce1: Vec, + version_rolling_mask: Option, + version_rolling_min_bit: Option, + tx_sv1_bridge: Sender, + tx_outgoing: Sender, + extranonce2_len: usize, + difficulty_mgmt: DownstreamDifficultyConfig, + upstream_difficulty_config: Arc>, + stats_sender: StatsSender, + first_job: Notify<'static>, + token: Arc>, + shared_token_state: Arc>, tx_update_token: Sender, ) -> Self { use crate::monitor::shares::SharesMonitor; - let token = Arc::new(Mutex::new(String::new())); Downstream { connection_id, authorized_names, @@ -421,7 +520,36 @@ impl Downstream { user_agent: std::cell::RefCell::new(String::new()), token, tx_update_token, + disconnect_requested: Cell::new(false), + shared_token_state, + } + } +} + +impl TokenChangeTracker { + fn new(current_token: String, max_token_changes_per_connection: u32) -> Self { + Self { + current_token, + change_count: 0, + max_token_changes_per_connection, + } + } + + fn handle_authorize_token(&mut self, new_token: &str) -> AuthorizeTokenAction { + if self.max_token_changes_per_connection == 0 { + return AuthorizeTokenAction::KeepCurrent(self.current_token.clone()); } + if new_token == self.current_token { + return AuthorizeTokenAction::KeepCurrent(self.current_token.clone()); + } + + self.change_count = self.change_count.saturating_add(1); + if self.change_count > self.max_token_changes_per_connection || new_token.is_empty() { + return AuthorizeTokenAction::Disconnect; + } + + self.current_token = new_token.to_string(); + AuthorizeTokenAction::Update(self.current_token.clone()) } } @@ -480,7 +608,25 @@ impl IsServer<'static> for Downstream { if self.authorized_names.is_empty() { let new_token = request.password.clone(); if !new_token.is_empty() { - if let Err(e) = self.token.safe_lock(|t| *t = new_token.clone()) { + let token = match self.handle_authorize_token(&request.password) { + AuthorizeTokenAction::KeepCurrent(token) => token, + AuthorizeTokenAction::Update(token) => { + let tx_update_token = self.tx_update_token.clone(); + let token_to_send = token.clone(); + tokio::spawn(async move { + if tx_update_token.send(token_to_send).await.is_err() { + error!("Failed to send token update to upstream"); + ProxyState::update_upstream_state(UpstreamType::TranslatorUpstream); + } + }); + token + } + AuthorizeTokenAction::Disconnect => { + self.disconnect_requested.set(true); + return false; + } + }; + if let Err(e) = self.token.safe_lock(|t| *t = token.clone()) { error!("Failed to update token: {:?}", e); ProxyState::update_downstream_state(DownstreamType::TranslatorDownstream); } @@ -492,6 +638,12 @@ impl IsServer<'static> for Downstream { ProxyState::update_upstream_state(UpstreamType::TranslatorUpstream); } }); + } else if self + .shared_token_state + .safe_lock(|s| s.max_token_changes_per_connection == 0) + .unwrap() + { + info!("Skip token check, max_token_changes_per_connection set to 0"); } else { error!("Downstream is expected to carry a token"); return false; @@ -849,18 +1001,261 @@ impl CircularBuffer { } } -//#[cfg(test)] -//mod tests { -// use super::*; -// -// #[test] -// fn gets_difficulty_from_target() { -// let target = vec![ -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 255, 127, -// 0, 0, 0, 0, 0, -// ]; -// let actual = Downstream::difficulty_from_target(target).unwrap(); -// let expect = 512.0; -// assert_eq!(actual, expect); -// } -//} +#[cfg(test)] +mod tests { + use super::*; + use crate::translator::upstream::diff_management::UpstreamDifficultyConfig; + use rand::Rng; + use sv1_api::utils::{MerkleNode, PrevHash}; + use tokio::sync::mpsc::{channel, Receiver}; + + fn test_first_job() -> Notify<'static> { + let random_str = rand::thread_rng().gen::<[u8; 32]>().to_vec(); + Notify { + job_id: "1".to_string(), + prev_hash: PrevHash::try_from("0".repeat(64).as_str()).unwrap(), + coin_base1: "ffff".try_into().unwrap(), + coin_base2: "ffff".try_into().unwrap(), + merkle_branch: vec![MerkleNode::try_from(random_str).unwrap()], + version: HexU32Be(1), + bits: HexU32Be(1), + time: HexU32Be(1), + clean_jobs: true, + } + } + + fn build_test_downstream_with_shared_state( + connection_id: u32, + shared_token_state: Arc>, + tx_update_token: Sender, + ) -> (Arc>, Receiver) { + let mut current_difficulties = VecDeque::new(); + current_difficulties.push_back(1.0); + + let downstream_conf = DownstreamDifficultyConfig { + estimated_downstream_hash_rate: 0.0, + submits: VecDeque::new(), + pid_controller: Pid::new(10.0, 1.0), + current_difficulties, + initial_difficulty: 1.0, + }; + let upstream_config = UpstreamDifficultyConfig { + channel_diff_update_interval: 60, + channel_nominal_hashrate: 0.0, + }; + let (tx_sv1_submit, _rx_sv1_submit) = channel(10); + let (tx_outgoing, rx_outgoing) = channel(10); + let token = Arc::new(Mutex::new( + shared_token_state + .safe_lock(|state| state.current_token.clone()) + .unwrap(), + )); + + let downstream = Downstream::new_with_shared_token_state( + connection_id, + vec![], + vec![], + None, + None, + tx_sv1_submit, + tx_outgoing, + 0, + downstream_conf, + Arc::new(Mutex::new(upstream_config)), + crate::api::stats::StatsSender::new(), + test_first_job(), + token, + shared_token_state, + tx_update_token, + ); + + (Arc::new(Mutex::new(downstream)), rx_outgoing) + } + + #[allow(clippy::type_complexity)] + fn build_test_downstream( + initial_token: &str, + max_token_changes_per_connection: u32, + ) -> ( + Arc>, + Receiver, + Receiver, + Arc>, + ) { + let shared_token_state = Arc::new(Mutex::new(TokenChangeTracker::new( + initial_token.to_string(), + max_token_changes_per_connection, + ))); + let (tx_update_token, rx_update_token) = channel(10); + let (downstream, rx_outgoing) = + build_test_downstream_with_shared_state(1, shared_token_state.clone(), tx_update_token); + + (downstream, rx_outgoing, rx_update_token, shared_token_state) + } + + fn authorize_request(id: u64, name: &str, password: &str) -> json_rpc::Message { + client_to_server::Authorize { + id, + name: name.to_string(), + password: password.to_string(), + } + .into() + } + + #[tokio::test] + async fn changed_token_updates_shared_state_until_limit() { + let (downstream, _rx_outgoing, _rx_update_token, shared_token_state) = + build_test_downstream("token-a", 1); + + let action = downstream + .safe_lock(|d| d.handle_authorize_token("token-b")) + .unwrap(); + let (token, disconnect_requested) = downstream + .safe_lock(|d| { + ( + d.token.safe_lock(|t| t.clone()).unwrap(), + d.disconnect_requested.get(), + ) + }) + .unwrap(); + let (current_token, change_count) = shared_token_state + .safe_lock(|state| (state.current_token.clone(), state.change_count)) + .unwrap(); + + assert_eq!(action, AuthorizeTokenAction::Update("token-b".to_string())); + assert_eq!(token, "token-b"); + assert_eq!(current_token, "token-b"); + assert_eq!(change_count, 1); + assert!(!disconnect_requested); + } + + #[tokio::test] + async fn zero_token_change_limit_ignores_requested_token_changes() { + let (downstream, _rx_outgoing, _rx_update_token, shared_token_state) = + build_test_downstream("token-a", 0); + let auth_m = client_to_server::Authorize { + id: 1, + name: "name".to_string(), + password: "token-b".to_string(), + }; + + downstream + .safe_lock(|d| d.handle_authorize(&auth_m)) + .unwrap(); + let (token, disconnect_requested) = downstream + .safe_lock(|d| { + ( + d.token.safe_lock(|t| t.clone()).unwrap(), + d.disconnect_requested.get(), + ) + }) + .unwrap(); + let (current_token, change_count) = shared_token_state + .safe_lock(|state| (state.current_token.clone(), state.change_count)) + .unwrap(); + + assert_eq!(token, "token-a"); + assert_eq!(current_token, "token-a"); + assert_eq!(change_count, 0); + assert!(!disconnect_requested); + } + + #[tokio::test] + async fn unchanged_token_does_not_increment_shared_counter_and_authorize_is_deduplicated() { + let (downstream, _rx_outgoing, _rx_update_token, shared_token_state) = + build_test_downstream("token-a", 1); + + let first = downstream + .safe_lock(|d| { + let action = d.handle_authorize_token("token-a"); + action + }) + .unwrap(); + let second = downstream + .safe_lock(|d| { + let action = d.handle_authorize_token("token-a"); + d.authorize("worker-b"); + action + }) + .unwrap(); + let (_, token) = downstream + .safe_lock(|d| { + ( + d.authorized_names.clone(), + d.token.safe_lock(|t| t.clone()).unwrap(), + ) + }) + .unwrap(); + let (current_token, change_count) = shared_token_state + .safe_lock(|state| (state.current_token.clone(), state.change_count)) + .unwrap(); + + assert_eq!( + first, + AuthorizeTokenAction::KeepCurrent("token-a".to_string()) + ); + assert_eq!( + second, + AuthorizeTokenAction::KeepCurrent("token-a".to_string()) + ); + assert_eq!(change_count, 0); + assert_eq!(current_token, "token-a"); + assert_eq!(token, "token-a"); + } + + #[tokio::test] + async fn exceeding_token_change_limit_disconnects_across_downstreams_without_response_or_upstream_update( + ) { + let shared_token_state = Arc::new(Mutex::new(TokenChangeTracker::new( + "token-a".to_string(), + 1, + ))); + let (tx_update_token, mut rx_update_token) = channel(10); + let (first_downstream, _first_rx_outgoing) = build_test_downstream_with_shared_state( + 1, + shared_token_state.clone(), + tx_update_token.clone(), + ); + + let first_action = first_downstream + .safe_lock(|d| { + let action = d.handle_authorize_token("token-b"); + d.authorize("worker-a"); + action + }) + .unwrap(); + assert_eq!( + first_action, + AuthorizeTokenAction::Update("token-b".to_string()) + ); + + let (second_downstream, mut second_rx_outgoing) = + build_test_downstream_with_shared_state(2, shared_token_state.clone(), tx_update_token); + let result = Downstream::handle_incoming_sv1( + second_downstream.clone(), + authorize_request(7, "worker-b", "token-c"), + ) + .await; + + let (token, disconnect_requested) = second_downstream + .safe_lock(|d| { + ( + d.token.safe_lock(|t| t.clone()).unwrap(), + d.disconnect_requested.get(), + ) + }) + .unwrap(); + let (current_token, change_count) = shared_token_state + .safe_lock(|state| (state.current_token.clone(), state.change_count)) + .unwrap(); + + dbg!(shared_token_state); + assert!(matches!(result, Err(Error::DisconnectDownstream))); + assert_eq!(token, "token-b"); + assert_eq!(current_token, "token-b"); + assert_eq!(change_count, 2); + assert!(!disconnect_requested); + assert!(second_rx_outgoing.try_recv().is_err()); + assert!(rx_update_token.try_recv().is_err()); + } +} diff --git a/src/translator/downstream/receive_from_downstream.rs b/src/translator/downstream/receive_from_downstream.rs index 59e31840..06f2b87b 100644 --- a/src/translator/downstream/receive_from_downstream.rs +++ b/src/translator/downstream/receive_from_downstream.rs @@ -33,11 +33,19 @@ pub async fn start_receive_downstream( } } - if let Err(error) = - Downstream::handle_incoming_sv1(downstream.clone(), incoming).await - { - error!("Failed to handle incoming sv1 msg: {:?}", error); - break; + match Downstream::handle_incoming_sv1(downstream.clone(), incoming).await { + Ok(()) => {} + Err(Error::DisconnectDownstream) => { + warn!( + "Downstream {} exceeded the token change limit. Closing connection.", + connection_id + ); + break; + } + Err(error) => { + error!("Failed to handle incoming sv1 msg: {:?}", error); + break; + } }; } else { // Message received could not be converted to rpc message diff --git a/src/translator/error.rs b/src/translator/error.rs index 0d45f2da..20d88498 100644 --- a/src/translator/error.rs +++ b/src/translator/error.rs @@ -28,6 +28,7 @@ pub enum Error<'a> { ImpossibleToOpenChannnel, #[allow(clippy::enum_variant_names)] AsyncChannelError, + DisconnectDownstream, } impl From for Error<'_> { @@ -47,6 +48,7 @@ impl fmt::Display for Error<'_> { Error::Infallible(e) => write!(f, "Infallible {e}"), Error::ImpossibleToOpenChannnel => write!(f, "ImpossibleToOpenChannnel"), Error::AsyncChannelError => write!(f, "AsyncChannelError"), + Error::DisconnectDownstream => write!(f, "DisconnectDownstream"), Error::TranslatorUpstreamMutexPoisoned => write!(f, "TranslatorUpstreamMutexPoisoned"), Error::TranslatorDiffConfigMutexPoisoned => { write!(f, "TranslatorDiffConfigMutexPoisoned") From 10f55de23ddd0ee0cdf4118f9565b614a802ab59 Mon Sep 17 00:00:00 2001 From: fi3 Date: Tue, 24 Mar 2026 13:14:08 +0100 Subject: [PATCH 2/4] Upate default max token change per connection to 0 --- src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 03e05986..45e337a3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -366,7 +366,7 @@ impl Configuration { .ok() .and_then(|s| s.parse().ok()) }) - .unwrap_or(1); + .unwrap_or(0); let signature = match args.signature { Some(s) => { From 78ee1272f0a3a576e8dd7751e3aba6d587859a41 Mon Sep 17 00:00:00 2001 From: fi3 Date: Tue, 24 Mar 2026 13:21:10 +0100 Subject: [PATCH 3/4] Fix clippy warning --- src/translator/downstream/downstream.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/translator/downstream/downstream.rs b/src/translator/downstream/downstream.rs index 707203de..1a49ad3c 100644 --- a/src/translator/downstream/downstream.rs +++ b/src/translator/downstream/downstream.rs @@ -1167,8 +1167,7 @@ mod tests { let first = downstream .safe_lock(|d| { - let action = d.handle_authorize_token("token-a"); - action + d.handle_authorize_token("token-a") }) .unwrap(); let second = downstream From 4e491b99abfe6f6f4c00cfc21283f2da302fb49d Mon Sep 17 00:00:00 2001 From: fi3 Date: Sat, 25 Apr 2026 10:42:52 +0200 Subject: [PATCH 4/4] Fix minor fixes --- Cargo.lock | 1242 ++++++++++++++++++++++- src/config.rs | 5 +- src/translator/downstream/downstream.rs | 4 +- tests/library_init.rs | 1 + 4 files changed, 1201 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 162309b8..50ab1360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aead" version = "0.5.2" @@ -37,6 +43,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -46,6 +64,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "anstream" version = "1.0.0" @@ -102,12 +126,38 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + [[package]] name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-recursion" version = "1.1.1" @@ -119,6 +169,17 @@ dependencies = [ "syn", ] +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -193,6 +254,18 @@ dependencies = [ "bitcoin_hashes 0.14.1", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -216,7 +289,7 @@ name = "binary_codec_sv2" version = "2.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "buffer_sv2", + "buffer_sv2 2.0.0", "hex", ] @@ -226,7 +299,16 @@ version = "2.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ "binary_codec_sv2", - "derive_codec_sv2", + "derive_codec_sv2 2.0.0", +] + +[[package]] +name = "binary_sv2" +version = "5.0.1" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "buffer_sv2 3.0.1", + "derive_codec_sv2 1.1.2", ] [[package]] @@ -236,6 +318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e499f9fc0407f50fe98af744ab44fa67d409f76b6772e1689ec8485eb0c0f66" dependencies = [ "base58ck", + "base64 0.21.7", "bech32", "bitcoin-internals 0.3.0", "bitcoin-io", @@ -247,6 +330,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin-capnp-types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e20759e30b46af17a13f2e34c9e090c3672938b5a0c22358cba971d1a8f5d492" +dependencies = [ + "capnp", + "capnpc", +] + [[package]] name = "bitcoin-internals" version = "0.2.0" @@ -278,6 +371,22 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin_core_sv2" +version = "0.1.1" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "bitcoin-capnp-types", + "capnp", + "capnp-rpc", + "stratum-core", + "tokio", + "tokio-util", + "tracing", + "tracing-subscriber", +] + [[package]] name = "bitcoin_hashes" version = "0.3.2" @@ -313,6 +422,9 @@ name = "bitflags" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +dependencies = [ + "serde_core", +] [[package]] name = "bitvec" @@ -361,6 +473,14 @@ dependencies = [ "aes-gcm", ] +[[package]] +name = "buffer_sv2" +version = "3.0.1" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "aes-gcm", +] + [[package]] name = "bumpalo" version = "3.20.2" @@ -385,6 +505,46 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +[[package]] +name = "capnp" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e92edec8974fcd7ece90bb021db782abe14a61c10c817f197f700fef7430eb8" +dependencies = [ + "embedded-io", +] + +[[package]] +name = "capnp-futures" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d04478adeb234836f886ec554a0d96e3af3a939ba7b3962af5addddf7ab71231" +dependencies = [ + "capnp", + "futures-channel", + "futures-util", +] + +[[package]] +name = "capnp-rpc" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e9c19ef52ff1b9c9822fb21bfa68a72bc58711676295ff06eb88e64c7877f7" +dependencies = [ + "capnp", + "capnp-futures", + "futures", +] + +[[package]] +name = "capnpc" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da96dcb0a0e0c526daf42bac55e1550f18ad973df9ef9ba75204f332c80ad16" +dependencies = [ + "capnp", +] + [[package]] name = "cc" version = "1.2.57" @@ -431,6 +591,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "channels_sv2" +version = "5.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "bitcoin", + "mining_sv2 9.0.0", + "primitive-types", + "template_distribution_sv2 5.0.0", + "tracing", +] + [[package]] name = "cipher" version = "0.4.4" @@ -487,11 +660,24 @@ name = "codec_sv2" version = "2.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", - "buffer_sv2", + "binary_sv2 2.0.0", + "buffer_sv2 2.0.0", "const_sv2", - "framing_sv2", - "noise_sv2", + "framing_sv2 4.0.0", + "noise_sv2 1.2.1", + "rand 0.8.5", + "tracing", +] + +[[package]] +name = "codec_sv2" +version = "5.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "buffer_sv2 3.0.1", + "framing_sv2 6.0.1", + "noise_sv2 1.4.2", "rand 0.8.5", "tracing", ] @@ -507,10 +693,46 @@ name = "common_messages_sv2" version = "4.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", + "binary_sv2 2.0.0", "const_sv2", ] +[[package]] +name = "common_messages_sv2" +version = "7.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "config" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" +dependencies = [ + "async-trait", + "convert_case", + "json5", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust2", +] + [[package]] name = "console" version = "0.15.11" @@ -530,6 +752,26 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + [[package]] name = "const_format" version = "0.2.35" @@ -555,6 +797,15 @@ name = "const_sv2" version = "3.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -581,6 +832,45 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "corepc-client" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c6b8eaeccd3df6c1f264cd6ff8cf5df7d056029473ce9551b2a6257832d38e0" +dependencies = [ + "bitcoin", + "corepc-types", + "jsonrpc", + "log", + "serde", + "serde_json", +] + +[[package]] +name = "corepc-node" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bcc6e09458f052024ec36e4728bd5619e248643da6175876eb3b10ca6d4d86" +dependencies = [ + "anyhow", + "corepc-client", + "log", + "serde_json", + "tempfile", + "which", +] + +[[package]] +name = "corepc-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4bc664fdaeeae1eaf459edb88650af3009b758010fc69b423c5b38142446cfb" +dependencies = [ + "bitcoin", + "serde", + "serde_json", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -590,6 +880,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -696,8 +995,8 @@ name = "demand-share-accounting-ext" version = "0.0.13" source = "git+https://github.com/demand-open-source/share-accounting-ext#c661e936264cd8cc6b13b51fc06a79e04a6ae76e" dependencies = [ - "binary_sv2", - "framing_sv2", + "binary_sv2 2.0.0", + "framing_sv2 4.0.0", "roles_logic_sv2", ] @@ -706,8 +1005,8 @@ name = "demand-sv2-connection" version = "0.0.8" source = "git+https://github.com/demand-open-source/demand-sv2-connection#edeb677c9e2aa07de99f6b7a9ce5b627ff0e1899" dependencies = [ - "binary_sv2", - "codec_sv2", + "binary_sv2 2.0.0", + "codec_sv2 2.0.0", "const_sv2", "futures", "tokio", @@ -733,6 +1032,22 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_codec_sv2" +version = "1.1.2" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" + [[package]] name = "derive_codec_sv2" version = "2.0.0" @@ -760,6 +1075,27 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.59.0", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -771,26 +1107,36 @@ dependencies = [ "syn", ] +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + [[package]] name = "dmnd-client" -version = "0.2.9" +version = "0.3.1" dependencies = [ "async-recursion", "axum", - "binary_sv2", + "binary_sv2 2.0.0", "bitcoin", "clap", - "codec_sv2", + "codec_sv2 2.0.0", "dashmap", "demand-share-accounting-ext", "demand-sv2-connection", - "framing_sv2", + "framing_sv2 4.0.0", "futures", + "integration_tests_sv2", "jemallocator", "key-utils", "lazy_static", "nohash-hasher", - "noise_sv2", + "noise_sv2 1.2.1", "pid", "primitive-types", "rand 0.8.5", @@ -800,7 +1146,8 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "sv1_api", + "stratum-apps", + "sv1_api 1.0.1", "sysinfo", "tokio", "tokio-util", @@ -841,6 +1188,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encode_unicode" version = "1.0.0" @@ -872,6 +1225,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "extensions_sv2" +version = "0.1.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -913,6 +1280,16 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "miniz_oxide", + "zlib-rs", +] + [[package]] name = "fnv" version = "1.0.7" @@ -954,11 +1331,21 @@ name = "framing_sv2" version = "4.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", - "buffer_sv2", + "binary_sv2 2.0.0", + "buffer_sv2 2.0.0", "const_sv2", ] +[[package]] +name = "framing_sv2" +version = "6.0.1" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "buffer_sv2 3.0.1", + "noise_sv2 1.4.2", +] + [[package]] name = "funty" version = "2.0.0" @@ -1132,11 +1519,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "handlers_sv2" +version = "0.3.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "common_messages_sv2 7.0.0", + "extensions_sv2", + "framing_sv2 6.0.1", + "job_declaration_sv2 7.0.0", + "mining_sv2 9.0.0", + "parsers_sv2", + "template_distribution_sv2 5.0.0", + "trait-variant", +] + [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashbrown" @@ -1153,6 +1560,15 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "heck" version = "0.5.0" @@ -1189,12 +1605,33 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "hex-conservative" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366fa3443ac84474447710ec17bb00b05dfbd096137817981e86f992f21a2793" + [[package]] name = "hex_lit" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" +[[package]] +name = "hotpath" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d9982fcb4356a5260502f0e646411ec1feb2962cc98c230777104a8d1c5ed3" +dependencies = [ + "hotpath-macros", +] + +[[package]] +name = "hotpath-macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4398eddb78466298f1ddcc739abbbd8a942e541d1972c7590bd83de364e626e0" + [[package]] name = "http" version = "1.4.0" @@ -1272,12 +1709,12 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls", + "rustls 0.23.37", "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 1.0.6", ] [[package]] @@ -1302,7 +1739,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -1483,6 +1920,31 @@ dependencies = [ "generic-array", ] +[[package]] +name = "integration_tests_sv2" +version = "0.1.1" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "clap", + "corepc-node", + "hex", + "jd_client_sv2", + "minreq", + "num-format", + "once_cell", + "pool_sv2", + "primitive-types", + "rand 0.8.5", + "sha2 0.10.9", + "stratum-apps", + "tokio", + "tokio-util", + "tracing", + "tracing-subscriber", + "translator_sv2", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -1511,6 +1973,39 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +[[package]] +name = "jd_client_sv2" +version = "0.1.4" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "bitcoin_core_sv2", + "clap", + "config", + "hex", + "hotpath", + "serde", + "stratum-apps", + "tokio", + "tracing", +] + +[[package]] +name = "jd_server_sv2" +version = "0.1.2" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "async-trait", + "bitcoin_core_sv2", + "dashmap", + "hotpath", + "serde", + "stratum-apps", + "tokio", + "tracing", +] + [[package]] name = "jemalloc-sys" version = "0.5.4+5.3.0-patched" @@ -1536,10 +2031,18 @@ name = "job_declaration_sv2" version = "3.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", + "binary_sv2 2.0.0", "const_sv2", ] +[[package]] +name = "job_declaration_sv2" +version = "7.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", +] + [[package]] name = "js-sys" version = "0.3.91" @@ -1550,6 +2053,29 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "jsonrpc" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" +dependencies = [ + "base64 0.13.1", + "minreq", + "serde", + "serde_json", +] + [[package]] name = "key-utils" version = "1.2.0" @@ -1653,16 +2179,74 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "mining_sv2" version = "3.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", + "binary_sv2 2.0.0", "const_sv2", "hex", ] +[[package]] +name = "mining_sv2" +version = "9.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", +] + +[[package]] +name = "miniscript" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "867b1f11e0545ad5ebbddd8a9f18756d9657a6758bf10d96cf15ddd0b726b650" +dependencies = [ + "bech32", + "bitcoin", + "hex-conservative 1.0.1", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "minreq" +version = "2.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" +dependencies = [ + "rustls 0.21.12", + "rustls-webpki 0.101.7", + "serde", + "serde_json", + "webpki-roots 0.25.4", +] + [[package]] name = "mio" version = "1.1.1" @@ -1710,6 +2294,27 @@ dependencies = [ "secp256k1 0.28.2", ] +[[package]] +name = "noise_sv2" +version = "1.4.2" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "aes-gcm", + "chacha20poly1305", + "rand 0.8.5", + "secp256k1 0.28.2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "ntapi" version = "0.4.3" @@ -1734,6 +2339,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec", + "itoa", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1811,6 +2426,22 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + [[package]] name = "parity-scale-codec" version = "3.7.5" @@ -1862,12 +2493,75 @@ dependencies = [ "windows-link", ] +[[package]] +name = "parsers_sv2" +version = "0.3.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "common_messages_sv2 7.0.0", + "extensions_sv2", + "framing_sv2 6.0.1", + "job_declaration_sv2 7.0.0", + "mining_sv2 9.0.0", + "template_distribution_sv2 5.0.0", +] + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + [[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2 0.10.9", +] + [[package]] name = "pid" version = "4.0.0" @@ -1934,6 +2628,24 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "pool_sv2" +version = "0.2.2" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "bitcoin_core_sv2", + "clap", + "config", + "hex", + "hotpath", + "jd_server_sv2", + "serde", + "stratum-apps", + "tokio", + "tracing", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -2003,6 +2715,27 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prometheus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror 1.0.69", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + [[package]] name = "quick-xml" version = "0.37.5" @@ -2024,9 +2757,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.23.37", "socket2", - "thiserror", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -2044,10 +2777,10 @@ dependencies = [ "rand 0.9.2", "ring", "rustc-hash", - "rustls", + "rustls 0.23.37", "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -2186,9 +2919,20 @@ dependencies = [ name = "redox_syscall" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "bitflags", + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", ] [[package]] @@ -2226,7 +2970,7 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "encoding_rs", "futures-channel", @@ -2247,7 +2991,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls", + "rustls 0.23.37", "rustls-pki-types", "serde", "serde_json", @@ -2263,7 +3007,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 1.0.6", ] [[package]] @@ -2285,22 +3029,78 @@ name = "roles_logic_sv2" version = "3.2.1" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", + "binary_sv2 2.0.0", "chacha20poly1305", - "common_messages_sv2", + "common_messages_sv2 4.0.0", "const_sv2", - "framing_sv2", + "framing_sv2 4.0.0", "hex-conservative 0.3.2", - "job_declaration_sv2", - "mining_sv2", + "job_declaration_sv2 3.0.0", + "mining_sv2 3.0.0", "nohash-hasher", "primitive-types", "siphasher", "stratum-common", - "template_distribution_sv2", + "template_distribution_sv2 3.0.0", "tracing", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.7", + "bitflags", + "serde", + "serde_derive", +] + +[[package]] +name = "rust-embed" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +dependencies = [ + "sha2 0.10.9", + "walkdir", +] + +[[package]] +name = "rust-ini" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + [[package]] name = "rustc-hash" version = "2.1.1" @@ -2335,6 +3135,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.23.37" @@ -2344,7 +3156,7 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.9", "subtle", "zeroize", ] @@ -2359,6 +3171,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.9" @@ -2382,6 +3204,15 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.29" @@ -2397,6 +3228,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "secp256k1" version = "0.28.2" @@ -2596,6 +3437,16 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.10.7", + "sha2-asm", +] + +[[package]] +name = "sha2-asm" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b845214d6175804686b2bd482bcffe96651bb2d1200742b712003504a2dac1ab" +dependencies = [ + "cc", ] [[package]] @@ -2607,6 +3458,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shellexpand" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8" +dependencies = [ + "dirs", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2633,6 +3493,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + [[package]] name = "siphasher" version = "1.0.2" @@ -2683,6 +3549,34 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stratum-apps" +version = "0.3.1" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "axum", + "bs58", + "config", + "dirs", + "futures", + "miniscript", + "prometheus", + "rand 0.8.5", + "rustversion", + "secp256k1 0.28.2", + "serde", + "serde_json", + "shellexpand", + "stratum-core", + "tokio", + "tokio-util", + "tracing", + "tracing-subscriber", + "utoipa", + "utoipa-swagger-ui", +] + [[package]] name = "stratum-common" version = "1.0.0" @@ -2692,6 +3586,42 @@ dependencies = [ "secp256k1 0.28.2", ] +[[package]] +name = "stratum-core" +version = "0.3.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "bitcoin", + "buffer_sv2 3.0.1", + "channels_sv2", + "codec_sv2 5.0.0", + "common_messages_sv2 7.0.0", + "extensions_sv2", + "framing_sv2 6.0.1", + "handlers_sv2", + "job_declaration_sv2 7.0.0", + "mining_sv2 9.0.0", + "noise_sv2 1.4.2", + "parsers_sv2", + "stratum_translation", + "sv1_api 4.0.0", + "template_distribution_sv2 5.0.0", +] + +[[package]] +name = "stratum_translation" +version = "0.2.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "bitcoin", + "channels_sv2", + "mining_sv2 9.0.0", + "sv1_api 4.0.0", + "tracing", +] + [[package]] name = "strsim" version = "0.11.1" @@ -2709,7 +3639,7 @@ name = "sv1_api" version = "1.0.1" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", + "binary_sv2 2.0.0", "bitcoin_hashes 0.3.2", "byteorder", "hex", @@ -2718,6 +3648,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "sv1_api" +version = "4.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", + "bitcoin_hashes 0.3.2", + "byteorder", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "syn" version = "2.0.117" @@ -2819,17 +3762,45 @@ name = "template_distribution_sv2" version = "3.0.0" source = "git+https://github.com/demand-open-source/stratum#48e510af59231a1885f454e7b5a43e89736abcb0" dependencies = [ - "binary_sv2", + "binary_sv2 2.0.0", "const_sv2", ] +[[package]] +name = "template_distribution_sv2" +version = "5.0.0" +source = "git+https://github.com/stratum-mining/stratum?branch=main#2bd3073c7241a6a4355de30a120bea1b2bc69fa3" +dependencies = [ + "binary_sv2 5.0.1", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2883,6 +3854,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinystr" version = "0.8.2" @@ -2953,7 +3933,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls", + "rustls 0.23.37", "tokio", ] @@ -2965,6 +3945,7 @@ checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -3106,7 +4087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 2.0.18", "time", "tracing-subscriber", ] @@ -3161,6 +4142,36 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "translator_sv2" +version = "0.2.3" +source = "git+https://github.com/stratum-mining/sv2-apps.git?branch=main#319b66ca3ebfc3ab3e14a873390ad6862225ccb0" +dependencies = [ + "async-channel", + "clap", + "config", + "dashmap", + "hex", + "hotpath", + "serde", + "serde_json", + "stratum-apps", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -3173,6 +4184,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "uint" version = "0.10.0" @@ -3185,12 +4202,24 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-segmentation" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + [[package]] name = "unicode-width" version = "0.2.2" @@ -3249,6 +4278,48 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "utoipa" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" +dependencies = [ + "indexmap", + "serde", + "serde_json", + "utoipa-gen", +] + +[[package]] +name = "utoipa-gen" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "utoipa-swagger-ui" +version = "9.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55" +dependencies = [ + "axum", + "base64 0.22.1", + "mime_guess", + "regex", + "rust-embed", + "serde", + "serde_json", + "url", + "utoipa", + "zip", +] + [[package]] name = "valuable" version = "0.1.1" @@ -3267,6 +4338,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -3413,6 +4494,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" version = "1.0.6" @@ -3422,6 +4509,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + [[package]] name = "winapi" version = "0.3.9" @@ -3438,6 +4534,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3828,6 +4933,17 @@ dependencies = [ "rustix", ] +[[package]] +name = "yaml-rust2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + [[package]] name = "yoke" version = "0.8.1" @@ -3931,19 +5047,51 @@ dependencies = [ "syn", ] +[[package]] +name = "zip" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308" +dependencies = [ + "arbitrary", + "crc32fast", + "flate2", + "indexmap", + "memchr", + "zopfli", +] + [[package]] name = "zipsign-api" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dba6063ff82cdbd9a765add16d369abe81e520f836054e997c2db217ceca40c0" dependencies = [ - "base64", + "base64 0.22.1", "ed25519-dalek", - "thiserror", + "thiserror 2.0.18", ] +[[package]] +name = "zlib-rs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" + [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] diff --git a/src/config.rs b/src/config.rs index 45e337a3..28ebaa3b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -134,6 +134,7 @@ impl Configuration { #[allow(clippy::too_many_arguments)] pub fn new( token: Option, + max_token_changes_per_connection: u32, tp_address: Option, interval: u64, delay: u64, @@ -154,6 +155,7 @@ impl Configuration { ) -> Self { Configuration { token, + max_token_changes_per_connection, tp_address, interval, delay, @@ -184,6 +186,7 @@ impl Configuration { fn default_for_tests() -> Self { Self::new( Some("test_token".to_string()), + 0, None, 120_000, 0, @@ -223,7 +226,7 @@ impl Configuration { } pub fn max_token_changes_per_connection() -> u32 { - CONFIG.max_token_changes_per_connection + Self::cfg().max_token_changes_per_connection } pub fn tp_address() -> Option { diff --git a/src/translator/downstream/downstream.rs b/src/translator/downstream/downstream.rs index 1a49ad3c..0e9d603f 100644 --- a/src/translator/downstream/downstream.rs +++ b/src/translator/downstream/downstream.rs @@ -1166,9 +1166,7 @@ mod tests { build_test_downstream("token-a", 1); let first = downstream - .safe_lock(|d| { - d.handle_authorize_token("token-a") - }) + .safe_lock(|d| d.handle_authorize_token("token-a")) .unwrap(); let second = downstream .safe_lock(|d| { diff --git a/tests/library_init.rs b/tests/library_init.rs index 046cea3b..1a4992ff 100644 --- a/tests/library_init.rs +++ b/tests/library_init.rs @@ -105,6 +105,7 @@ async fn library_init_sv2_setup_connection() { let config = dmnd_client::Configuration::new( Some("test_token".to_string()), + 0, Some(tp_sniffer_addr.to_string()), 120_000, 0,