diff --git a/bitcoin-core-sv2/Cargo.toml b/bitcoin-core-sv2/Cargo.toml index 9228a9272..827d7e830 100644 --- a/bitcoin-core-sv2/Cargo.toml +++ b/bitcoin-core-sv2/Cargo.toml @@ -26,4 +26,5 @@ bitcoin_capnp_types_v31 = { package = "bitcoin-capnp-types", version = "0.2.1" } # fetching from github enables synchronizing development workflows across sv2-apps and stratum repos # it MUST be changed before bitcoin-core-sv2 is published to crates.io # with the proper version of stratum-core being fetched from crates.io as well -stratum-core = { git = "https://github.com/stratum-mining/stratum", branch = "main" } +stratum-core = { git = "https://github.com/Shourya742/stratum", branch = "2026-07-13-split-inner" } + diff --git a/bitcoin-core-sv2/examples/tdp_logger.rs b/bitcoin-core-sv2/examples/tdp_logger.rs index 453559407..ebdc1a650 100644 --- a/bitcoin-core-sv2/examples/tdp_logger.rs +++ b/bitcoin-core-sv2/examples/tdp_logger.rs @@ -25,8 +25,8 @@ use std::path::Path; use async_channel::unbounded; use stratum_core::{ - parsers_sv2::TemplateDistribution, - template_distribution_sv2::{CoinbaseOutputConstraints, RequestTransactionData}, + parsers_sv2::TemplateDistributionOwned, + template_distribution_sv2::{CoinbaseOutputConstraintsOwned, RequestTransactionDataOwned}, }; use tokio_util::sync::CancellationToken; use tracing::{error, info}; @@ -137,9 +137,9 @@ async fn main() { info!("Message received: {}", template_distribution_message); // send a RequestTransactionData every time a NewTemplate message is received - if let TemplateDistribution::NewTemplate(new_template) = template_distribution_message { + if let TemplateDistributionOwned::NewTemplate(new_template) = template_distribution_message { let template_id = new_template.template_id; - let request_transaction_data = TemplateDistribution::RequestTransactionData(RequestTransactionData { + let request_transaction_data = TemplateDistributionOwned::RequestTransactionData(RequestTransactionDataOwned { template_id, }); @@ -162,7 +162,7 @@ async fn main() { // `BitcoinCoreSv2TDP` will not start distributing new templates until it receives the first // `CoinbaseOutputConstraints` message. let new_coinbase_output_constraints = - TemplateDistribution::CoinbaseOutputConstraints(CoinbaseOutputConstraints { + TemplateDistributionOwned::CoinbaseOutputConstraints(CoinbaseOutputConstraintsOwned { coinbase_output_max_additional_size: 2, coinbase_output_max_additional_sigops: 2, }); diff --git a/bitcoin-core-sv2/src/runtime_api/job_declaration_protocol/io.rs b/bitcoin-core-sv2/src/runtime_api/job_declaration_protocol/io.rs index d9788d0dd..f77c31791 100644 --- a/bitcoin-core-sv2/src/runtime_api/job_declaration_protocol/io.rs +++ b/bitcoin-core-sv2/src/runtime_api/job_declaration_protocol/io.rs @@ -2,7 +2,7 @@ use stratum_core::{ bitcoin::{BlockHash, CompactTarget, Transaction, Txid, Wtxid, block::Version}, - job_declaration_sv2::PushSolution, + job_declaration_sv2::PushSolutionOwned, }; use tokio::sync::oneshot; @@ -34,9 +34,7 @@ pub enum JdRequest { response_tx: oneshot::Sender, }, /// Submit a mining solution to Bitcoin Core (fire-and-forget). - PushSolution { - push_solution: PushSolution<'static>, - }, + PushSolution { push_solution: PushSolutionOwned }, } /// The result of trying to handle a DeclareMiningJob request. diff --git a/bitcoin-core-sv2/src/runtime_api/template_distribution_protocol/mod.rs b/bitcoin-core-sv2/src/runtime_api/template_distribution_protocol/mod.rs index 82555c6f6..e736b53ee 100644 --- a/bitcoin-core-sv2/src/runtime_api/template_distribution_protocol/mod.rs +++ b/bitcoin-core-sv2/src/runtime_api/template_distribution_protocol/mod.rs @@ -18,7 +18,7 @@ use crate::{ }; use async_channel::{Receiver, Sender}; use std::path::Path; -use stratum_core::parsers_sv2::TemplateDistribution; +use stratum_core::parsers_sv2::TemplateDistributionOwned; pub use tokio_util::sync::CancellationToken; /// Version-agnostic TDP runtime handle. @@ -48,8 +48,8 @@ pub async fn new

( bitcoin_core_unix_socket_path: P, fee_threshold: u64, min_interval: u8, - incoming_messages: Receiver>, - outgoing_messages: Sender>, + incoming_messages: Receiver, + outgoing_messages: Sender, global_cancellation_token: CancellationToken, ) -> Result where diff --git a/bitcoin-core-sv2/src/unix_capnp/v30x/job_declaration_protocol/handlers.rs b/bitcoin-core-sv2/src/unix_capnp/v30x/job_declaration_protocol/handlers.rs index 078730363..2a31e391a 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v30x/job_declaration_protocol/handlers.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v30x/job_declaration_protocol/handlers.rs @@ -16,7 +16,7 @@ use stratum_core::{ }, job_declaration_sv2::{ ERROR_CODE_DECLARE_MINING_JOB_INTERNAL_ERROR, ERROR_CODE_DECLARE_MINING_JOB_INVALID_JOB, - ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, PushSolution, + ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, PushSolutionOwned, }, }; use tokio::sync::oneshot; @@ -314,7 +314,7 @@ impl BitcoinCoreSv2JDP { /// Submits a mining solution to Bitcoin Core. /// /// Not yet implemented — deliberately left as a stub for future work. - pub(crate) async fn handle_push_solution(&self, _push_solution: PushSolution<'_>) { + pub(crate) async fn handle_push_solution(&self, _push_solution: PushSolutionOwned) { // todo } } diff --git a/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/handlers.rs b/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/handlers.rs index 3ef1c9325..7ba5bda4c 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/handlers.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/handlers.rs @@ -4,10 +4,10 @@ use crate::unix_capnp::v30x::template_distribution_protocol::{ BitcoinCoreSv2TDP, error::BitcoinCoreSv2TDPError, }; use stratum_core::{ - parsers_sv2::TemplateDistribution, + parsers_sv2::TemplateDistributionOwned, template_distribution_sv2::{ - CoinbaseOutputConstraints, RequestTransactionData, RequestTransactionDataError, - SubmitSolution, + CoinbaseOutputConstraintsOwned, RequestTransactionDataErrorOwned, + RequestTransactionDataOwned, SubmitSolutionOwned, }, }; use tokio_util::sync::CancellationToken; @@ -16,7 +16,7 @@ use tracing::{debug, error}; impl BitcoinCoreSv2TDP { pub(crate) async fn handle_coinbase_output_constraints( &mut self, - coinbase_output_constraints: CoinbaseOutputConstraints, + coinbase_output_constraints: CoinbaseOutputConstraintsOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!("handle_coinbase_output_constraints() called"); @@ -63,7 +63,7 @@ impl BitcoinCoreSv2TDP { pub(crate) async fn handle_request_transaction_data( &self, - request_transaction_data: RequestTransactionData, + request_transaction_data: RequestTransactionDataOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!( "handle_request_transaction_data() called for template_id: {}", @@ -82,7 +82,7 @@ impl BitcoinCoreSv2TDP { "Template {} is stale, sending error response", request_transaction_data.template_id ); - let request_transaction_data_error = RequestTransactionDataError { + let request_transaction_data_error = RequestTransactionDataErrorOwned { template_id: request_transaction_data.template_id, error_code: "stale-template-id" .to_string() @@ -92,7 +92,7 @@ impl BitcoinCoreSv2TDP { if let Err(e) = self .outgoing_messages - .send(TemplateDistribution::RequestTransactionDataError( + .send(TemplateDistributionOwned::RequestTransactionDataError( request_transaction_data_error.clone(), )) .await @@ -139,7 +139,7 @@ impl BitcoinCoreSv2TDP { return Err(BitcoinCoreSv2TDPError::FailedToFetchTemplateTxData); } }; - TemplateDistribution::RequestTransactionDataSuccess( + TemplateDistributionOwned::RequestTransactionDataSuccess( request_transaction_data_success, ) } @@ -148,13 +148,15 @@ impl BitcoinCoreSv2TDP { "Template {} not found, sending error response", request_transaction_data.template_id ); - TemplateDistribution::RequestTransactionDataError(RequestTransactionDataError { - template_id: request_transaction_data.template_id, - error_code: "template-id-not-found" - .to_string() - .try_into() - .expect("error code must be valid string"), - }) + TemplateDistributionOwned::RequestTransactionDataError( + RequestTransactionDataErrorOwned { + template_id: request_transaction_data.template_id, + error_code: "template-id-not-found" + .to_string() + .try_into() + .expect("error code must be valid string"), + }, + ) } } }; @@ -169,7 +171,7 @@ impl BitcoinCoreSv2TDP { pub(crate) async fn handle_submit_solution( &self, - submit_solution: SubmitSolution<'static>, + submit_solution: SubmitSolutionOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!( "handle_submit_solution() called for template_id: {}", diff --git a/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/mod.rs b/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/mod.rs index a76f2c1c8..881810720 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/mod.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/mod.rs @@ -28,10 +28,10 @@ use std::{ time::Instant, }; use stratum_core::{ - binary_sv2::U256, + binary_sv2::U256Owned, bitcoin::{Transaction, block::Header, consensus::deserialize}, - parsers_sv2::TemplateDistribution, - template_distribution_sv2::CoinbaseOutputConstraints, + parsers_sv2::TemplateDistributionOwned, + template_distribution_sv2::CoinbaseOutputConstraintsOwned, }; use std::sync::RwLock; @@ -91,12 +91,12 @@ pub struct BitcoinCoreSv2TDP { mining_ipc_client: MiningIpcClient, monitor_ipc_templates_handle: Rc>>>, current_template_ipc_client: Rc>>, - current_prev_hash: Rc>>>, + current_prev_hash: Rc>>, template_data: Rc>>, stale_template_ids: Rc>>, template_id_factory: Rc, - incoming_messages: Receiver>, - outgoing_messages: Sender>, + incoming_messages: Receiver, + outgoing_messages: Sender, global_cancellation_token: CancellationToken, template_ipc_client_cancellation_token: CancellationToken, last_sent_template_instant: Option, @@ -110,8 +110,8 @@ impl BitcoinCoreSv2TDP { bitcoin_core_unix_socket_path: P, fee_threshold: u64, min_interval: u8, - incoming_messages: Receiver>, - outgoing_messages: Sender>, + incoming_messages: Receiver, + outgoing_messages: Sender, global_cancellation_token: CancellationToken, ) -> Result where @@ -217,7 +217,7 @@ impl BitcoinCoreSv2TDP { Ok(message) = self.incoming_messages.recv() => { debug!("run() received message during initial loop: {:?}", message); match message { - TemplateDistribution::CoinbaseOutputConstraints(coinbase_output_constraints) => { + TemplateDistributionOwned::CoinbaseOutputConstraints(coinbase_output_constraints) => { info!("Received: {:?}", coinbase_output_constraints); debug!("First CoinbaseOutputConstraints received - max_additional_size: {}, max_additional_sigops: {}", coinbase_output_constraints.coinbase_output_max_additional_size, @@ -466,7 +466,7 @@ impl BitcoinCoreSv2TDP { template_data.get_template_id() ); self.outgoing_messages - .send(TemplateDistribution::NewTemplate(new_template)) + .send(TemplateDistributionOwned::NewTemplate(new_template)) .await .map_err(|e| { error!("Failed to send NewTemplate message: {:?}", e); @@ -480,7 +480,7 @@ impl BitcoinCoreSv2TDP { template_data.get_prev_hash() ); self.outgoing_messages - .send(TemplateDistribution::SetNewPrevHash(set_new_prev_hash)) + .send(TemplateDistributionOwned::SetNewPrevHash(set_new_prev_hash)) .await .map_err(|e| { error!("Failed to send SetNewPrevHash message: {:?}", e); @@ -511,7 +511,7 @@ impl BitcoinCoreSv2TDP { /// - stores the client as `current_template_ipc_client` async fn bootstrap_template_ipc_client_from_coinbase_output_constraints( &mut self, - coinbase_output_constraints: CoinbaseOutputConstraints, + coinbase_output_constraints: CoinbaseOutputConstraintsOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!( "bootstrap_template_ipc_client_from_coinbase_output_constraints() called - max_size: {}, max_sigops: {}", diff --git a/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/template_data.rs b/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/template_data.rs index 2d46c0dd7..921841bea 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/template_data.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v30x/template_distribution_protocol/template_data.rs @@ -18,9 +18,10 @@ use stratum_core::bitcoin::{ }; use stratum_core::{ - binary_sv2::{B016M, B064K, B0255, Seq064K, Seq0255, U256}, + binary_sv2::{B016MOwned, B064KOwned, B0255Owned, Seq064KOwned, Seq0255Owned, U256Owned}, template_distribution_sv2::{ - NewTemplate, RequestTransactionDataSuccess, SetNewPrevHash, SubmitSolution, + NewTemplateOwned, RequestTransactionDataSuccessOwned, SetNewPrevHashOwned, + SubmitSolutionOwned, }, }; use tracing::{debug, error, info}; @@ -77,8 +78,8 @@ impl TemplateData { pub fn get_new_template_message( &self, future_template: bool, - ) -> Result, TemplateDataError> { - let new_template = NewTemplate { + ) -> Result { + let new_template = NewTemplateOwned { template_id: self.template_id, future_template, version: self.get_version()?, @@ -91,37 +92,36 @@ impl TemplateData { coinbase_tx_locktime: self.get_coinbase_tx_lock_time(), merkle_path: self.get_merkle_path()?, }; - Ok(new_template.into_static()) + Ok(new_template) } // please note that `SetNewPrevHash.target` is consensus and not weak-block // so it's essentially redundant with `SetNewPrevHash.n_bits` - pub fn get_set_new_prev_hash_message(&self) -> SetNewPrevHash<'static> { - let set_new_prev_hash = SetNewPrevHash { + pub fn get_set_new_prev_hash_message(&self) -> SetNewPrevHashOwned { + SetNewPrevHashOwned { template_id: self.template_id, prev_hash: self.get_prev_hash(), header_timestamp: self.get_ntime(), n_bits: self.get_nbits(), target: self.get_target(), - }; - set_new_prev_hash.into_static() + } } pub async fn get_request_transaction_data_success_message( &self, thread_map: ThreadMapIpcClient, - ) -> Result, TemplateDataError> { - let request_transaction_data_success = RequestTransactionDataSuccess { + ) -> Result { + let request_transaction_data_success = RequestTransactionDataSuccessOwned { template_id: self.template_id, transaction_list: self.get_tx_data(thread_map).await?, excess_data: vec![] .try_into() .expect("empty vec should always be valid for B064K"), }; - Ok(request_transaction_data_success.into_static()) + Ok(request_transaction_data_success) } - pub fn get_prev_hash(&self) -> U256<'static> { + pub fn get_prev_hash(&self) -> U256Owned { self.header.prev_blockhash.to_byte_array().into() } @@ -239,7 +239,7 @@ impl TemplateData { pub async fn submit_solution( &self, - submit_solution: SubmitSolution<'static>, + submit_solution: SubmitSolutionOwned, thread_ipc_client: ThreadIpcClient, thread_map: ThreadMapIpcClient, path_dir: &Path, @@ -291,10 +291,10 @@ impl TemplateData { self.header.bits.to_consensus() } - fn get_target(&self) -> U256<'_> { + fn get_target(&self) -> U256Owned { let target = Target::from(self.header.bits); let target_bytes: [u8; 32] = target.to_le_bytes(); - U256::from(target_bytes) + U256Owned::from(target_bytes) } fn get_ntime(&self) -> u32 { @@ -317,8 +317,8 @@ impl TemplateData { .map_err(|_| TemplateDataError::InvalidCoinbaseTxVersion) } - fn get_coinbase_script_sig(&self) -> Result, TemplateDataError> { - let coinbase_script_sig: B0255 = self.coinbase_tx.input[0] + fn get_coinbase_script_sig(&self) -> Result { + let coinbase_script_sig: B0255Owned = self.coinbase_tx.input[0] .script_sig .to_bytes() .try_into() @@ -339,13 +339,13 @@ impl TemplateData { .collect() } - fn get_serialized_empty_coinbase_outputs(&self) -> Result, TemplateDataError> { + fn get_serialized_empty_coinbase_outputs(&self) -> Result { let empty_coinbase_outputs = self.get_empty_coinbase_outputs(); let mut serialized_empty_coinbase_outputs = Vec::new(); for output in empty_coinbase_outputs { serialized_empty_coinbase_outputs.extend_from_slice(&serialize(&output)); } - let serialized_empty_coinbase_outputs: B064K = serialized_empty_coinbase_outputs + let serialized_empty_coinbase_outputs: B064KOwned = serialized_empty_coinbase_outputs .try_into() .map_err(|_| TemplateDataError::FailedToSerializeEmptyCoinbaseOutputs)?; Ok(serialized_empty_coinbase_outputs) @@ -369,7 +369,7 @@ impl TemplateData { async fn get_tx_data( &self, thread_map: ThreadMapIpcClient, - ) -> Result>, TemplateDataError> { + ) -> Result, TemplateDataError> { debug!("Creating a dedicated thread IPC client for get_tx_data"); let thread_ipc_client_request = thread_map.make_thread_request(); let thread_ipc_client_response = thread_ipc_client_request.send().promise.await?; @@ -395,7 +395,7 @@ impl TemplateData { block.header.prev_blockhash ); - let tx_data: Vec> = block + let tx_data: Vec = block .txdata .iter() .skip(1) // skip coinbase tx @@ -405,21 +405,22 @@ impl TemplateData { .expect("tx data should always be valid for B016M") }) .collect(); - Ok(Seq064K::new(tx_data).expect("tx data should always be valid for Seq064K")) + Ok(Seq064KOwned::new(tx_data).expect("tx data should always be valid for Seq064K")) } - fn get_merkle_path(&self) -> Result>, TemplateDataError> { + fn get_merkle_path(&self) -> Result, TemplateDataError> { // Convert each Vec in the merkle path to U256 - let merkle_path_u256: Vec> = self + let merkle_path_u256: Vec = self .merkle_path .iter() .map(|hash_bytes| { // Convert Vec to U256 - U256::try_from(hash_bytes.clone()) + U256Owned::try_from(hash_bytes.clone()) .map_err(|_| TemplateDataError::FailedToConvertMerklePathHashToU256) }) .collect::, _>>()?; - Seq0255::new(merkle_path_u256).map_err(|_| TemplateDataError::FailedToCreateMerklePathSeq) + Seq0255Owned::new(merkle_path_u256) + .map_err(|_| TemplateDataError::FailedToCreateMerklePathSeq) } } diff --git a/bitcoin-core-sv2/src/unix_capnp/v31x/job_declaration_protocol/handlers.rs b/bitcoin-core-sv2/src/unix_capnp/v31x/job_declaration_protocol/handlers.rs index b6f3d7b9c..9196fd958 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v31x/job_declaration_protocol/handlers.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v31x/job_declaration_protocol/handlers.rs @@ -16,7 +16,7 @@ use stratum_core::{ }, job_declaration_sv2::{ ERROR_CODE_DECLARE_MINING_JOB_INTERNAL_ERROR, ERROR_CODE_DECLARE_MINING_JOB_INVALID_JOB, - ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, PushSolution, + ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, PushSolutionOwned, }, }; use tokio::sync::oneshot; @@ -329,7 +329,7 @@ impl BitcoinCoreSv2JDP { /// Submits a mining solution to Bitcoin Core. /// /// Not yet implemented — deliberately left as a stub for future work. - pub(crate) async fn handle_push_solution(&self, _push_solution: PushSolution<'_>) { + pub(crate) async fn handle_push_solution(&self, _push_solution: PushSolutionOwned) { // todo } } diff --git a/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/handlers.rs b/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/handlers.rs index ab08dfd86..a115aefe4 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/handlers.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/handlers.rs @@ -4,11 +4,11 @@ use crate::unix_capnp::v31x::template_distribution_protocol::{ BitcoinCoreSv2TDP, error::BitcoinCoreSv2TDPError, }; use stratum_core::{ - parsers_sv2::TemplateDistribution, + parsers_sv2::TemplateDistributionOwned, template_distribution_sv2::{ - CoinbaseOutputConstraints, ERROR_CODE_REQUEST_TRANSACTION_DATA_STALE_TEMPLATE_ID, - ERROR_CODE_REQUEST_TRANSACTION_DATA_TEMPLATE_ID_NOT_FOUND, RequestTransactionData, - RequestTransactionDataError, SubmitSolution, + CoinbaseOutputConstraintsOwned, ERROR_CODE_REQUEST_TRANSACTION_DATA_STALE_TEMPLATE_ID, + ERROR_CODE_REQUEST_TRANSACTION_DATA_TEMPLATE_ID_NOT_FOUND, + RequestTransactionDataErrorOwned, RequestTransactionDataOwned, SubmitSolutionOwned, }, }; use tokio_util::sync::CancellationToken; @@ -17,7 +17,7 @@ use tracing::{debug, error}; impl BitcoinCoreSv2TDP { pub(crate) async fn handle_coinbase_output_constraints( &mut self, - coinbase_output_constraints: CoinbaseOutputConstraints, + coinbase_output_constraints: CoinbaseOutputConstraintsOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!("handle_coinbase_output_constraints() called"); @@ -64,7 +64,7 @@ impl BitcoinCoreSv2TDP { pub(crate) async fn handle_request_transaction_data( &self, - request_transaction_data: RequestTransactionData, + request_transaction_data: RequestTransactionDataOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!( "handle_request_transaction_data() called for template_id: {}", @@ -83,7 +83,7 @@ impl BitcoinCoreSv2TDP { "Template {} is stale, sending error response", request_transaction_data.template_id ); - let request_transaction_data_error = RequestTransactionDataError { + let request_transaction_data_error = RequestTransactionDataErrorOwned { template_id: request_transaction_data.template_id, error_code: ERROR_CODE_REQUEST_TRANSACTION_DATA_STALE_TEMPLATE_ID .to_string() @@ -93,7 +93,7 @@ impl BitcoinCoreSv2TDP { if let Err(e) = self .outgoing_messages - .send(TemplateDistribution::RequestTransactionDataError( + .send(TemplateDistributionOwned::RequestTransactionDataError( request_transaction_data_error.clone(), )) .await @@ -140,7 +140,7 @@ impl BitcoinCoreSv2TDP { return Err(BitcoinCoreSv2TDPError::FailedToFetchTemplateTxData); } }; - TemplateDistribution::RequestTransactionDataSuccess( + TemplateDistributionOwned::RequestTransactionDataSuccess( request_transaction_data_success, ) } @@ -149,13 +149,15 @@ impl BitcoinCoreSv2TDP { "Template {} not found, sending error response", request_transaction_data.template_id ); - TemplateDistribution::RequestTransactionDataError(RequestTransactionDataError { - template_id: request_transaction_data.template_id, - error_code: ERROR_CODE_REQUEST_TRANSACTION_DATA_TEMPLATE_ID_NOT_FOUND - .to_string() - .try_into() - .expect("error code must be valid string"), - }) + TemplateDistributionOwned::RequestTransactionDataError( + RequestTransactionDataErrorOwned { + template_id: request_transaction_data.template_id, + error_code: ERROR_CODE_REQUEST_TRANSACTION_DATA_TEMPLATE_ID_NOT_FOUND + .to_string() + .try_into() + .expect("error code must be valid string"), + }, + ) } } }; @@ -170,7 +172,7 @@ impl BitcoinCoreSv2TDP { pub(crate) async fn handle_submit_solution( &self, - submit_solution: SubmitSolution<'static>, + submit_solution: SubmitSolutionOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!( "handle_submit_solution() called for template_id: {}", diff --git a/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/mod.rs b/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/mod.rs index 58dc43062..40403f829 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/mod.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/mod.rs @@ -29,7 +29,7 @@ use std::{ time::Instant, }; use stratum_core::{ - binary_sv2::U256, + binary_sv2::U256Owned, bitcoin::{ OutPoint, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Witness, absolute::LockTime, @@ -37,8 +37,8 @@ use stratum_core::{ consensus::{Decodable, deserialize}, transaction::Version as TransactionVersion, }, - parsers_sv2::TemplateDistribution, - template_distribution_sv2::CoinbaseOutputConstraints, + parsers_sv2::TemplateDistributionOwned, + template_distribution_sv2::CoinbaseOutputConstraintsOwned, }; use std::sync::RwLock; @@ -98,12 +98,12 @@ pub struct BitcoinCoreSv2TDP { mining_ipc_client: MiningIpcClient, monitor_ipc_templates_handle: Rc>>>, current_template_ipc_client: Rc>>, - current_prev_hash: Rc>>>, + current_prev_hash: Rc>>, template_data: Rc>>, stale_template_ids: Rc>>, template_id_factory: Rc, - incoming_messages: Receiver>, - outgoing_messages: Sender>, + incoming_messages: Receiver, + outgoing_messages: Sender, global_cancellation_token: CancellationToken, template_ipc_client_cancellation_token: CancellationToken, last_sent_template_instant: Option, @@ -117,8 +117,8 @@ impl BitcoinCoreSv2TDP { bitcoin_core_unix_socket_path: P, fee_threshold: u64, min_interval: u8, - incoming_messages: Receiver>, - outgoing_messages: Sender>, + incoming_messages: Receiver, + outgoing_messages: Sender, global_cancellation_token: CancellationToken, ) -> Result where @@ -224,7 +224,7 @@ impl BitcoinCoreSv2TDP { Ok(message) = self.incoming_messages.recv() => { debug!("run() received message during initial loop: {:?}", message); match message { - TemplateDistribution::CoinbaseOutputConstraints(coinbase_output_constraints) => { + TemplateDistributionOwned::CoinbaseOutputConstraints(coinbase_output_constraints) => { info!("Received: {:?}", coinbase_output_constraints); debug!("First CoinbaseOutputConstraints received - max_additional_size: {}, max_additional_sigops: {}", coinbase_output_constraints.coinbase_output_max_additional_size, @@ -473,7 +473,7 @@ impl BitcoinCoreSv2TDP { template_data.get_template_id() ); self.outgoing_messages - .send(TemplateDistribution::NewTemplate(new_template)) + .send(TemplateDistributionOwned::NewTemplate(new_template)) .await .map_err(|e| { error!("Failed to send NewTemplate message: {:?}", e); @@ -487,7 +487,7 @@ impl BitcoinCoreSv2TDP { template_data.get_prev_hash() ); self.outgoing_messages - .send(TemplateDistribution::SetNewPrevHash(set_new_prev_hash)) + .send(TemplateDistributionOwned::SetNewPrevHash(set_new_prev_hash)) .await .map_err(|e| { error!("Failed to send SetNewPrevHash message: {:?}", e); @@ -518,7 +518,7 @@ impl BitcoinCoreSv2TDP { /// - stores the client as `current_template_ipc_client` async fn bootstrap_template_ipc_client_from_coinbase_output_constraints( &mut self, - coinbase_output_constraints: CoinbaseOutputConstraints, + coinbase_output_constraints: CoinbaseOutputConstraintsOwned, ) -> Result<(), BitcoinCoreSv2TDPError> { debug!( "bootstrap_template_ipc_client_from_coinbase_output_constraints() called - max_size: {}, max_sigops: {}", diff --git a/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/template_data.rs b/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/template_data.rs index 87a7bf74b..0314d05ea 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/template_data.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v31x/template_distribution_protocol/template_data.rs @@ -17,9 +17,10 @@ use stratum_core::bitcoin::{ }; use stratum_core::{ - binary_sv2::{B016M, B064K, B0255, Seq064K, Seq0255, U256}, + binary_sv2::{B016MOwned, B064KOwned, B0255Owned, Seq064KOwned, Seq0255Owned, U256Owned}, template_distribution_sv2::{ - NewTemplate, RequestTransactionDataSuccess, SetNewPrevHash, SubmitSolution, + NewTemplateOwned, RequestTransactionDataSuccessOwned, SetNewPrevHashOwned, + SubmitSolutionOwned, }, }; use tracing::{debug, error, info}; @@ -79,8 +80,8 @@ impl TemplateData { pub fn get_new_template_message( &self, future_template: bool, - ) -> Result, TemplateDataError> { - let new_template = NewTemplate { + ) -> Result { + let new_template = NewTemplateOwned { template_id: self.template_id, future_template, version: self.get_version()?, @@ -93,37 +94,36 @@ impl TemplateData { coinbase_tx_locktime: self.get_coinbase_tx_lock_time(), merkle_path: self.get_merkle_path()?, }; - Ok(new_template.into_static()) + Ok(new_template) } // please note that `SetNewPrevHash.target` is consensus and not weak-block // so it's essentially redundant with `SetNewPrevHash.n_bits` - pub fn get_set_new_prev_hash_message(&self) -> SetNewPrevHash<'static> { - let set_new_prev_hash = SetNewPrevHash { + pub fn get_set_new_prev_hash_message(&self) -> SetNewPrevHashOwned { + SetNewPrevHashOwned { template_id: self.template_id, prev_hash: self.get_prev_hash(), header_timestamp: self.get_ntime(), n_bits: self.get_nbits(), target: self.get_target(), - }; - set_new_prev_hash.into_static() + } } pub async fn get_request_transaction_data_success_message( &self, thread_map: ThreadMapIpcClient, - ) -> Result, TemplateDataError> { - let request_transaction_data_success = RequestTransactionDataSuccess { + ) -> Result { + let request_transaction_data_success = RequestTransactionDataSuccessOwned { template_id: self.template_id, transaction_list: self.get_tx_data(thread_map).await?, excess_data: vec![] .try_into() .expect("empty vec should always be valid for B064K"), }; - Ok(request_transaction_data_success.into_static()) + Ok(request_transaction_data_success) } - pub fn get_prev_hash(&self) -> U256<'static> { + pub fn get_prev_hash(&self) -> U256Owned { self.header.prev_blockhash.to_byte_array().into() } @@ -241,7 +241,7 @@ impl TemplateData { pub async fn submit_solution( &self, - submit_solution: SubmitSolution<'static>, + submit_solution: SubmitSolutionOwned, thread_ipc_client: ThreadIpcClient, thread_map: ThreadMapIpcClient, path_dir: &Path, @@ -293,10 +293,10 @@ impl TemplateData { self.header.bits.to_consensus() } - fn get_target(&self) -> U256<'_> { + fn get_target(&self) -> U256Owned { let target = Target::from(self.header.bits); let target_bytes: [u8; 32] = target.to_le_bytes(); - U256::from(target_bytes) + U256Owned::from(target_bytes) } fn get_ntime(&self) -> u32 { @@ -319,8 +319,8 @@ impl TemplateData { .map_err(|_| TemplateDataError::InvalidCoinbaseTxVersion) } - fn get_coinbase_script_sig(&self) -> Result, TemplateDataError> { - let coinbase_script_sig: B0255 = self.coinbase_tx.input[0] + fn get_coinbase_script_sig(&self) -> Result { + let coinbase_script_sig: B0255Owned = self.coinbase_tx.input[0] .script_sig .to_bytes() .try_into() @@ -336,12 +336,12 @@ impl TemplateData { &self.coinbase_tx.output } - fn get_serialized_required_coinbase_outputs(&self) -> Result, TemplateDataError> { + fn get_serialized_required_coinbase_outputs(&self) -> Result { let mut serialized_required_coinbase_outputs = Vec::new(); for output in self.get_required_coinbase_outputs() { serialized_required_coinbase_outputs.extend_from_slice(&serialize(output)); } - let serialized_required_coinbase_outputs: B064K = serialized_required_coinbase_outputs + let serialized_required_coinbase_outputs: B064KOwned = serialized_required_coinbase_outputs .try_into() .map_err(|_| TemplateDataError::FailedToSerializeCoinbaseOutputs)?; Ok(serialized_required_coinbase_outputs) @@ -354,7 +354,7 @@ impl TemplateData { async fn get_tx_data( &self, thread_map: ThreadMapIpcClient, - ) -> Result>, TemplateDataError> { + ) -> Result, TemplateDataError> { debug!("Creating a dedicated thread IPC client for get_tx_data"); let thread_ipc_client_request = thread_map.make_thread_request(); let thread_ipc_client_response = thread_ipc_client_request.send().promise.await?; @@ -380,7 +380,7 @@ impl TemplateData { block.header.prev_blockhash ); - let tx_data: Vec> = block + let tx_data: Vec = block .txdata .iter() .skip(1) // skip coinbase tx @@ -390,21 +390,22 @@ impl TemplateData { .expect("tx data should always be valid for B016M") }) .collect(); - Ok(Seq064K::new(tx_data).expect("tx data should always be valid for Seq064K")) + Ok(Seq064KOwned::new(tx_data).expect("tx data should always be valid for Seq064K")) } - fn get_merkle_path(&self) -> Result>, TemplateDataError> { + fn get_merkle_path(&self) -> Result, TemplateDataError> { // Convert each Vec in the merkle path to U256 - let merkle_path_u256: Vec> = self + let merkle_path_u256: Vec = self .merkle_path .iter() .map(|hash_bytes| { // Convert Vec to U256 - U256::try_from(hash_bytes.clone()) + U256Owned::try_from(hash_bytes.clone()) .map_err(|_| TemplateDataError::FailedToConvertMerklePathHashToU256) }) .collect::, _>>()?; - Seq0255::new(merkle_path_u256).map_err(|_| TemplateDataError::FailedToCreateMerklePathSeq) + Seq0255Owned::new(merkle_path_u256) + .map_err(|_| TemplateDataError::FailedToCreateMerklePathSeq) } } diff --git a/bitcoin-core-sv2/src/unix_capnp/v31x_v30x/template_distribution_protocol/monitors.rs b/bitcoin-core-sv2/src/unix_capnp/v31x_v30x/template_distribution_protocol/monitors.rs index 86f73ac35..2e6e39e1d 100644 --- a/bitcoin-core-sv2/src/unix_capnp/v31x_v30x/template_distribution_protocol/monitors.rs +++ b/bitcoin-core-sv2/src/unix_capnp/v31x_v30x/template_distribution_protocol/monitors.rs @@ -1,7 +1,7 @@ // Shared monitor implementation included by v30.x and v31.x TDP modules. use super::{BitcoinCoreSv2TDP, bitcoin_capnp_types::capnp}; -use stratum_core::parsers_sv2::TemplateDistribution; +use stratum_core::parsers_sv2::TemplateDistributionOwned; use tracing::{debug, error, info, warn}; impl BitcoinCoreSv2TDP { @@ -243,11 +243,11 @@ impl BitcoinCoreSv2TDP { break; } Ok(incoming_message) = self_clone.incoming_messages.recv() => { - info!("Received: {}", incoming_message); + info!("Received: {:?}", incoming_message); debug!("monitor_incoming_messages() processing message"); match incoming_message { - TemplateDistribution::CoinbaseOutputConstraints(coinbase_output_constraints) => { + TemplateDistributionOwned::CoinbaseOutputConstraints(coinbase_output_constraints) => { debug!("Received CoinbaseOutputConstraints - max_additional_size: {}, max_additional_sigops: {}", coinbase_output_constraints.coinbase_output_max_additional_size, coinbase_output_constraints.coinbase_output_max_additional_sigops); @@ -258,7 +258,7 @@ impl BitcoinCoreSv2TDP { break; } } - TemplateDistribution::RequestTransactionData(request_transaction_data) => { + TemplateDistributionOwned::RequestTransactionData(request_transaction_data) => { debug!("Received RequestTransactionData for template_id: {}", request_transaction_data.template_id); if let Err(e) = self_clone.handle_request_transaction_data(request_transaction_data).await { error!("Failed to handle request transaction data: {:?}", e); @@ -267,7 +267,7 @@ impl BitcoinCoreSv2TDP { break; } } - TemplateDistribution::SubmitSolution(submit_solution) => { + TemplateDistributionOwned::SubmitSolution(submit_solution) => { debug!("Received SubmitSolution for template_id: {}", submit_solution.template_id); if let Err(e) = self_clone.handle_submit_solution(submit_solution).await { error!("Failed to handle submit solution: {:?}", e); @@ -275,7 +275,7 @@ impl BitcoinCoreSv2TDP { } } _ => { - error!("Received unexpected message: {}", incoming_message); + error!("Received unexpected message: {:?}", incoming_message); warn!("Ignoring message"); continue; } diff --git a/integration-tests/Cargo.lock b/integration-tests/Cargo.lock index 4c860f33a..09b8542ce 100644 --- a/integration-tests/Cargo.lock +++ b/integration-tests/Cargo.lock @@ -14,7 +14,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arbitrary" @@ -158,9 +158,9 @@ checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "asic-rs" @@ -201,7 +201,7 @@ dependencies = [ "ipnet", "measurements", "pyo3-build-config", - "rand 0.10.1", + "rand 0.10.2", "rlimit", "serde", "serde_json", @@ -910,15 +910,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" dependencies = [ "aws-lc-sys", "zeroize", @@ -926,14 +926,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -990,12 +991,11 @@ dependencies = [ [[package]] name = "base58ck" -version = "0.1.0" +version = "0.1.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +checksum = "365c0acd5b2e8dd0111a46c4faea83fb3cfb6e39a49a7c73a06e090db7b2eff0" dependencies = [ - "bitcoin-internals", - "bitcoin_hashes 0.14.1", + "bitcoin_hashes 0.14.101", ] [[package]] @@ -1024,8 +1024,8 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -1033,17 +1033,16 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.9" +version = "0.32.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf93e61f2dbc3e3c41234ca26a65e2c0b0975c52e0f069ab9893ebbede584d3" +checksum = "bb0ce8bd5baaa0d303a19915a6d93afed161f528654e42da2a7a97d05c59499a" dependencies = [ "base58ck", "base64 0.21.7", "bech32", - "bitcoin-internals", "bitcoin-io", "bitcoin-units", - "bitcoin_hashes 0.14.1", + "bitcoin_hashes 0.14.101", "hex-conservative 0.2.2", "hex_lit", "secp256k1 0.29.1", @@ -1073,27 +1072,38 @@ dependencies = [ ] [[package]] -name = "bitcoin-internals" -version = "0.3.0" +name = "bitcoin-consensus-encoding" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" +checksum = "207311705279250ba465076a1bac4b1ac982855fff73fc5f67e22158ac58cdc9" dependencies = [ + "bitcoin-internals", + "hex-conservative 1.2.0", "serde", ] +[[package]] +name = "bitcoin-internals" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d573f4cf32996a8dce612e4348cece65a241f1882ed594047c9ba348e8869fa5" + [[package]] name = "bitcoin-io" -version = "0.1.4" +version = "0.1.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" +checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78" +dependencies = [ + "bitcoin-consensus-encoding", +] [[package]] name = "bitcoin-units" -version = "0.1.3" +version = "0.1.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346568ebaab2918487cea76dd55dae13c27bb618cdb737c952e69eb2017c4118" +checksum = "9cb95693f371d089a4b5b6fc41c6f3ea6e01ee8c15388335dfac8ea685173b51" dependencies = [ - "bitcoin-internals", + "bitcoin-consensus-encoding", "serde", ] @@ -1122,9 +1132,9 @@ dependencies = [ [[package]] name = "bitcoin_hashes" -version = "0.14.1" +version = "0.14.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" +checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2" dependencies = [ "bitcoin-io", "hex-conservative 0.2.2", @@ -1139,18 +1149,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" dependencies = [ "serde_core", ] [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -1176,6 +1186,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -1210,16 +1229,16 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byte-slice-cast" @@ -1235,15 +1254,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "capnp" -version = "0.25.4" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63da65e5e9ffc3b8f993d4ad222a548152549351a643f6b850a7773cb6ff2809" +checksum = "4777a3bc19b8f8e5fb2d0196c6b5dfcbbcc8b2fe08ae57f873f2f35f15cfc210" dependencies = [ "embedded-io", ] @@ -1287,9 +1306,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.62" +version = "1.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38" dependencies = [ "find-msvc-tools", "jobserver", @@ -1305,9 +1324,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" @@ -1322,9 +1341,9 @@ dependencies = [ [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures 0.3.0", @@ -1346,8 +1365,8 @@ dependencies = [ [[package]] name = "channels_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -1403,16 +1422,16 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", "zeroize", ] [[package]] name = "clap" -version = "4.6.1" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "dd059f9da4f5c36b3787f65d38ccaab1cc315f07b01f89abc8359ee6a8205011" dependencies = [ "clap_builder", "clap_derive", @@ -1420,9 +1439,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" dependencies = [ "anstream", "anstyle", @@ -1459,14 +1478,14 @@ dependencies = [ [[package]] name = "codec_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", "framing_sv2", "noise_sv2", - "rand 0.8.6", + "rand 0.8.7", "tracing", ] @@ -1488,8 +1507,8 @@ dependencies = [ [[package]] name = "common_messages_sv2" -version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "9.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1539,6 +1558,12 @@ dependencies = [ "yaml-rust2", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-random" version = "0.1.18" @@ -1712,9 +1737,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crunchy" @@ -1732,6 +1757,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "csv" version = "1.4.0" @@ -1764,9 +1798,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "6.1.0" +version = "6.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1789,8 +1823,8 @@ dependencies = [ [[package]] name = "derive_codec_sv2" -version = "1.1.3" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "2.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" [[package]] name = "digest" @@ -1808,7 +1842,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "crypto-common", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", ] [[package]] @@ -1820,7 +1865,7 @@ dependencies = [ "digest 0.10.7", "hex", "md-5", - "rand 0.8.6", + "rand 0.8.7", "sha2 0.10.9", ] @@ -1893,9 +1938,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "embedded-io" @@ -1968,8 +2013,8 @@ dependencies = [ [[package]] name = "extensions_sv2" -version = "0.2.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.3.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -2002,7 +2047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand 0.8.6", + "rand 0.8.7", "rustc-hex", "static_assertions", ] @@ -2024,12 +2069,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -2041,8 +2080,8 @@ dependencies = [ [[package]] name = "framing_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -2202,30 +2241,16 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", + "r-efi", "rand_core 0.10.1", - "wasip2", - "wasip3", + "wasm-bindgen", ] [[package]] @@ -2262,8 +2287,8 @@ dependencies = [ [[package]] name = "handlers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2286,15 +2311,6 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - [[package]] name = "hashbrown" version = "0.17.1" @@ -2351,9 +2367,9 @@ dependencies = [ [[package]] name = "hex-conservative" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7289f6b628ce69fb1a371d0fdcf8ff38cd93ec00e3010eb055d1e044998c8d1" +checksum = "35431185f361ccf3ffc58254628af5f1f5d5f28531da2e02e5d6c82bbc282a10" dependencies = [ "arrayvec", ] @@ -2381,9 +2397,9 @@ checksum = "4398eddb78466298f1ddcc739abbbd8a942e541d1972c7590bd83de364e626e0" [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -2391,9 +2407,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -2401,9 +2417,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" dependencies = [ "bytes", "futures-core", @@ -2424,11 +2440,20 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -2454,7 +2479,7 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls 0.23.40", + "rustls 0.23.42", "tokio", "tokio-rustls", "tower-service", @@ -2477,7 +2502,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.3", + "socket2 0.6.5", "tokio", "tower-service", "tracing", @@ -2589,12 +2614,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idna" version = "1.1.0" @@ -2684,7 +2703,7 @@ dependencies = [ "once_cell", "pool_sv2", "primitive-types", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_json", "sha2 0.10.9", @@ -2825,31 +2844,30 @@ dependencies = [ [[package]] name = "job_declaration_sv2" -version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "10.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -2906,12 +2924,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" version = "0.2.186" @@ -2926,9 +2938,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ "libc", ] @@ -2968,9 +2980,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" dependencies = [ "value-bag", ] @@ -3017,9 +3029,9 @@ dependencies = [ [[package]] name = "md5" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0" +checksum = "7ebb8d8732c6a6df3d8f032a82911cfc747e00efb95cc46e8d0acd5b5b88570c" [[package]] name = "md5crypt" @@ -3042,9 +3054,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "mime" @@ -3070,21 +3082,21 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" -version = "11.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "12.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] [[package]] name = "miniscript" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867b1f11e0545ad5ebbddd8a9f18756d9657a6758bf10d96cf15ddd0b726b650" +checksum = "cd35e2c377504e50159561884b03610711db6c2fec6c89f2b98d94016684726b" dependencies = [ "bech32", "bitcoin", - "hex-conservative 1.1.0", + "hex-conservative 1.2.0", ] [[package]] @@ -3112,9 +3124,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -3124,11 +3136,11 @@ dependencies = [ [[package]] name = "noise_sv2" version = "1.4.2" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", "chacha20poly1305", - "rand 0.8.6", + "rand 0.8.7", "secp256k1 0.28.2", ] @@ -3285,8 +3297,8 @@ dependencies = [ [[package]] name = "parsers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -3311,9 +3323,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.6" +version = "2.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "47627dd7305c6a2d6c8c6bcd24c5a4c17dbbf425f4f9c5313e724b38fc9782e9" dependencies = [ "memchr", "ucd-trie", @@ -3321,9 +3333,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.6" +version = "2.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +checksum = "4b4254325ecad416ab689e27ba51da03ba01a9632bc6e108f5fe7c3c4ad29d58" dependencies = [ "pest", "pest_generator", @@ -3331,9 +3343,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.6" +version = "2.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +checksum = "6c4c0e91ead7a8f7acecbca6f003fc2e8282b1dbe2dd9c9d2f16aba42995e0a7" dependencies = [ "pest", "pest_meta", @@ -3344,12 +3356,11 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.6" +version = "2.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +checksum = "f9744bc48116fee06334924bb5f2bad41eed5e89bd26e29b0b799f9a3f82c210" dependencies = [ "pest", - "sha2 0.10.9", ] [[package]] @@ -3375,6 +3386,12 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "polling" version = "2.8.0" @@ -3462,16 +3479,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "primitive-types" version = "0.13.1" @@ -3489,7 +3496,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.11+spec-1.1.0", + "toml_edit 0.25.13+spec-1.1.0", ] [[package]] @@ -3533,9 +3540,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", @@ -3543,8 +3550,8 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.40", - "socket2 0.6.3", + "rustls 0.23.42", + "socket2 0.6.5", "thiserror 2.0.18", "tokio", "tracing", @@ -3553,18 +3560,19 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ "aws-lc-rs", "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.4", + "rand 0.10.2", + "rand_pcg", "ring", "rustc-hash", - "rustls 0.23.40", + "rustls 0.23.42", "rustls-pki-types", "slab", "thiserror 2.0.18", @@ -3575,33 +3583,27 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.3", + "socket2 0.6.5", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "r-efi" version = "6.0.0" @@ -3616,33 +3618,23 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "chacha20 0.10.0", - "getrandom 0.4.2", + "chacha20 0.10.1", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -3656,16 +3648,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - [[package]] name = "rand_core" version = "0.6.4" @@ -3677,18 +3659,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.5" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] -name = "rand_core" -version = "0.10.1" +name = "rand_pcg" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] [[package]] name = "redox_syscall" @@ -3696,7 +3678,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", ] [[package]] @@ -3712,9 +3694,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -3724,9 +3706,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" dependencies = [ "aho-corasick", "memchr", @@ -3735,9 +3717,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" @@ -3761,7 +3743,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.40", + "rustls 0.23.42", "rustls-pki-types", "rustls-platform-verifier", "serde", @@ -3810,16 +3792,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.11.1", + "bitflags 2.13.1", "serde", "serde_derive", ] [[package]] name = "rust-embed" -version = "8.11.0" +version = "8.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +checksum = "e9e7760e252aaba7b09f4be00e36476cf585bdb68a53552ac954cdf504ab4bc9" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -3828,10 +3810,11 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.11.0" +version = "8.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +checksum = "3bcfc4d6f53af43755f7a723e4b6b8794fcce052a178dd8c6c1dadc5f5343097" dependencies = [ + "mime_guess", "proc-macro2", "quote", "rust-embed-utils", @@ -3841,11 +3824,11 @@ dependencies = [ [[package]] name = "rust-embed-utils" -version = "8.11.0" +version = "8.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0" dependencies = [ - "sha2 0.10.9", + "sha2 0.11.0", "walkdir", ] @@ -3861,9 +3844,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc-hex" @@ -3900,11 +3883,11 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3913,7 +3896,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys 0.12.1", @@ -3934,9 +3917,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" dependencies = [ "aws-lc-rs", "once_cell", @@ -3960,9 +3943,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -3979,7 +3962,7 @@ dependencies = [ "jni", "log", "once_cell", - "rustls 0.23.40", + "rustls 0.23.42", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki 0.103.13", @@ -4019,9 +4002,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" @@ -4070,7 +4053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ "bitcoin_hashes 0.13.1", - "rand 0.8.6", + "rand 0.8.7", "secp256k1-sys 0.9.2", ] @@ -4080,7 +4063,7 @@ version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ - "bitcoin_hashes 0.14.1", + "bitcoin_hashes 0.14.101", "secp256k1-sys 0.10.1", "serde", ] @@ -4118,7 +4101,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "core-foundation", "core-foundation-sys", "libc", @@ -4173,9 +4156,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -4241,6 +4224,17 @@ dependencies = [ "sha2-asm", ] +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + [[package]] name = "sha2-asm" version = "0.6.4" @@ -4270,9 +4264,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -4286,15 +4280,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "simd_cesu8" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" dependencies = [ "rustc_version", "simdutf8", @@ -4314,9 +4308,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "smol" @@ -4347,9 +4341,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -4382,7 +4376,7 @@ dependencies = [ "futures", "miniscript", "prometheus", - "rand 0.8.6", + "rand 0.8.7", "rustversion", "secp256k1 0.28.2", "serde", @@ -4399,8 +4393,8 @@ dependencies = [ [[package]] name = "stratum-core" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -4422,8 +4416,8 @@ dependencies = [ [[package]] name = "stratum_translation" -version = "0.4.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.5.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -4469,8 +4463,8 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sv1_api" -version = "5.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "6.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -4482,9 +4476,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -4537,8 +4531,8 @@ dependencies = [ [[package]] name = "template_distribution_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -4585,9 +4579,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -4623,9 +4617,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -4638,9 +4632,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.3" +version = "1.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "317fafbbe3f02fc663dad00ea6186197de963cd4190e86a26d8d0fae095539af" dependencies = [ "bytes", "libc", @@ -4648,7 +4642,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.3", + "socket2 0.6.5", "tokio-macros", "tracing", "windows-sys 0.61.2", @@ -4671,7 +4665,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.40", + "rustls 0.23.42", "tokio", ] @@ -4746,14 +4740,14 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ "indexmap", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -4762,7 +4756,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -4794,7 +4788,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", - "bitflags 2.11.1", + "bitflags 2.13.1", "bytes", "futures-core", "futures-util", @@ -4921,9 +4915,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ucd-trie" @@ -4957,9 +4951,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -4973,7 +4967,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -5064,9 +5058,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" +checksum = "5dd4ec1eb1d240636e354a30110a1dfcb37047169a4d9bd6d9d3469df574b5c4" [[package]] name = "version_check" @@ -5105,29 +5099,11 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", -] - [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -5138,9 +5114,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -5148,9 +5124,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5158,9 +5134,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -5171,35 +5147,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.5.0" @@ -5213,23 +5167,11 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -5247,9 +5189,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] @@ -5377,6 +5319,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -5518,107 +5469,13 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.11.1", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "writeable" version = "0.6.3" @@ -5670,18 +5527,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", @@ -5711,9 +5568,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" @@ -5764,15 +5621,15 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" +checksum = "b142a20ec14a91d5bc708c1dc21b080c550113d8aa77afa29635673a65dd02c5" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zopfli" diff --git a/integration-tests/lib/interceptor.rs b/integration-tests/lib/interceptor.rs index 820934ad5..d386e4e44 100644 --- a/integration-tests/lib/interceptor.rs +++ b/integration-tests/lib/interceptor.rs @@ -1,7 +1,7 @@ use std::fmt; +use stratum_apps::stratum_core::parsers_sv2::AnyMessageOwned; use crate::types::MsgType; -use stratum_apps::stratum_core::parsers_sv2::AnyMessage; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MessageDirection { @@ -87,7 +87,7 @@ impl From for InterceptAction { pub struct ReplaceMessage { direction: MessageDirection, expected_message_type: MsgType, - pub(crate) replacement_message: AnyMessage<'static>, + pub(crate) replacement_message: AnyMessageOwned, } impl ReplaceMessage { @@ -99,7 +99,7 @@ impl ReplaceMessage { pub fn new( direction: MessageDirection, expected_message_type: MsgType, - replacement_message: AnyMessage<'static>, + replacement_message: AnyMessageOwned, ) -> Self { Self { direction, diff --git a/integration-tests/lib/message_aggregator.rs b/integration-tests/lib/message_aggregator.rs index 7140b10cc..8c29f8fc4 100644 --- a/integration-tests/lib/message_aggregator.rs +++ b/integration-tests/lib/message_aggregator.rs @@ -1,7 +1,7 @@ use std::{collections::VecDeque, sync::Arc}; use stratum_apps::{ custom_mutex::Mutex, - stratum_core::parsers_sv2::{AnyMessage, Tlv}, + stratum_core::parsers_sv2::{AnyMessageOwned, Tlv}, }; use crate::types::MsgType; @@ -9,7 +9,7 @@ use crate::types::MsgType; #[allow(clippy::type_complexity)] #[derive(Debug, Clone)] pub struct MessagesAggregator { - messages: Arc, Option>)>>>, + messages: Arc>)>>>, } impl Default for MessagesAggregator { @@ -27,7 +27,7 @@ impl MessagesAggregator { } /// Adds a message to the end of the queue. - pub fn add_message(&self, msg_type: MsgType, message: AnyMessage<'static>) { + pub fn add_message(&self, msg_type: MsgType, message: AnyMessageOwned) { self.add_message_with_tlvs(msg_type, message, None); } @@ -35,7 +35,7 @@ impl MessagesAggregator { pub fn add_message_with_tlvs( &self, msg_type: MsgType, - message: AnyMessage<'static>, + message: AnyMessageOwned, tlv_fields: Option>, ) { self.messages @@ -95,7 +95,7 @@ impl MessagesAggregator { /// the queue. /// /// The returned message is removed from the queue. - pub fn next_message(&self) -> Option<(MsgType, AnyMessage<'static>)> { + pub fn next_message(&self) -> Option<(MsgType, AnyMessageOwned)> { self.next_message_with_tlvs() .map(|(msg_type, msg, _)| (msg_type, msg)) } @@ -104,9 +104,7 @@ impl MessagesAggregator { /// with its TLV fields in the queue. /// /// The returned message is removed from the queue. - pub fn next_message_with_tlvs( - &self, - ) -> Option<(MsgType, AnyMessage<'static>, Option>)> { + pub fn next_message_with_tlvs(&self) -> Option<(MsgType, AnyMessageOwned, Option>)> { let is_state = self .messages .safe_lock(|messages| { diff --git a/integration-tests/lib/mining_device/mod.rs b/integration-tests/lib/mining_device/mod.rs index b1e4a1ce5..f26ad210d 100644 --- a/integration-tests/lib/mining_device/mod.rs +++ b/integration-tests/lib/mining_device/mod.rs @@ -25,13 +25,16 @@ use stratum_apps::{ }, codec_sv2::{HandshakeRole, StandardEitherFrame, StandardSv2Frame}, common_messages_sv2::{ - ChannelEndpointChanged, Protocol, Reconnect, SetupConnection, SetupConnectionError, - SetupConnectionSuccess, + ChannelEndpointChangedOwned, Protocol, ReconnectOwned, SetupConnectionErrorOwned, + SetupConnectionOwned, SetupConnectionSuccessOwned, }, mining_sv2, mining_sv2::*, noise_sv2::Initiator, - parsers_sv2::{CommonMessages, Mining, MiningDeviceMessages, ParserError}, + parsers_sv2::{ + CommonMessages, CommonMessagesOwned, Mining, MiningDeviceMessagesOwned, MiningOwned, + ParserError, + }, }, }; use tokio::net::TcpStream; @@ -149,7 +152,7 @@ pub async fn connect( .await } -pub type Message = MiningDeviceMessages<'static>; +pub type Message = MiningDeviceMessagesOwned; pub type StdFrame = StandardSv2Frame; pub type EitherFrame = StandardEitherFrame; @@ -178,7 +181,7 @@ impl SetupConnectionHandler { fn get_setup_connection_message( address: SocketAddr, device_id: Option, - ) -> SetupConnection<'static> { + ) -> SetupConnectionOwned { let endpoint_host = address.ip().to_string().try_into().unwrap(); let vendor = "".try_into().unwrap(); let hardware_version = "".try_into().unwrap(); @@ -188,7 +191,7 @@ impl SetupConnectionHandler { "Creating SetupConnection message with device id: {:?}", device_id ); - SetupConnection { + SetupConnectionOwned { protocol: Protocol::MiningProtocol, min_version: 2, max_version: 2, @@ -210,7 +213,7 @@ impl SetupConnectionHandler { ) { let setup_connection = Self::get_setup_connection_message(address, device_id); - let sv2_frame: StdFrame = MiningDeviceMessages::Common(setup_connection.into()) + let sv2_frame: StdFrame = MiningDeviceMessagesOwned::Common(setup_connection.into()) .try_into() .unwrap(); let sv2_frame = sv2_frame.into(); @@ -228,49 +231,50 @@ impl SetupConnectionHandler { message_type: u8, payload: &mut [u8], ) -> Result<(), ParserError> { - let message: CommonMessages<'_> = (message_type, payload).try_into()?; + let message: CommonMessagesOwned = + CommonMessages::try_from((message_type, payload))?.into_owned(); self_ .safe_lock(|handler| match message { - CommonMessages::SetupConnectionSuccess(m) => { + CommonMessagesOwned::SetupConnectionSuccess(m) => { handler.handle_setup_connection_success(m); Ok(()) } - CommonMessages::SetupConnectionError(m) => { + CommonMessagesOwned::SetupConnectionError(m) => { handler.handle_setup_connection_error(m); Ok(()) } - CommonMessages::ChannelEndpointChanged(m) => { + CommonMessagesOwned::ChannelEndpointChanged(m) => { handler.handle_channel_endpoint_changed(m); Ok(()) } - CommonMessages::Reconnect(m) => { + CommonMessagesOwned::Reconnect(m) => { handler.handle_reconnect(m); Ok(()) } - CommonMessages::SetupConnection(_) => { + CommonMessagesOwned::SetupConnection(_) => { Err(ParserError::UnexpectedMessage(message_type)) } }) .unwrap() } - fn handle_setup_connection_success(&mut self, m: SetupConnectionSuccess) { + fn handle_setup_connection_success(&mut self, m: SetupConnectionSuccessOwned) { info!( "Received `SetupConnectionSuccess`: version={}, flags={:b}", m.used_version, m.flags ); } - fn handle_setup_connection_error(&mut self, _: SetupConnectionError) { + fn handle_setup_connection_error(&mut self, _: SetupConnectionErrorOwned) { error!("Setup connection error"); todo!() } - fn handle_channel_endpoint_changed(&mut self, _: ChannelEndpointChanged) { + fn handle_channel_endpoint_changed(&mut self, _: ChannelEndpointChangedOwned) { todo!() } - fn handle_reconnect(&mut self, _m: Reconnect) { + fn handle_reconnect(&mut self, _m: ReconnectOwned) { todo!() } } @@ -290,8 +294,8 @@ pub struct Device { channel_opened: bool, channel_id: Option, miner: Arc>, - jobs: Vec>, - prev_hash: Option>, + jobs: Vec, + prev_hash: Option, sequence_numbers: Id, notify_changes_to_mining_thread: NewWorkNotifier, } @@ -300,7 +304,7 @@ fn open_channel( device_id: Option, nominal_hashrate_multiplier: Option, handicap: u32, -) -> OpenStandardMiningChannel<'static> { +) -> OpenStandardMiningChannelOwned { let user_identity = device_id.unwrap_or_default().try_into().unwrap(); let id: u32 = 10; info!("Measuring CPU hashrate"); @@ -318,11 +322,11 @@ fn open_channel( info!("MINING DEVICE: send open channel with request id {}", id); - OpenStandardMiningChannel { + OpenStandardMiningChannelOwned { request_id: id, user_identity, nominal_hash_rate, - max_target: vec![0xFF_u8; 32].try_into().unwrap(), + max_target: [0xFF_u8; 32].into(), } } @@ -364,9 +368,10 @@ impl Device { sender: notify_changes_to_mining_thread, }, }; - let open_channel = MiningDeviceMessages::Mining(Mining::OpenStandardMiningChannel( - open_channel(user_id, nominal_hashrate_multiplier, handicap), - )); + let open_channel = + MiningDeviceMessagesOwned::Mining(MiningOwned::OpenStandardMiningChannel( + open_channel(user_id, nominal_hashrate_multiplier, handicap), + )); let frame: StdFrame = open_channel.try_into().unwrap(); self_.sender.send(frame.into()).await.unwrap(); let self_mutex = std::sync::Arc::new(Mutex::new(self_)); @@ -416,15 +421,16 @@ impl Device { version: u32, ntime: u32, ) { - let share = - MiningDeviceMessages::Mining(Mining::SubmitSharesStandard(SubmitSharesStandard { + let share = MiningDeviceMessagesOwned::Mining(MiningOwned::SubmitSharesStandard( + SubmitSharesStandardOwned { channel_id: self_mutex.safe_lock(|s| s.channel_id.unwrap()).unwrap(), sequence_number: self_mutex.safe_lock(|s| s.sequence_numbers.next()).unwrap(), job_id, nonce, ntime, version, - })); + }, + )); let frame: StdFrame = share.try_into().unwrap(); let sender = self_mutex.safe_lock(|s| s.sender.clone()).unwrap(); sender.send(frame.into()).await.unwrap(); @@ -435,46 +441,46 @@ impl Device { message_type: u8, payload: &mut [u8], ) -> Result<(), ParserError> { - let message: Mining<'_> = (message_type, payload).try_into()?; + let message: MiningOwned = Mining::try_from((message_type, payload))?.into_owned(); self_ .safe_lock(|device| match message { - Mining::OpenStandardMiningChannelSuccess(m) => { + MiningOwned::OpenStandardMiningChannelSuccess(m) => { device.handle_open_standard_mining_channel_success(m); Ok(()) } - Mining::OpenMiningChannelError(m) => { + MiningOwned::OpenMiningChannelError(m) => { device.handle_open_mining_channel_error(m); Ok(()) } - Mining::UpdateChannelError(m) => { + MiningOwned::UpdateChannelError(m) => { device.handle_update_channel_error(m); Ok(()) } - Mining::CloseChannel(m) => { + MiningOwned::CloseChannel(m) => { device.handle_close_channel(m); Ok(()) } - Mining::SetExtranoncePrefix(m) => { + MiningOwned::SetExtranoncePrefix(m) => { device.handle_set_extranonce_prefix(m); Ok(()) } - Mining::SubmitSharesSuccess(m) => { + MiningOwned::SubmitSharesSuccess(m) => { device.handle_submit_shares_success(m); Ok(()) } - Mining::SubmitSharesError(m) => { + MiningOwned::SubmitSharesError(m) => { device.handle_submit_shares_error(m); Ok(()) } - Mining::NewMiningJob(m) => { + MiningOwned::NewMiningJob(m) => { device.handle_new_mining_job(m); Ok(()) } - Mining::SetNewPrevHash(m) => { + MiningOwned::SetNewPrevHash(m) => { device.handle_set_new_prev_hash(m); Ok(()) } - Mining::SetTarget(m) => { + MiningOwned::SetTarget(m) => { device.handle_set_target(m); Ok(()) } @@ -483,10 +489,13 @@ impl Device { .unwrap() } - fn handle_open_standard_mining_channel_success(&mut self, m: OpenStandardMiningChannelSuccess) { + fn handle_open_standard_mining_channel_success( + &mut self, + m: OpenStandardMiningChannelSuccessOwned, + ) { self.channel_opened = true; self.channel_id = Some(m.channel_id); - let req_id = m.get_request_id_as_u32(); + let req_id = m.request_id; info!( "MINING DEVICE: channel opened with: group id {}, channel id {}, request id {}", m.group_channel_id, m.channel_id, req_id @@ -497,87 +506,87 @@ impl Device { self.notify_changes_to_mining_thread.should_send = true; } - fn handle_open_mining_channel_error(&mut self, _: OpenMiningChannelError) { + fn handle_open_mining_channel_error(&mut self, _: OpenMiningChannelErrorOwned) { todo!() } - fn handle_update_channel_error(&mut self, _: UpdateChannelError) { + fn handle_update_channel_error(&mut self, _: UpdateChannelErrorOwned) { todo!() } - fn handle_close_channel(&mut self, _: CloseChannel) { + fn handle_close_channel(&mut self, _: CloseChannelOwned) { todo!() } - fn handle_set_extranonce_prefix(&mut self, _: SetExtranoncePrefix) { + fn handle_set_extranonce_prefix(&mut self, _: SetExtranoncePrefixOwned) { todo!() } - fn handle_submit_shares_success(&mut self, m: SubmitSharesSuccess) { + fn handle_submit_shares_success(&mut self, m: SubmitSharesSuccessOwned) { info!("Received SubmitSharesSuccess"); debug!("SubmitSharesSuccess: {}", m); } - fn handle_submit_shares_error(&mut self, m: SubmitSharesError) { + fn handle_submit_shares_error(&mut self, m: SubmitSharesErrorOwned) { error!( "Received SubmitSharesError with error code {}", std::str::from_utf8(m.error_code.as_ref()).unwrap_or("unknown error code") ); } - fn handle_new_mining_job(&mut self, m: NewMiningJob) { + fn handle_new_mining_job(&mut self, m: NewMiningJobOwned) { info!( "Received new mining job for channel id: {} with job id: {} is future: {}", m.channel_id, m.job_id, m.is_future() ); - debug!("NewMiningJob: {}", m); + debug!("NewMiningJob: {:?}", m); match (m.is_future(), self.prev_hash.as_ref()) { (false, Some(p_h)) => { self.miner .safe_lock(|miner| miner.new_header(p_h, &m)) .unwrap(); - self.jobs = vec![m.as_static()]; + self.jobs = vec![m]; self.notify_changes_to_mining_thread.should_send = true; } - (true, _) => self.jobs.push(m.as_static()), + (true, _) => self.jobs.push(m), (false, None) => { panic!() } } } - fn handle_set_new_prev_hash(&mut self, m: SetNewPrevHash) { + fn handle_set_new_prev_hash(&mut self, m: SetNewPrevHashOwned) { info!( "Received SetNewPrevHash channel id: {}, job id: {}", m.channel_id, m.job_id ); - debug!("SetNewPrevHash: {}", m); - let jobs: Vec<&NewMiningJob<'static>> = self + debug!("SetNewPrevHash: {:?}", m); + let jobs: Vec<&NewMiningJobOwned> = self .jobs .iter() .filter(|j| j.job_id == m.job_id && j.is_future()) .collect(); match jobs.len() { 0 => { - self.prev_hash = Some(m.as_static()); + self.prev_hash = Some(m); } 1 => { self.miner .safe_lock(|miner| miner.new_header(&m, jobs[0])) .unwrap(); self.jobs = vec![jobs[0].clone()]; - self.prev_hash = Some(m.as_static()); + self.prev_hash = Some(m); self.notify_changes_to_mining_thread.should_send = true; } _ => panic!(), } } - fn handle_set_target(&mut self, m: SetTarget) { + fn handle_set_target(&mut self, m: SetTargetOwned) { info!("Received SetTarget for channel id: {}", m.channel_id); - debug!("SetTarget: {}", m); + debug!("SetTarget: {:?}", m); self.miner .safe_lock(|miner| miner.new_target(m.maximum_target.to_owned_bytes())) .unwrap(); @@ -623,7 +632,7 @@ impl Miner { self.target = Some(U256::from_little_endian(target.as_slice())); } - fn new_header(&mut self, set_new_prev_hash: &SetNewPrevHash, new_job: &NewMiningJob) { + fn new_header(&mut self, set_new_prev_hash: &SetNewPrevHashOwned, new_job: &NewMiningJobOwned) { self.job_id = Some(new_job.job_id); self.version = Some(new_job.version); let prev_hash = set_new_prev_hash.prev_hash.to_array(); diff --git a/integration-tests/lib/mock_roles.rs b/integration-tests/lib/mock_roles.rs index e4f3142cf..c58e0dcb2 100644 --- a/integration-tests/lib/mock_roles.rs +++ b/integration-tests/lib/mock_roles.rs @@ -5,10 +5,10 @@ use stratum_apps::{ stratum_core::{ codec_sv2::StandardEitherFrame, common_messages_sv2::{ - Protocol, SetupConnection, SetupConnectionError, SetupConnectionSuccess, + Protocol, SetupConnectionErrorOwned, SetupConnectionOwned, SetupConnectionSuccessOwned, ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL, MESSAGE_TYPE_SETUP_CONNECTION, }, - parsers_sv2::{AnyMessage, CommonMessages, IsSv2Message}, + parsers_sv2::{AnyMessageOwned, CommonMessagesOwned, IsSv2Message}, }, utils::types::Sv2Frame, }; @@ -16,13 +16,13 @@ use tokio::net::TcpStream; use tracing::info; pub enum WithSetup { - Yes(SetupConnection<'static>), + Yes(SetupConnectionOwned), No, } impl WithSetup { pub fn yes_with_defaults(protocol: Protocol, flags: u32) -> Self { - WithSetup::Yes(SetupConnection { + WithSetup::Yes(SetupConnectionOwned { protocol, min_version: 2, max_version: 2, @@ -36,7 +36,7 @@ impl WithSetup { }) } - pub fn yes(setup_connection: SetupConnection<'static>) -> Self { + pub fn yes(setup_connection: SetupConnectionOwned) -> Self { WithSetup::Yes(setup_connection) } @@ -58,10 +58,10 @@ impl MockDownstream { } } - pub async fn start(self) -> Sender> { + pub async fn start(self) -> Sender { let upstream_address = self.upstream_address; - let (proxy_sender, proxy_receiver) = async_channel::unbounded::>(); + let (proxy_sender, proxy_receiver) = async_channel::unbounded::(); let (upstream_receiver, upstream_sender) = create_upstream(loop { match TcpStream::connect(upstream_address).await { @@ -80,9 +80,10 @@ impl MockDownstream { if let WithSetup::Yes(setup_connection) = self.setup { let protocol = setup_connection.protocol; let flags = setup_connection.flags; - let msg = AnyMessage::Common(CommonMessages::SetupConnection(setup_connection)); + let msg = + AnyMessageOwned::Common(CommonMessagesOwned::SetupConnection(setup_connection)); let message_type = msg.message_type(); - let frame = StandardEitherFrame::>::Sv2( + let frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message(msg, message_type, 0, false) .expect("Failed to create SetupConnection frame"), ); @@ -109,7 +110,7 @@ impl MockDownstream { tokio::spawn(async move { while let Ok(message) = proxy_receiver.recv().await { let message_type = message.message_type(); - let frame = StandardEitherFrame::>::Sv2( + let frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message(message, message_type, 0, false) .expect("Failed to create frame from message"), ); @@ -143,10 +144,10 @@ impl MockUpstream { self } - pub async fn start(self) -> Sender> { + pub async fn start(self) -> Sender { let listening_address = self.listening_address; - let (proxy_sender, proxy_receiver) = async_channel::unbounded::>(); + let (proxy_sender, proxy_receiver) = async_channel::unbounded::(); tokio::spawn(async move { let (downstream_receiver, downstream_sender) = @@ -169,16 +170,21 @@ impl MockUpstream { ); if msg_type == MESSAGE_TYPE_SETUP_CONNECTION { - if let AnyMessage::Common(CommonMessages::SetupConnection(setup_msg)) = &msg { + if let AnyMessageOwned::Common(CommonMessagesOwned::SetupConnection( + setup_msg, + )) = &msg + { if setup_msg.protocol == expected_protocol { - let success = AnyMessage::Common( - CommonMessages::SetupConnectionSuccess(SetupConnectionSuccess { - used_version: 2, - flags, - }), + let success = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess( + SetupConnectionSuccessOwned { + used_version: 2, + flags, + }, + ), ); let success_type = success.message_type(); - let response_frame = StandardEitherFrame::>::Sv2( + let response_frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message(success, success_type, 0, false) .expect("Failed to create SetupConnectionSuccess frame"), ); @@ -198,18 +204,20 @@ impl MockUpstream { return; } } else { - let error = AnyMessage::Common(CommonMessages::SetupConnectionError( - SetupConnectionError { - flags: 0, - error_code: ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL - .to_string() - .into_bytes() - .try_into() - .unwrap(), - }, - )); + let error = + AnyMessageOwned::Common(CommonMessagesOwned::SetupConnectionError( + SetupConnectionErrorOwned { + flags: 0, + error_code: + ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL + .to_string() + .into_bytes() + .try_into() + .unwrap(), + }, + )); let error_type = error.message_type(); - let response_frame = StandardEitherFrame::>::Sv2( + let response_frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message(error, error_type, 0, false) .expect("Failed to create SetupConnectionError frame"), ); @@ -240,7 +248,7 @@ impl MockUpstream { while let Ok(message) = proxy_receiver.recv().await { let message_type = message.message_type(); - let frame = StandardEitherFrame::>::Sv2( + let frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message(message, message_type, 0, false) .expect("Failed to create frame from message"), ); diff --git a/integration-tests/lib/sniffer.rs b/integration-tests/lib/sniffer.rs index 9358b5cc0..9dcd5a12a 100644 --- a/integration-tests/lib/sniffer.rs +++ b/integration-tests/lib/sniffer.rs @@ -11,7 +11,7 @@ use std::{ net::SocketAddr, sync::{Arc, Mutex}, }; -use stratum_apps::stratum_core::parsers_sv2::{message_type_to_name, AnyMessage}; +use stratum_apps::stratum_core::parsers_sv2::{message_type_to_name, AnyMessageOwned}; use tokio::{net::TcpStream, select}; const DEFAULT_TIMEOUT: u64 = 60; @@ -121,7 +121,7 @@ impl<'a> Sniffer<'a> { /// This can be used to assert that the downstream sent: /// - specific message types /// - specific message fields - pub fn next_message_from_downstream(&self) -> Option<(MsgType, AnyMessage<'static>)> { + pub fn next_message_from_downstream(&self) -> Option<(MsgType, AnyMessageOwned)> { self.messages_from_downstream.next_message() } @@ -132,7 +132,7 @@ impl<'a> Sniffer<'a> { &self, ) -> Option<( MsgType, - AnyMessage<'static>, + AnyMessageOwned, Option>, )> { self.messages_from_downstream.next_message_with_tlvs() @@ -145,7 +145,7 @@ impl<'a> Sniffer<'a> { /// This can be used to assert that the upstream sent: /// - specific message types /// - specific message fields - pub fn next_message_from_upstream(&self) -> Option<(MsgType, AnyMessage<'static>)> { + pub fn next_message_from_upstream(&self) -> Option<(MsgType, AnyMessageOwned)> { self.messages_from_upstream.next_message() } @@ -156,7 +156,7 @@ impl<'a> Sniffer<'a> { &self, ) -> Option<( MsgType, - AnyMessage<'static>, + AnyMessageOwned, Option>, )> { self.messages_from_upstream.next_message_with_tlvs() @@ -293,19 +293,19 @@ impl<'a> Sniffer<'a> { // This macro can be called in two ways: // 1. If you want to assert the message without any of its properties, you can invoke the macro // with the message group, the nested message group, the message, and the expected message: -// `assert_message!(TemplateDistribution, TemplateDistribution, $msg, +// `assert_message!(TemplateDistribution, TemplateDistributionOwned, $msg, // $expected_message_variant);`. // // 2. If you want to assert the message with its properties, you can invoke the macro with the // message group, the nested message group, the message, the expected message, and the expected // properties and values: -// `assert_message!(TemplateDistribution, TemplateDistribution, $msg, $expected_message_variant, -// $expected_property, $expected_property_value, ...);`. +// `assert_message!(TemplateDistribution, TemplateDistributionOwned, $msg, +// $expected_message_variant, $expected_property, $expected_property_value, ...);`. // Note that you can provide any number of properties and values. // -// In both cases, the `$message_group` could be any variant of `AnyMessage::$message_group` and -// the `$nested_message_group` could be any variant of -// `AnyMessage::$message_group($nested_message_group)`. +// In both cases, the `$message_group` could be any variant of `AnyMessageOwned::$message_group` +// and the `$nested_message_group` could be any variant of +// `AnyMessageOwned::$message_group($nested_message_group)`. // // If you dont want to provide the `$message_group` and `$nested_message_group` arguments, you can // utilize `assert_common_message!`, `assert_tp_message!`, `assert_mining_message!`, and @@ -317,15 +317,11 @@ macro_rules! assert_message { ($message_group:ident, $nested_message_group:ident, $msg:expr, $expected_message_variant:ident, $($expected_property:ident, $expected_property_value:expr),*) => { match $msg { Some((_, message)) => { + use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, $nested_message_group}; match message { - AnyMessage::$message_group($nested_message_group::$expected_message_variant( - $expected_message_variant { - $($expected_property,)* - .. - }, - )) => { + AnyMessageOwned::$message_group($nested_message_group::$expected_message_variant(message_payload)) => { $( - assert_eq!($expected_property.clone(), $expected_property_value); + assert_eq!(message_payload.$expected_property.clone(), $expected_property_value); )* } _ => { @@ -342,8 +338,9 @@ macro_rules! assert_message { ($message_group:ident, $nested_message_group:ident, $msg:expr, $expected_message_variant:ident) => { match $msg { Some((_, message)) => { + use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, $nested_message_group}; match message { - AnyMessage::$message_group($nested_message_group::$expected_message_variant(_)) => {} + AnyMessageOwned::$message_group($nested_message_group::$expected_message_variant(_)) => {} _ => { panic!( "Sent wrong message: {:?}", @@ -361,10 +358,10 @@ macro_rules! assert_message { #[macro_export] macro_rules! assert_common_message { ($msg:expr, $expected_message_variant:ident, $($expected_property:ident, $expected_property_value:expr),*) => { - assert_message!(Common, CommonMessages, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); + assert_message!(Common, CommonMessagesOwned, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); }; ($msg:expr, $expected_message_variant:ident) => { - assert_message!(Common, CommonMessages, $msg, $expected_message_variant); + assert_message!(Common, CommonMessagesOwned, $msg, $expected_message_variant); }; } @@ -373,10 +370,10 @@ macro_rules! assert_common_message { #[macro_export] macro_rules! assert_tp_message { ($msg:expr, $expected_message_variant:ident, $($expected_property:ident, $expected_property_value:expr),*) => { - assert_message!(TemplateDistribution, TemplateDistribution, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); + assert_message!(TemplateDistribution, TemplateDistributionOwned, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); }; ($msg:expr, $expected_message_variant:ident) => { - assert_message!(TemplateDistribution, TemplateDistribution, $msg, $expected_message_variant); + assert_message!(TemplateDistribution, TemplateDistributionOwned, $msg, $expected_message_variant); }; } @@ -384,10 +381,10 @@ macro_rules! assert_tp_message { #[macro_export] macro_rules! assert_mining_message { ($msg:expr, $expected_message_variant:ident, $($expected_property:ident, $expected_property_value:expr),*) => { - assert_message!(Mining, Mining, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); + assert_message!(Mining, MiningOwned, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); }; ($msg:expr, $expected_message_variant:ident) => { - assert_message!(Mining, Mining, $msg, $expected_message_variant); + assert_message!(Mining, MiningOwned, $msg, $expected_message_variant); }; } @@ -396,10 +393,10 @@ macro_rules! assert_mining_message { #[macro_export] macro_rules! assert_jd_message { ($msg:expr, $expected_message_variant:ident, $($expected_property:ident, $expected_property_value:expr),*) => { - assert_message!(JobDeclaration, JobDeclaration, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); + assert_message!(JobDeclaration, JobDeclarationOwned, $msg, $expected_message_variant, $($expected_property, $expected_property_value),*); }; ($msg:expr, $expected_message_variant:ident) => { - assert_message!(JobDeclaration, JobDeclaration, $msg, $expected_message_variant); + assert_message!(JobDeclaration, JobDeclarationOwned, $msg, $expected_message_variant); }; } diff --git a/integration-tests/lib/types.rs b/integration-tests/lib/types.rs index a707d59db..617ab714b 100644 --- a/integration-tests/lib/types.rs +++ b/integration-tests/lib/types.rs @@ -1,4 +1,4 @@ -use stratum_apps::stratum_core::{codec_sv2::StandardEitherFrame, parsers_sv2::AnyMessage}; +use stratum_apps::stratum_core::{codec_sv2::StandardEitherFrame, parsers_sv2::AnyMessageOwned}; -pub type MessageFrame = StandardEitherFrame>; +pub type MessageFrame = StandardEitherFrame; pub type MsgType = u8; diff --git a/integration-tests/lib/utils.rs b/integration-tests/lib/utils.rs index 8551d585a..ac459f372 100644 --- a/integration-tests/lib/utils.rs +++ b/integration-tests/lib/utils.rs @@ -20,16 +20,8 @@ use stratum_apps::{ framing_sv2::framing::{Frame, Sv2Frame}, noise_sv2::{Initiator, Responder}, parsers_sv2::{ - message_type_to_name, parse_message_frame_with_tlvs, AnyMessage, CommonMessages, - IsSv2Message, - JobDeclaration::{ - AllocateMiningJobToken, AllocateMiningJobTokenSuccess, DeclareMiningJob, - DeclareMiningJobError, DeclareMiningJobSuccess, ProvideMissingTransactions, - ProvideMissingTransactionsSuccess, PushSolution, - }, - TemplateDistribution, - TemplateDistribution::CoinbaseOutputConstraints, - Tlv, + message_type_to_name, parse_message_frame_with_tlvs, AnyMessage, AnyMessageOwned, + ExtensionsNegotiationOwned, ExtensionsOwned, IsSv2Message, Tlv, }, }, }; @@ -86,7 +78,7 @@ pub async fn create_downstream( .unwrap(); if let Ok((receiver_from_client, sender_to_client)) = - Connection::new::>(stream, HandshakeRole::Responder(responder)).await + Connection::new::(stream, HandshakeRole::Responder(responder)).await { Some((receiver_from_client, sender_to_client)) } else { @@ -99,7 +91,7 @@ pub async fn create_upstream( ) -> Option<(Receiver, Sender)> { let initiator = Initiator::without_pk().expect("This fn call can not fail"); if let Ok((receiver_from_server, sender_to_server)) = - Connection::new::>(stream, HandshakeRole::Initiator(initiator)).await + Connection::new::(stream, HandshakeRole::Initiator(initiator)).await { Some((receiver_from_server, sender_to_server)) } else { @@ -120,20 +112,17 @@ pub async fn recv_from_down_send_to_up( let (msg_type, msg, tlv_fields) = message_from_frame_with_tlvs(&mut frame, &extensions); // Track extension negotiation - if let AnyMessage::Extensions(ref ext_msg) = msg { - use stratum_apps::stratum_core::parsers_sv2::{Extensions, ExtensionsNegotiation}; - if let Extensions::ExtensionsNegotiation( - ExtensionsNegotiation::RequestExtensionsSuccess(ref success), - ) = ext_msg - { - let mut exts = negotiated_extensions.lock().unwrap(); - *exts = success.supported_extensions.clone().into_inner(); - tracing::info!( - "🔍 Sniffer {} | Tracked negotiated extensions: {:?}", - identifier, - *exts - ); - } + if let AnyMessageOwned::Extensions(ExtensionsOwned::ExtensionsNegotiation( + ExtensionsNegotiationOwned::RequestExtensionsSuccess(ref success), + )) = msg + { + let mut exts = negotiated_extensions.lock().unwrap(); + *exts = success.supported_extensions.clone().into_inner(); + tracing::info!( + "🔍 Sniffer {} | Tracked negotiated extensions: {:?}", + identifier, + *exts + ); } let action = action.iter().find(|action| { @@ -152,7 +141,7 @@ pub async fn recv_from_down_send_to_up( continue; } InterceptAction::ReplaceMessage(intercept_message) => { - let intercept_frame = StandardEitherFrame::>::Sv2( + let intercept_frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message( intercept_message.replacement_message.clone(), intercept_message.replacement_message.message_type(), @@ -206,20 +195,17 @@ pub async fn recv_from_up_send_to_down( let (msg_type, msg, tlv_fields) = message_from_frame_with_tlvs(&mut frame, &extensions); // Track extension negotiation - if let AnyMessage::Extensions(ref ext_msg) = msg { - use stratum_apps::stratum_core::parsers_sv2::{Extensions, ExtensionsNegotiation}; - if let Extensions::ExtensionsNegotiation( - ExtensionsNegotiation::RequestExtensionsSuccess(ref success), - ) = ext_msg - { - let mut exts = negotiated_extensions.lock().unwrap(); - *exts = success.supported_extensions.clone().into_inner(); - tracing::info!( - "🔍 Sniffer {} | Tracked negotiated extensions: {:?}", - identifier, - *exts - ); - } + if let AnyMessageOwned::Extensions(ExtensionsOwned::ExtensionsNegotiation( + ExtensionsNegotiationOwned::RequestExtensionsSuccess(ref success), + )) = msg + { + let mut exts = negotiated_extensions.lock().unwrap(); + *exts = success.supported_extensions.clone().into_inner(); + tracing::info!( + "🔍 Sniffer {} | Tracked negotiated extensions: {:?}", + identifier, + *exts + ); } let action = action.iter().find(|action| { @@ -239,7 +225,7 @@ pub async fn recv_from_up_send_to_down( continue; } InterceptAction::ReplaceMessage(intercept_message) => { - let intercept_frame = StandardEitherFrame::>::Sv2( + let intercept_frame = StandardEitherFrame::::Sv2( Sv2Frame::from_message( intercept_message.replacement_message.clone(), intercept_message.replacement_message.message_type(), @@ -280,7 +266,7 @@ pub async fn recv_from_up_send_to_down( Err(SnifferError::UpstreamClosed) } -pub fn message_from_frame(frame: &mut MessageFrame) -> (MsgType, AnyMessage<'static>) { +pub fn message_from_frame(frame: &mut MessageFrame) -> (MsgType, AnyMessageOwned) { let (msg_type, msg, _) = message_from_frame_with_tlvs(frame, &[]); (msg_type, msg) } @@ -288,7 +274,7 @@ pub fn message_from_frame(frame: &mut MessageFrame) -> (MsgType, AnyMessage<'sta pub fn message_from_frame_with_tlvs( frame: &mut MessageFrame, negotiated_extensions: &[u16], -) -> (MsgType, AnyMessage<'static>, Option>) { +) -> (MsgType, AnyMessageOwned, Option>) { match frame { Frame::Sv2(frame) => { if let Some(header) = frame.get_header() { @@ -298,7 +284,7 @@ pub fn message_from_frame_with_tlvs( if !negotiated_extensions.is_empty() { match parse_message_frame_with_tlvs(header, payload, negotiated_extensions) { Ok((message, tlv_fields)) => { - let message = into_static(message); + let message = into_owned(message); return (header.msg_type(), message, tlv_fields); } Err(e) => { @@ -313,7 +299,7 @@ pub fn message_from_frame_with_tlvs( (header, payload.as_mut_slice()).try_into(); match message { Ok(message) => { - let message = into_static(message); + let message = into_owned(message); (header.msg_type(), message, None) } _ => { @@ -333,77 +319,8 @@ pub fn message_from_frame_with_tlvs( } } -pub fn into_static(m: AnyMessage<'_>) -> AnyMessage<'static> { - match m { - AnyMessage::Mining(m) => AnyMessage::Mining(m.into_static()), - AnyMessage::Common(m) => match m { - CommonMessages::ChannelEndpointChanged(m) => { - AnyMessage::Common(CommonMessages::ChannelEndpointChanged(m.into_static())) - } - CommonMessages::SetupConnection(m) => { - AnyMessage::Common(CommonMessages::SetupConnection(m.into_static())) - } - CommonMessages::SetupConnectionError(m) => { - AnyMessage::Common(CommonMessages::SetupConnectionError(m.into_static())) - } - CommonMessages::SetupConnectionSuccess(m) => { - AnyMessage::Common(CommonMessages::SetupConnectionSuccess(m.into_static())) - } - CommonMessages::Reconnect(m) => { - AnyMessage::Common(CommonMessages::Reconnect(m.into_static())) - } - }, - AnyMessage::JobDeclaration(m) => match m { - AllocateMiningJobToken(m) => { - AnyMessage::JobDeclaration(AllocateMiningJobToken(m.into_static())) - } - AllocateMiningJobTokenSuccess(m) => { - AnyMessage::JobDeclaration(AllocateMiningJobTokenSuccess(m.into_static())) - } - DeclareMiningJob(m) => AnyMessage::JobDeclaration(DeclareMiningJob(m.into_static())), - DeclareMiningJobError(m) => { - AnyMessage::JobDeclaration(DeclareMiningJobError(m.into_static())) - } - DeclareMiningJobSuccess(m) => { - AnyMessage::JobDeclaration(DeclareMiningJobSuccess(m.into_static())) - } - ProvideMissingTransactions(m) => { - AnyMessage::JobDeclaration(ProvideMissingTransactions(m.into_static())) - } - ProvideMissingTransactionsSuccess(m) => { - AnyMessage::JobDeclaration(ProvideMissingTransactionsSuccess(m.into_static())) - } - PushSolution(m) => AnyMessage::JobDeclaration(PushSolution(m.into_static())), - }, - AnyMessage::TemplateDistribution(m) => match m { - CoinbaseOutputConstraints(m) => { - AnyMessage::TemplateDistribution(CoinbaseOutputConstraints(m.into_static())) - } - TemplateDistribution::NewTemplate(m) => { - AnyMessage::TemplateDistribution(TemplateDistribution::NewTemplate(m.into_static())) - } - TemplateDistribution::RequestTransactionData(m) => AnyMessage::TemplateDistribution( - TemplateDistribution::RequestTransactionData(m.into_static()), - ), - TemplateDistribution::RequestTransactionDataError(m) => { - AnyMessage::TemplateDistribution(TemplateDistribution::RequestTransactionDataError( - m.into_static(), - )) - } - TemplateDistribution::RequestTransactionDataSuccess(m) => { - AnyMessage::TemplateDistribution( - TemplateDistribution::RequestTransactionDataSuccess(m.into_static()), - ) - } - TemplateDistribution::SetNewPrevHash(m) => AnyMessage::TemplateDistribution( - TemplateDistribution::SetNewPrevHash(m.into_static()), - ), - TemplateDistribution::SubmitSolution(m) => AnyMessage::TemplateDistribution( - TemplateDistribution::SubmitSolution(m.into_static()), - ), - }, - AnyMessage::Extensions(extensions) => AnyMessage::Extensions(extensions.into_static()), - } +pub fn into_owned(m: AnyMessage<'_>) -> AnyMessageOwned { + m.into_owned() } pub mod http { diff --git a/integration-tests/tests/bitcoin_core_ipc_tdp_io.rs b/integration-tests/tests/bitcoin_core_ipc_tdp_io.rs index cd9ec4c51..f3d1c4b50 100644 --- a/integration-tests/tests/bitcoin_core_ipc_tdp_io.rs +++ b/integration-tests/tests/bitcoin_core_ipc_tdp_io.rs @@ -22,9 +22,10 @@ use stratum_apps::{ CancellationToken, }, stratum_core::{ - parsers_sv2::TemplateDistribution, + parsers_sv2::TemplateDistributionOwned, template_distribution_sv2::{ - CoinbaseOutputConstraints, RequestTransactionData, RequestTransactionDataSuccess, + CoinbaseOutputConstraintsOwned, RequestTransactionDataOwned, + RequestTransactionDataSuccessOwned, ERROR_CODE_REQUEST_TRANSACTION_DATA_STALE_TEMPLATE_ID, ERROR_CODE_REQUEST_TRANSACTION_DATA_TEMPLATE_ID_NOT_FOUND, }, @@ -97,13 +98,13 @@ async fn assert_tdp_io_integration(version: BitcoinCoreVersion) { } async fn bootstrap_tdp_and_get_template_id( - incoming_sender: &Sender>, - outgoing_receiver: &Receiver>, + incoming_sender: &Sender, + outgoing_receiver: &Receiver, ) -> u64 { // TDP requires CoinbaseOutputConstraints first; this triggers initial template publication. incoming_sender - .send(TemplateDistribution::CoinbaseOutputConstraints( - CoinbaseOutputConstraints { + .send(TemplateDistributionOwned::CoinbaseOutputConstraints( + CoinbaseOutputConstraintsOwned { coinbase_output_max_additional_size: 2, coinbase_output_max_additional_sigops: 2, }, @@ -112,20 +113,20 @@ async fn bootstrap_tdp_and_get_template_id( .expect("failed to send CoinbaseOutputConstraints"); let new_template = recv_tdp_message(outgoing_receiver, Duration::from_secs(20), |msg| { - matches!(msg, TemplateDistribution::NewTemplate(_)) + matches!(msg, TemplateDistributionOwned::NewTemplate(_)) }) .await; let new_template = match new_template { - TemplateDistribution::NewTemplate(message) => message, + TemplateDistributionOwned::NewTemplate(message) => message, _ => unreachable!("message kind already filtered"), }; let set_new_prev_hash = recv_tdp_message(outgoing_receiver, Duration::from_secs(20), |msg| { - matches!(msg, TemplateDistribution::SetNewPrevHash(_)) + matches!(msg, TemplateDistributionOwned::SetNewPrevHash(_)) }) .await; let set_new_prev_hash = match set_new_prev_hash { - TemplateDistribution::SetNewPrevHash(message) => message, + TemplateDistributionOwned::SetNewPrevHash(message) => message, _ => unreachable!("message kind already filtered"), }; @@ -134,8 +135,8 @@ async fn bootstrap_tdp_and_get_template_id( } async fn assert_tdp_request_tx_data_success( - incoming_sender: &Sender>, - outgoing_receiver: &Receiver>, + incoming_sender: &Sender, + outgoing_receiver: &Receiver, template_id: u64, ) { let response = request_tdp_tx_data_and_recv_response_for_template_id( @@ -146,8 +147,8 @@ async fn assert_tdp_request_tx_data_success( ) .await; - let request_tx_data_success: RequestTransactionDataSuccess<'static> = match response { - TemplateDistribution::RequestTransactionDataSuccess(message) => message, + let request_tx_data_success: RequestTransactionDataSuccessOwned = match response { + TemplateDistributionOwned::RequestTransactionDataSuccess(message) => message, _ => unreachable!("message kind already filtered"), }; @@ -158,8 +159,8 @@ async fn assert_tdp_request_tx_data_success( } async fn assert_tdp_request_tx_data_not_found( - incoming_sender: &Sender>, - outgoing_receiver: &Receiver>, + incoming_sender: &Sender, + outgoing_receiver: &Receiver, ) { let not_found_response = request_tdp_tx_data_and_recv_response_for_template_id( incoming_sender, @@ -170,7 +171,7 @@ async fn assert_tdp_request_tx_data_not_found( .await; match not_found_response { - TemplateDistribution::RequestTransactionDataError(message) => { + TemplateDistributionOwned::RequestTransactionDataError(message) => { assert_eq!( message.error_code.as_utf8_or_hex(), ERROR_CODE_REQUEST_TRANSACTION_DATA_TEMPLATE_ID_NOT_FOUND, @@ -183,8 +184,8 @@ async fn assert_tdp_request_tx_data_not_found( async fn assert_tdp_old_template_eventually_stale( bitcoin_core: &BitcoinCore, - incoming_sender: &Sender>, - outgoing_receiver: &Receiver>, + incoming_sender: &Sender, + outgoing_receiver: &Receiver, old_template_id: u64, ) { // Force a tip change so the previously active template becomes non-current. @@ -194,13 +195,13 @@ async fn assert_tdp_old_template_eventually_stale( recv_tdp_message(outgoing_receiver, Duration::from_secs(20), |msg| { matches!( msg, - TemplateDistribution::SetNewPrevHash(message) + TemplateDistributionOwned::SetNewPrevHash(message) if message.template_id != old_template_id ) }) .await; match next_set_new_prev_hash { - TemplateDistribution::SetNewPrevHash(_) => {} + TemplateDistributionOwned::SetNewPrevHash(_) => {} _ => unreachable!("message kind already filtered"), } @@ -221,14 +222,14 @@ async fn assert_tdp_old_template_eventually_stale( .await; match stale_response { - TemplateDistribution::RequestTransactionDataError(message) => { + TemplateDistributionOwned::RequestTransactionDataError(message) => { let error_code = message.error_code.as_utf8_or_hex(); if error_code == ERROR_CODE_REQUEST_TRANSACTION_DATA_STALE_TEMPLATE_ID { break; } panic!("expected stale-template-id, got error code: {error_code}"); } - TemplateDistribution::RequestTransactionDataSuccess(_) => { + TemplateDistributionOwned::RequestTransactionDataSuccess(_) => { tokio::time::sleep(Duration::from_millis(250)).await; } _ => unreachable!("message kind already filtered"), @@ -237,12 +238,12 @@ async fn assert_tdp_old_template_eventually_stale( } async fn recv_tdp_message( - receiver: &Receiver>, + receiver: &Receiver, timeout: Duration, predicate: F, -) -> TemplateDistribution<'static> +) -> TemplateDistributionOwned where - F: Fn(&TemplateDistribution<'static>) -> bool, + F: Fn(&TemplateDistributionOwned) -> bool, { let deadline = Instant::now() + timeout; @@ -264,15 +265,15 @@ where } async fn request_tdp_tx_data_and_recv_response_for_template_id( - incoming_sender: &Sender>, - outgoing_receiver: &Receiver>, + incoming_sender: &Sender, + outgoing_receiver: &Receiver, template_id: u64, timeout: Duration, -) -> TemplateDistribution<'static> { +) -> TemplateDistributionOwned { // Send request and then wait for either success or error that matches the same template id. incoming_sender - .send(TemplateDistribution::RequestTransactionData( - RequestTransactionData { template_id }, + .send(TemplateDistributionOwned::RequestTransactionData( + RequestTransactionDataOwned { template_id }, )) .await .expect("failed to send RequestTransactionData"); @@ -280,11 +281,11 @@ async fn request_tdp_tx_data_and_recv_response_for_template_id( recv_tdp_message(outgoing_receiver, timeout, |msg| { matches!( msg, - TemplateDistribution::RequestTransactionDataSuccess(message) + TemplateDistributionOwned::RequestTransactionDataSuccess(message) if message.template_id == template_id ) || matches!( msg, - TemplateDistribution::RequestTransactionDataError(message) + TemplateDistributionOwned::RequestTransactionDataError(message) if message.template_id == template_id ) }) diff --git a/integration-tests/tests/extensions.rs b/integration-tests/tests/extensions.rs index 7968bb773..c96386e8b 100644 --- a/integration-tests/tests/extensions.rs +++ b/integration-tests/tests/extensions.rs @@ -1,3 +1,6 @@ +use stratum_apps::stratum_core::parsers_sv2::{ + AnyMessageOwned, ExtensionsNegotiationOwned, ExtensionsOwned, MiningOwned, +}; // Integration test for translator extension negotiation with extension 0x0002 // (EXTENSION_TYPE_WORKER_HASHRATE_TRACKING) and user_identity TLV validation. // @@ -9,11 +12,10 @@ use integration_tests_sv2::{interceptor::MessageDirection, template_provider::DifficultyLevel, *}; use stratum_apps::stratum_core::{ - binary_sv2::Seq064K, + binary_sv2::Seq064KOwned, common_messages_sv2::*, extensions_sv2::{EXTENSION_TYPE_WORKER_HASHRATE_TRACKING, TLV_FIELD_TYPE_USER_IDENTITY}, mining_sv2::*, - parsers_sv2::{AnyMessage, Extensions, ExtensionsNegotiation, Mining}, }; use tracing::info; @@ -75,8 +77,8 @@ async fn test_extension_negotiation_with_tlv_in_submit_shares() { let request_extensions_msg = match pool_translator_sniffer.next_message_from_downstream() { Some(( _, - AnyMessage::Extensions(Extensions::ExtensionsNegotiation( - ExtensionsNegotiation::RequestExtensions(msg), + AnyMessageOwned::Extensions(ExtensionsOwned::ExtensionsNegotiation( + ExtensionsNegotiationOwned::RequestExtensions(msg), )), )) => msg, _ => panic!( @@ -86,7 +88,7 @@ async fn test_extension_negotiation_with_tlv_in_submit_shares() { }; assert_eq!( request_extensions_msg.requested_extensions, - Seq064K::new(supported_extensions.clone()).unwrap() + Seq064KOwned::new(supported_extensions.clone()).unwrap() ); // Verify RequestExtensionsSuccess acknowledges the extension @@ -94,13 +96,13 @@ async fn test_extension_negotiation_with_tlv_in_submit_shares() { match request_extensions_success_msg { Some(( _, - AnyMessage::Extensions(Extensions::ExtensionsNegotiation( - ExtensionsNegotiation::RequestExtensionsSuccess(msg), + AnyMessageOwned::Extensions(ExtensionsOwned::ExtensionsNegotiation( + ExtensionsNegotiationOwned::RequestExtensionsSuccess(msg), )), )) => { assert_eq!( msg.supported_extensions, - Seq064K::new(supported_extensions).unwrap() + Seq064KOwned::new(supported_extensions).unwrap() ); } _ => panic!("Expected RequestExtensionsSuccess message"), @@ -116,7 +118,7 @@ async fn test_extension_negotiation_with_tlv_in_submit_shares() { // Extract and verify user_identity from OpenExtendedMiningChannel let open_channel_msg = pool_translator_sniffer.next_message_from_downstream(); match open_channel_msg { - Some((_, AnyMessage::Mining(Mining::OpenExtendedMiningChannel(msg)))) => { + Some((_, AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel(msg)))) => { let user_identity = msg.user_identity.as_utf8_or_hex(); assert_eq!(user_identity, "user_identity.miner1".to_string()); } @@ -149,7 +151,7 @@ async fn test_extension_negotiation_with_tlv_in_submit_shares() { // Verify SubmitSharesExtended contains TLV with user_identity let submit_shares_msg = pool_translator_sniffer.next_message_from_downstream_with_tlvs(); match submit_shares_msg { - Some((_, AnyMessage::Mining(Mining::SubmitSharesExtended(msg)), tlv_fields)) => { + Some((_, AnyMessageOwned::Mining(MiningOwned::SubmitSharesExtended(msg)), tlv_fields)) => { info!( "SubmitSharesExtended received - channel_id: {}, sequence_number: {}, job_id: {}", msg.channel_id, msg.sequence_number, msg.job_id diff --git a/integration-tests/tests/jd_integration.rs b/integration-tests/tests/jd_integration.rs index 89792f979..a5a81257f 100644 --- a/integration-tests/tests/jd_integration.rs +++ b/integration-tests/tests/jd_integration.rs @@ -1,3 +1,4 @@ +use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, JobDeclarationOwned, MiningOwned}; // This file contains integration tests for the `JDC/S` module. use integration_tests_sv2::{ interceptor::{MessageDirection, ReplaceMessage}, @@ -7,11 +8,11 @@ use integration_tests_sv2::{ *, }; use stratum_apps::stratum_core::{ - binary_sv2::{Seq064K, B032, U256}, + binary_sv2::{B032Owned, Seq064KOwned, U256Owned}, common_messages_sv2::*, - job_declaration_sv2::{ProvideMissingTransactionsSuccess, PushSolution, *}, + job_declaration_sv2::*, mining_sv2::*, - parsers_sv2::{self, AnyMessage, JobDeclaration, Mining}, + parsers_sv2::{self}, template_distribution_sv2::*, }; @@ -204,9 +205,10 @@ async fn jds_reject_setup_connection_with_non_job_declaration_protocol() { let setup_connection_error = sniffer.next_message_from_upstream(); let setup_connection_error = match setup_connection_error { - Some((_, AnyMessage::Common(parsers_sv2::CommonMessages::SetupConnectionError(msg)))) => { - msg - } + Some(( + _, + AnyMessageOwned::Common(parsers_sv2::CommonMessagesOwned::SetupConnectionError(msg)), + )) => msg, msg => panic!("Expected SetupConnectionError message, found: {:?}", msg), }; assert_eq!( @@ -245,9 +247,10 @@ async fn jds_reject_setup_connection_without_declare_tx_data_flag() { let setup_connection_error = sniffer.next_message_from_upstream(); let setup_connection_error = match setup_connection_error { - Some((_, AnyMessage::Common(parsers_sv2::CommonMessages::SetupConnectionError(msg)))) => { - msg - } + Some(( + _, + AnyMessageOwned::Common(parsers_sv2::CommonMessagesOwned::SetupConnectionError(msg)), + )) => msg, msg => panic!("Expected SetupConnectionError message, found: {:?}", msg), }; assert_eq!( @@ -287,9 +290,10 @@ async fn jdc_coinbase_only_mode_rejected_by_jds() { let setup_connection_error = sniffer.next_message_from_upstream(); let setup_connection_error = match setup_connection_error { - Some((_, AnyMessage::Common(parsers_sv2::CommonMessages::SetupConnectionError(msg)))) => { - msg - } + Some(( + _, + AnyMessageOwned::Common(parsers_sv2::CommonMessagesOwned::SetupConnectionError(msg)), + )) => msg, msg => panic!("Expected SetupConnectionError message, found: {:?}", msg), }; assert_eq!( @@ -332,14 +336,14 @@ async fn jds_reject_declare_mining_job_with_invalid_mining_job_token() { // Deliberately send a malformed token (1 byte instead of 8-byte JdToken) to exercise // the decode/parse failure branch before allocation ownership checks. - let malformed_token_declare = AnyMessage::JobDeclaration( - parsers_sv2::JobDeclaration::DeclareMiningJob(DeclareMiningJob { + let malformed_token_declare = AnyMessageOwned::JobDeclaration( + parsers_sv2::JobDeclarationOwned::DeclareMiningJob(DeclareMiningJobOwned { request_id: 10, mining_job_token: vec![0x01].try_into().unwrap(), version: 0, coinbase_tx_prefix: Vec::::new().try_into().unwrap(), coinbase_tx_suffix: Vec::::new().try_into().unwrap(), - wtxid_list: Seq064K::new(Vec::new()).unwrap(), + wtxid_list: Seq064KOwned::new(Vec::new()).unwrap(), excess_data: Vec::::new().try_into().unwrap(), }), ); @@ -364,7 +368,9 @@ async fn jds_reject_declare_mining_job_with_invalid_mining_job_token() { let malformed_token_error = match malformed_token_error { Some(( _, - AnyMessage::JobDeclaration(parsers_sv2::JobDeclaration::DeclareMiningJobError(msg)), + AnyMessageOwned::JobDeclaration( + parsers_sv2::JobDeclarationOwned::DeclareMiningJobError(msg), + ), )) => msg, msg => panic!("Expected DeclareMiningJobError message, found: {:?}", msg), }; @@ -380,14 +386,14 @@ async fn jds_reject_declare_mining_job_with_invalid_mining_job_token() { // Send a well-formed but never-allocated token to exercise the ownership/allocation // validation branch (distinct from malformed token parsing). - let unallocated_token_declare = AnyMessage::JobDeclaration( - parsers_sv2::JobDeclaration::DeclareMiningJob(DeclareMiningJob { + let unallocated_token_declare = AnyMessageOwned::JobDeclaration( + parsers_sv2::JobDeclarationOwned::DeclareMiningJob(DeclareMiningJobOwned { request_id: 11, mining_job_token: 42_u64.to_le_bytes().try_into().unwrap(), version: 0, coinbase_tx_prefix: Vec::::new().try_into().unwrap(), coinbase_tx_suffix: Vec::::new().try_into().unwrap(), - wtxid_list: Seq064K::new(Vec::new()).unwrap(), + wtxid_list: Seq064KOwned::new(Vec::new()).unwrap(), excess_data: Vec::::new().try_into().unwrap(), }), ); @@ -410,7 +416,9 @@ async fn jds_reject_declare_mining_job_with_invalid_mining_job_token() { let unallocated_token_error = match unallocated_token_error { Some(( _, - AnyMessage::JobDeclaration(parsers_sv2::JobDeclaration::DeclareMiningJobError(msg)), + AnyMessageOwned::JobDeclaration( + parsers_sv2::JobDeclarationOwned::DeclareMiningJobError(msg), + ), )) => msg, msg => panic!("Expected DeclareMiningJobError message, found: {:?}", msg), }; @@ -457,7 +465,7 @@ async fn pool_rejects_reused_set_custom_mining_job_token() { let first_set_custom_mining_job = loop { match jdc_pool_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(Mining::SetCustomMiningJob(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJob(msg)))) => break msg, _ => continue, } }; @@ -493,7 +501,7 @@ async fn pool_rejects_reused_set_custom_mining_job_token() { ) .await; - let replayed_set_custom_mining_job = AnyMessage::Mining(Mining::SetCustomMiningJob( + let replayed_set_custom_mining_job = AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJob( first_set_custom_mining_job.clone(), )); send_to_pool @@ -510,7 +518,9 @@ async fn pool_rejects_reused_set_custom_mining_job_token() { let set_custom_mining_job_error = loop { match mock_pool_sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::SetCustomMiningJobError(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJobError(msg)))) => { + break msg + } _ => continue, } }; @@ -540,11 +550,11 @@ async fn jds_receive_solution_while_processing_declared_job_test() { let (pool, pool_addr, jds_addr, _) = start_pool_with_jds(tp_1.bitcoin_core(), vec![], vec![], false).await; - let prev_hash = U256::from([ + let prev_hash = U256Owned::from([ 184, 103, 138, 88, 153, 105, 236, 29, 123, 246, 107, 203, 1, 33, 10, 122, 188, 139, 218, 141, 62, 177, 158, 101, 125, 92, 214, 150, 199, 220, 29, 8, ]); - let extranonce = B032::try_from([ + let extranonce = B032Owned::try_from([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, ]) @@ -552,14 +562,16 @@ async fn jds_receive_solution_while_processing_declared_job_test() { let submit_solution_replace = ReplaceMessage::new( MessageDirection::ToUpstream, MESSAGE_TYPE_PROVIDE_MISSING_TRANSACTIONS_SUCCESS, - AnyMessage::JobDeclaration(parsers_sv2::JobDeclaration::PushSolution(PushSolution { - ntime: 0, - nbits: 0, - nonce: 0, - version: 0, - prev_hash, - extranonce, - })), + AnyMessageOwned::JobDeclaration(parsers_sv2::JobDeclarationOwned::PushSolution( + PushSolutionOwned { + ntime: 0, + nbits: 0, + nonce: 0, + version: 0, + prev_hash, + extranonce, + }, + )), ); // This sniffer sits between `jds` and `jdc`, replacing `ProvideMissingTransactionSuccess` @@ -645,11 +657,11 @@ async fn jds_wont_exit_upon_receiving_unexpected_txids_in_provide_missing_transa let provide_missing_transaction_success_replace = ReplaceMessage::new( MessageDirection::ToUpstream, MESSAGE_TYPE_PROVIDE_MISSING_TRANSACTIONS_SUCCESS, - AnyMessage::JobDeclaration( - parsers_sv2::JobDeclaration::ProvideMissingTransactionsSuccess( - ProvideMissingTransactionsSuccess { + AnyMessageOwned::JobDeclaration( + parsers_sv2::JobDeclarationOwned::ProvideMissingTransactionsSuccess( + ProvideMissingTransactionsSuccessOwned { request_id: 1, - transaction_list: Seq064K::new(Vec::new()).unwrap(), + transaction_list: Seq064KOwned::new(Vec::new()).unwrap(), }, ), ), @@ -760,15 +772,15 @@ async fn jdc_group_extended_channels() { const EXPECTED_GROUP_CHANNEL_ID: u32 = 1; for i in 0..NUM_EXTENDED_CHANNELS { - let open_extended_mining_channel = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannel(OpenExtendedMiningChannelOwned { request_id: i, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: [0xff; 32].into(), min_extranonce_size: 0, - }, - )); + }), + ); send_to_jdc .send(open_extended_mining_channel) .await @@ -785,7 +797,10 @@ async fn jdc_group_extended_channels() { // if we get any other message (e.g.: NewExtendedMiningJob), just continue the loop let (channel_id, group_channel_id) = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenExtendedMiningChannelSuccess(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannelSuccess(msg)), + )) => { break (msg.channel_id, msg.group_channel_id); } _ => continue, @@ -835,7 +850,7 @@ async fn jdc_group_extended_channels() { // assert that the NewExtendedMiningJob message is directed to the correct group channel ID let new_extended_mining_job_msg = sniffer.next_message_from_upstream(); let new_extended_mining_job_msg = match new_extended_mining_job_msg { - Some((_, AnyMessage::Mining(Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::NewExtendedMiningJob(msg)))) => msg, msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; @@ -880,7 +895,7 @@ async fn jdc_group_extended_channels() { let set_new_prev_hash_msg = sniffer.next_message_from_upstream(); let set_new_prev_hash_msg = match set_new_prev_hash_msg { - Some((_, AnyMessage::Mining(Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetNewPrevHash(msg)))) => msg, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; @@ -945,14 +960,14 @@ async fn jdc_group_standard_channels() { const EXPECTED_GROUP_CHANNEL_ID: u32 = 1; for i in 0..NUM_STANDARD_CHANNELS { - let open_standard_mining_channel = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenStandardMiningChannel(OpenStandardMiningChannelOwned { request_id: i, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), - }, - )); + }), + ); send_to_jdc .send(open_standard_mining_channel) @@ -970,7 +985,10 @@ async fn jdc_group_standard_channels() { // if we get any other message (e.g.: NewExtendedMiningJob), just continue the loop let (channel_id, group_channel_id) = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenStandardMiningChannelSuccess(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannelSuccess(msg)), + )) => { break (msg.channel_id, msg.group_channel_id); } _ => continue, @@ -1017,7 +1035,7 @@ async fn jdc_group_standard_channels() { // assert that the NewExtendedMiningJob message is directed to the correct group channel ID let new_extended_mining_job_msg = sniffer.next_message_from_upstream(); let new_extended_mining_job_msg = match new_extended_mining_job_msg { - Some((_, AnyMessage::Mining(Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::NewExtendedMiningJob(msg)))) => msg, msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; @@ -1074,7 +1092,7 @@ async fn jdc_group_standard_channels() { let set_new_prev_hash_msg = sniffer.next_message_from_upstream(); let set_new_prev_hash_msg = match set_new_prev_hash_msg { - Some((_, AnyMessage::Mining(Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetNewPrevHash(msg)))) => msg, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; @@ -1139,14 +1157,14 @@ async fn jdc_require_standard_jobs_set_does_not_group_standard_channels() { const EXPECTED_GROUP_CHANNEL_ID: u32 = 1; for i in 0..NUM_STANDARD_CHANNELS { - let open_standard_mining_channel = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenStandardMiningChannel(OpenStandardMiningChannelOwned { request_id: i, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), - }, - )); + }), + ); send_to_jdc .send(open_standard_mining_channel) @@ -1164,7 +1182,10 @@ async fn jdc_require_standard_jobs_set_does_not_group_standard_channels() { // if we get any other message (e.g.: NewExtendedMiningJob), just continue the loop let (channel_id, group_channel_id) = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenStandardMiningChannelSuccess(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannelSuccess(msg)), + )) => { break (msg.channel_id, msg.group_channel_id); } _ => continue, @@ -1207,7 +1228,7 @@ async fn jdc_require_standard_jobs_set_does_not_group_standard_channels() { let channel_id = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::NewMiningJob(msg)))) => { + Some((_, AnyMessageOwned::Mining(MiningOwned::NewMiningJob(msg)))) => { break msg.channel_id; } _ => continue, @@ -1232,7 +1253,7 @@ async fn jdc_require_standard_jobs_set_does_not_group_standard_channels() { let channel_id = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::NewMiningJob(msg)))) => { + Some((_, AnyMessageOwned::Mining(MiningOwned::NewMiningJob(msg)))) => { break msg.channel_id; } _ => continue, @@ -1255,7 +1276,7 @@ async fn jdc_require_standard_jobs_set_does_not_group_standard_channels() { let channel_id = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::SetNewPrevHash(msg)))) => { + Some((_, AnyMessageOwned::Mining(MiningOwned::SetNewPrevHash(msg)))) => { break msg.channel_id; } _ => continue, @@ -1308,15 +1329,15 @@ async fn jdc_require_standard_jobs_set_rejects_open_extended_mining_channel() { ) .await; - let open_extended_mining_channel = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannel(OpenExtendedMiningChannelOwned { request_id: 100u32, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), min_extranonce_size: 8, - }, - )); + }), + ); send_to_jdc .send(open_extended_mining_channel) .await @@ -1331,7 +1352,9 @@ async fn jdc_require_standard_jobs_set_rejects_open_extended_mining_channel() { let error = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenMiningChannelError(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::OpenMiningChannelError(msg)))) => { + break msg + } _ => continue, } }; @@ -1405,9 +1428,10 @@ async fn jdc_per_upstream_identity_switches_on_fallback() { let allocate_msg = loop { match fallback_jds_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::JobDeclaration(JobDeclaration::AllocateMiningJobToken(msg)))) => { - break msg - } + Some(( + _, + AnyMessageOwned::JobDeclaration(JobDeclarationOwned::AllocateMiningJobToken(msg)), + )) => break msg, _ => continue, } }; diff --git a/integration-tests/tests/jd_tproxy_integration.rs b/integration-tests/tests/jd_tproxy_integration.rs index d35ef0360..4c5dabb25 100644 --- a/integration-tests/tests/jd_tproxy_integration.rs +++ b/integration-tests/tests/jd_tproxy_integration.rs @@ -9,7 +9,7 @@ use integration_tests_sv2::{ use stratum_apps::stratum_core::{ common_messages_sv2::*, mining_sv2::*, - parsers_sv2::{AnyMessage, CommonMessages, Mining}, + parsers_sv2::{AnyMessageOwned, CommonMessagesOwned, MiningOwned}, }; #[tokio::test] @@ -231,12 +231,12 @@ async fn jdc_sends_per_upstream_identity() { // Respond with success so JDC proceeds to connect to JDS and open channels. pool_sender - .send(AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + .send(AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - ))) + }), + )) .await .unwrap(); @@ -253,7 +253,9 @@ async fn jdc_sends_per_upstream_identity() { let oemc = loop { match pool_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(Mining::OpenExtendedMiningChannel(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel(msg)))) => { + break msg + } _ => continue, } }; diff --git a/integration-tests/tests/jdc_cached_shares.rs b/integration-tests/tests/jdc_cached_shares.rs index df703d7fb..166eba645 100644 --- a/integration-tests/tests/jdc_cached_shares.rs +++ b/integration-tests/tests/jdc_cached_shares.rs @@ -9,7 +9,7 @@ use std::time::Duration; use stratum_apps::stratum_core::{ common_messages_sv2::Protocol, mining_sv2::*, - parsers_sv2::{AnyMessage, Mining}, + parsers_sv2::{AnyMessageOwned, MiningOwned}, }; // Verifies that the JD client buffers `SubmitSharesExtended` while waiting for @@ -55,7 +55,9 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { let open_channel_msg = loop { match pool_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(Mining::OpenExtendedMiningChannel(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel(msg)))) => { + break msg + } _ => { tokio::time::sleep(Duration::from_secs(1)).await; } @@ -63,8 +65,8 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { }; let channel_id = 9u32; - let open_channel_success = AnyMessage::Mining(Mining::OpenExtendedMiningChannelSuccess( - OpenExtendedMiningChannelSuccess { + let open_channel_success = AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannelSuccess(OpenExtendedMiningChannelSuccessOwned { request_id: open_channel_msg.request_id, channel_id, // Set the target to the maximum value (lowest difficulty) @@ -74,13 +76,13 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { extranonce_size: open_channel_msg.min_extranonce_size, extranonce_prefix: vec![0x00, 0x00, 0x00, 0x00].try_into().unwrap(), group_channel_id: 1, - }, - )); + }), + ); mock_pool_sender.send(open_channel_success).await.unwrap(); let set_custom_mining_job = loop { match pool_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(Mining::SetCustomMiningJob(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJob(msg)))) => break msg, _ => { tokio::time::sleep(Duration::from_secs(1)).await; } @@ -93,8 +95,8 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { let job_id = 99; - let set_custom_job_success = AnyMessage::Mining(Mining::SetCustomMiningJobSuccess( - SetCustomMiningJobSuccess { + let set_custom_job_success = AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJobSuccess( + SetCustomMiningJobSuccessOwned { channel_id: set_custom_mining_job.channel_id, request_id: set_custom_mining_job.request_id, job_id, @@ -104,7 +106,9 @@ async fn jdc_cached_shares_relayed_on_set_custom_job_success() { let submit_share_extended = loop { match pool_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(Mining::SubmitSharesExtended(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SubmitSharesExtended(msg)))) => { + break msg + } _ => { tokio::time::sleep(Duration::from_secs(1)).await; } diff --git a/integration-tests/tests/jds_downstream_state_isolation.rs b/integration-tests/tests/jds_downstream_state_isolation.rs index 04266bb55..cdcb90a17 100644 --- a/integration-tests/tests/jds_downstream_state_isolation.rs +++ b/integration-tests/tests/jds_downstream_state_isolation.rs @@ -9,7 +9,7 @@ use stratum_apps::stratum_core::{ common_messages_sv2::Protocol, job_declaration_sv2::*, mining_sv2::*, - parsers_sv2::{AnyMessage, JobDeclaration, Mining}, + parsers_sv2::{AnyMessageOwned, JobDeclarationOwned, MiningOwned}, }; #[tokio::test] @@ -76,27 +76,27 @@ async fn jds_isolates_state_for_colliding_request_ids_across_downstreams() { // Trigger both JDCs to start job declaration for their mining channel. send_to_jdc1 - .send(AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + .send(AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannel(OpenExtendedMiningChannelOwned { request_id: 1, - user_identity: b"user_identity".to_vec().try_into().unwrap(), + user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, - max_target: vec![0xff; 32].try_into().unwrap(), + max_target: [0xff; 32].into(), min_extranonce_size: 0, - }, - ))) + }), + )) .await .unwrap(); send_to_jdc2 - .send(AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + .send(AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannel(OpenExtendedMiningChannelOwned { request_id: 1, - user_identity: b"user_identity".to_vec().try_into().unwrap(), + user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), min_extranonce_size: 0, - }, - ))) + }), + )) .await .unwrap(); @@ -146,8 +146,10 @@ async fn jds_isolates_state_for_colliding_request_ids_across_downstreams() { // Returns the first DeclareMiningJob request_id observed from a given sniffer. fn next_declare_mining_job_request_id(sniffer: &Sniffer<'_>) -> u32 { loop { - if let Some((_, AnyMessage::JobDeclaration(JobDeclaration::DeclareMiningJob(msg)))) = - sniffer.next_message_from_downstream() + if let Some(( + _, + AnyMessageOwned::JobDeclaration(JobDeclarationOwned::DeclareMiningJob(msg)), + )) = sniffer.next_message_from_downstream() { return msg.request_id; } @@ -157,7 +159,7 @@ fn next_declare_mining_job_request_id(sniffer: &Sniffer<'_>) -> u32 { // Scans captured downstream responses and ensures no SetCustomMiningJobError is emitted. fn assert_no_set_custom_mining_job_error(sniffer: &Sniffer<'_>) { while let Some((_, message)) = sniffer.next_message_from_upstream() { - if let AnyMessage::Mining(Mining::SetCustomMiningJobError(msg)) = message { + if let AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJobError(msg)) = message { panic!( "unexpected SetCustomMiningJobError while validating colliding request_id flow: {}", msg.error_code.as_utf8_or_hex() diff --git a/integration-tests/tests/pool_integration.rs b/integration-tests/tests/pool_integration.rs index 7574c665d..06401d029 100644 --- a/integration-tests/tests/pool_integration.rs +++ b/integration-tests/tests/pool_integration.rs @@ -1,3 +1,6 @@ +use stratum_apps::stratum_core::parsers_sv2::{ + AnyMessageOwned, CommonMessagesOwned, MiningOwned, TemplateDistributionOwned, +}; // This file contains integration tests for the `PoolSv2` module. // // `PoolSv2` is a module that implements the Pool role in the Stratum V2 protocol. @@ -8,10 +11,10 @@ use integration_tests_sv2::{ *, }; use stratum_apps::stratum_core::{ - binary_sv2::Seq0255, - common_messages_sv2::{has_work_selection, Protocol, SetupConnection, *}, + binary_sv2::Seq0255Owned, + common_messages_sv2::{has_work_selection, Protocol, *}, mining_sv2::*, - parsers_sv2::{self, AnyMessage, CommonMessages, Mining, TemplateDistribution}, + parsers_sv2::{self}, template_distribution_sv2::*, }; @@ -148,9 +151,10 @@ async fn header_timestamp_value_assertion_in_new_extended_mining_job() { assert_tp_message!(&tp_pool_sniffer.next_message_from_upstream(), NewTemplate); // Extract header timestamp from SetNewPrevHash message let header_timestamp_to_check = match tp_pool_sniffer.next_message_from_upstream() { - Some((_, AnyMessage::TemplateDistribution(TemplateDistribution::SetNewPrevHash(msg)))) => { - msg.header_timestamp - } + Some(( + _, + AnyMessageOwned::TemplateDistribution(TemplateDistributionOwned::SetNewPrevHash(msg)), + )) => msg.header_timestamp, _ => panic!("SetNewPrevHash not found!"), }; pool_translator_sniffer @@ -172,7 +176,7 @@ async fn header_timestamp_value_assertion_in_new_extended_mining_job() { .await; // Extract min_ntime from the second NewExtendedMiningJob message let second_job_ntime = match pool_translator_sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::NewExtendedMiningJob(job)))) => { + Some((_, AnyMessageOwned::Mining(MiningOwned::NewExtendedMiningJob(job)))) => { job.min_ntime.into_inner() } _ => panic!("Second NewExtendedMiningJob not found!"), @@ -302,7 +306,7 @@ async fn pool_does_not_send_jobs_to_jdc() { // Verify SetupConnection has work_selection flag set (JDC requires custom work) let setup_msg = pool_jdc_sniffer.next_message_from_downstream(); match setup_msg { - Some((_, AnyMessage::Common(CommonMessages::SetupConnection(msg)))) => { + Some((_, AnyMessageOwned::Common(CommonMessagesOwned::SetupConnection(msg)))) => { assert!( has_work_selection(msg.flags), "JDC should set work_selection flag in SetupConnection" @@ -394,8 +398,8 @@ async fn pool_reject_setup_connection_with_non_mining_protocol() { let setup_connection_replace = ReplaceMessage::new( MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION, - AnyMessage::Common(parsers_sv2::CommonMessages::SetupConnection( - SetupConnection { + AnyMessageOwned::Common(parsers_sv2::CommonMessagesOwned::SetupConnection( + SetupConnectionOwned { protocol: Protocol::TemplateDistributionProtocol, min_version: 2, max_version: 2, @@ -439,7 +443,7 @@ async fn pool_reject_setup_connection_with_non_mining_protocol() { .await; let setup_connection_error = pool_translator_sniffer.next_message_from_upstream(); let setup_connection_error = match setup_connection_error { - Some((_, AnyMessage::Common(CommonMessages::SetupConnectionError(msg)))) => msg, + Some((_, AnyMessageOwned::Common(CommonMessagesOwned::SetupConnectionError(msg)))) => msg, msg => panic!("Expected SetupConnectionError message, found: {:?}", msg), }; assert_eq!( @@ -482,7 +486,7 @@ async fn pool_without_jds_rejects_set_custom_mining_job() { .await; let set_custom_mining_job = - AnyMessage::Mining(Mining::SetCustomMiningJob(SetCustomMiningJob { + AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJob(SetCustomMiningJobOwned { channel_id: 1, request_id: 7, token: 42_u64.to_le_bytes().try_into().unwrap(), @@ -495,7 +499,7 @@ async fn pool_without_jds_rejects_set_custom_mining_job() { coinbase_tx_input_n_sequence: 0, coinbase_tx_outputs: Vec::::new().try_into().unwrap(), coinbase_tx_locktime: 0, - merkle_path: Seq0255::new(Vec::new()).unwrap(), + merkle_path: Seq0255Owned::new(Vec::new()).unwrap(), })); send_to_pool.send(set_custom_mining_job).await.unwrap(); @@ -508,7 +512,9 @@ async fn pool_without_jds_rejects_set_custom_mining_job() { let set_custom_mining_job_error = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::SetCustomMiningJobError(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetCustomMiningJobError(msg)))) => { + break msg + } _ => continue, } }; @@ -553,15 +559,15 @@ async fn pool_group_extended_channels() { for i in 0..NUM_EXTENDED_CHANNELS { // send OpenExtendedMiningChannel message to the pool - let open_extended_mining_channel = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannel(OpenExtendedMiningChannelOwned { request_id: i, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: [0xff; 32].into(), min_extranonce_size: 0, - }, - )); + }), + ); send_to_pool .send(open_extended_mining_channel) .await @@ -576,7 +582,10 @@ async fn pool_group_extended_channels() { let group_channel_id = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenExtendedMiningChannelSuccess(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannelSuccess(msg)), + )) => { break msg.group_channel_id; } _ => continue, @@ -621,7 +630,7 @@ async fn pool_group_extended_channels() { // assert that the NewExtendedMiningJob message is directed to the correct group channel ID let new_extended_mining_job_msg = sniffer.next_message_from_upstream(); let new_extended_mining_job_msg = match new_extended_mining_job_msg { - Some((_, AnyMessage::Mining(Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::NewExtendedMiningJob(msg)))) => msg, msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; @@ -665,7 +674,7 @@ async fn pool_group_extended_channels() { let set_new_prev_hash_msg = sniffer.next_message_from_upstream(); let set_new_prev_hash_msg = match set_new_prev_hash_msg { - Some((_, AnyMessage::Mining(Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetNewPrevHash(msg)))) => msg, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; @@ -720,14 +729,14 @@ async fn pool_group_standard_channels() { const EXPECTED_GROUP_CHANNEL_ID: u32 = 1; for i in 0..NUM_STANDARD_CHANNELS { - let open_standard_mining_channel = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenStandardMiningChannel(OpenStandardMiningChannelOwned { request_id: i, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), - }, - )); + }), + ); send_to_pool .send(open_standard_mining_channel) @@ -743,7 +752,10 @@ async fn pool_group_standard_channels() { let (channel_id, group_channel_id) = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenStandardMiningChannelSuccess(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannelSuccess(msg)), + )) => { break (msg.channel_id, msg.group_channel_id); } _ => continue, @@ -790,7 +802,7 @@ async fn pool_group_standard_channels() { // assert that the NewExtendedMiningJob message is directed to the correct group channel ID let new_extended_mining_job_msg = sniffer.next_message_from_upstream(); let new_extended_mining_job_msg = match new_extended_mining_job_msg { - Some((_, AnyMessage::Mining(Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::NewExtendedMiningJob(msg)))) => msg, msg => panic!("Expected NewMiningJob message, found: {:?}", msg), }; @@ -846,7 +858,7 @@ async fn pool_group_standard_channels() { let set_new_prev_hash_msg = sniffer.next_message_from_upstream(); let set_new_prev_hash_msg = match set_new_prev_hash_msg { - Some((_, AnyMessage::Mining(Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetNewPrevHash(msg)))) => msg, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; @@ -903,14 +915,14 @@ async fn pool_require_standard_jobs_set_does_not_group_standard_channels() { let mut channel_ids = Vec::new(); for i in 0..NUM_STANDARD_CHANNELS { - let open_standard_mining_channel = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenStandardMiningChannel(OpenStandardMiningChannelOwned { request_id: i, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), - }, - )); + }), + ); send_to_pool .send(open_standard_mining_channel) @@ -926,7 +938,10 @@ async fn pool_require_standard_jobs_set_does_not_group_standard_channels() { let (channel_id, group_channel_id) = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenStandardMiningChannelSuccess(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannelSuccess(msg)), + )) => { break (msg.channel_id, msg.group_channel_id); } _ => continue, @@ -971,7 +986,7 @@ async fn pool_require_standard_jobs_set_does_not_group_standard_channels() { let new_mining_job_msg = sniffer.next_message_from_upstream(); let channel_id = match new_mining_job_msg { - Some((_, AnyMessage::Mining(Mining::NewMiningJob(msg)))) => msg.channel_id, + Some((_, AnyMessageOwned::Mining(MiningOwned::NewMiningJob(msg)))) => msg.channel_id, msg => panic!("Expected NewMiningJob message, found: {:?}", msg), }; @@ -998,7 +1013,7 @@ async fn pool_require_standard_jobs_set_does_not_group_standard_channels() { let new_mining_job_msg = sniffer.next_message_from_upstream(); let channel_id = match new_mining_job_msg { - Some((_, AnyMessage::Mining(Mining::NewMiningJob(msg)))) => msg.channel_id, + Some((_, AnyMessageOwned::Mining(MiningOwned::NewMiningJob(msg)))) => msg.channel_id, msg => panic!("Expected NewMiningJob message, found: {:?}", msg), }; @@ -1018,7 +1033,7 @@ async fn pool_require_standard_jobs_set_does_not_group_standard_channels() { let set_new_prev_hash_msg = sniffer.next_message_from_upstream(); let channel_id = match set_new_prev_hash_msg { - Some((_, AnyMessage::Mining(Mining::SetNewPrevHash(msg)))) => msg.channel_id, + Some((_, AnyMessageOwned::Mining(MiningOwned::SetNewPrevHash(msg)))) => msg.channel_id, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; @@ -1063,15 +1078,15 @@ async fn pool_require_standard_jobs_set_rejects_open_extended_mining_channel() { ) .await; - let open_extended_mining_channel = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended_mining_channel = AnyMessageOwned::Mining( + MiningOwned::OpenExtendedMiningChannel(OpenExtendedMiningChannelOwned { request_id: 100u32, user_identity: "user_identity".try_into().unwrap(), nominal_hash_rate: 1000.0, max_target: vec![0xff; 32].try_into().unwrap(), min_extranonce_size: 8, - }, - )); + }), + ); send_to_pool .send(open_extended_mining_channel) .await @@ -1086,7 +1101,9 @@ async fn pool_require_standard_jobs_set_rejects_open_extended_mining_channel() { let error = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(Mining::OpenMiningChannelError(msg)))) => break msg, + Some((_, AnyMessageOwned::Mining(MiningOwned::OpenMiningChannelError(msg)))) => { + break msg + } _ => continue, } }; diff --git a/integration-tests/tests/pool_solo_mining.rs b/integration-tests/tests/pool_solo_mining.rs index 6dad84e5d..49e1a9f6c 100644 --- a/integration-tests/tests/pool_solo_mining.rs +++ b/integration-tests/tests/pool_solo_mining.rs @@ -31,14 +31,16 @@ use stratum_apps::stratum_core::{ bitcoin::{consensus::deserialize, params::TESTNET4, Address, Transaction}, common_messages_sv2::*, mining_sv2::*, - parsers_sv2::{self, AnyMessage, Mining}, + parsers_sv2::{ + AnyMessageOwned, MiningOwned, {self}, + }, }; const MINER_COINBASE_REWARD_ADDR: &str = "tb1qpusf5256yxv50qt0pm0tue8k952fsu5lzsphft"; fn build_coinbase_tx( - channel_success: &OpenExtendedMiningChannelSuccess, - new_job: &NewExtendedMiningJob, + channel_success: &OpenExtendedMiningChannelSuccessOwned, + new_job: &NewExtendedMiningJobOwned, ) -> Transaction { let prefix = new_job.coinbase_tx_prefix.as_bytes(); let suffix = new_job.coinbase_tx_suffix.as_bytes(); @@ -127,8 +129,8 @@ async fn pool_solo_mining_invalid_payout_address() { .await; // === Extended Channel - invalid payout address === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: "sri/solo/tb1qbalieiro/worker.1" .to_string() @@ -148,9 +150,12 @@ async fn pool_solo_mining_invalid_payout_address() { ) .await; - let error_ext: OpenMiningChannelError = loop { + let error_ext: OpenMiningChannelErrorOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenMiningChannelError(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenMiningChannelError(msg)), + )) => { break msg; } _ => continue, @@ -162,8 +167,8 @@ async fn pool_solo_mining_invalid_payout_address() { ); // === Standard Channel - invalid payout address === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: "sri/solo/tb1qbalieiro/worker.1" .to_string() @@ -182,9 +187,12 @@ async fn pool_solo_mining_invalid_payout_address() { ) .await; - let error_std: OpenMiningChannelError = loop { + let error_std: OpenMiningChannelErrorOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenMiningChannelError(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenMiningChannelError(msg)), + )) => { break msg; } _ => continue, @@ -219,8 +227,8 @@ async fn pool_solo_mining_wrong_user_identity() { .await; // === Extended Channel - missing keyword === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: "sri/worker.1".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -237,9 +245,12 @@ async fn pool_solo_mining_wrong_user_identity() { ) .await; - let error_ext: OpenMiningChannelError = loop { + let error_ext: OpenMiningChannelErrorOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenMiningChannelError(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenMiningChannelError(msg)), + )) => { break msg; } _ => continue, @@ -251,8 +262,8 @@ async fn pool_solo_mining_wrong_user_identity() { ); // === Standard Channel - missing keyword === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: "sri/worker.1".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -268,9 +279,12 @@ async fn pool_solo_mining_wrong_user_identity() { ) .await; - let error_std: OpenMiningChannelError = loop { + let error_std: OpenMiningChannelErrorOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenMiningChannelError(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenMiningChannelError(msg)), + )) => { break msg; } _ => continue, @@ -306,8 +320,8 @@ async fn pool_solo_mining_random_user_identity() { .await; // === Extended Channel - random user_identity, pool gets 100% === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: "cool_miner/worker.1".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -324,19 +338,24 @@ async fn pool_solo_mining_random_user_identity() { ) .await; - let channel_success_ext: OpenExtendedMiningChannelSuccess = loop { + let channel_success_ext: OpenExtendedMiningChannelSuccessOwned = loop { match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => break msg, _ => continue, } }; - let new_job_ext: NewExtendedMiningJob = loop { + let new_job_ext: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -364,9 +383,12 @@ async fn pool_solo_mining_random_user_identity() { .await; // === Wait for second job (from mempool) and verify payout === - let new_job_ext_second: NewExtendedMiningJob = loop { + let new_job_ext_second: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -401,9 +423,12 @@ async fn pool_solo_mining_random_user_identity() { .await; // === Wait for third job (from generate blocks) and verify payout === - let new_job_ext_third: NewExtendedMiningJob = loop { + let new_job_ext_third: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -428,8 +453,8 @@ async fn pool_solo_mining_random_user_identity() { ); // === Standard Channel - random user_identity === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: "cool_miner/worker.1".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -470,8 +495,8 @@ async fn pool_solo_mining_legacy_pattern() { .await; // === Extended Channel - legacy pattern, miner gets 100% === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: MINER_COINBASE_REWARD_ADDR.try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -488,19 +513,24 @@ async fn pool_solo_mining_legacy_pattern() { ) .await; - let channel_success_ext: OpenExtendedMiningChannelSuccess = loop { + let channel_success_ext: OpenExtendedMiningChannelSuccessOwned = loop { match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => break msg, _ => continue, } }; - let new_job_ext: NewExtendedMiningJob = loop { + let new_job_ext: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -528,9 +558,12 @@ async fn pool_solo_mining_legacy_pattern() { .await; // === Wait for second job (from mempool) and verify payout === - let new_job_ext_second: NewExtendedMiningJob = loop { + let new_job_ext_second: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -565,9 +598,12 @@ async fn pool_solo_mining_legacy_pattern() { .await; // === Wait for third job (from generate blocks) and verify payout === - let new_job_ext_third: NewExtendedMiningJob = loop { + let new_job_ext_third: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -592,8 +628,8 @@ async fn pool_solo_mining_legacy_pattern() { ); // === Standard Channel - legacy pattern === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: MINER_COINBASE_REWARD_ADDR.try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -634,8 +670,8 @@ async fn pool_solo_mining_solo_pattern() { .await; // === Extended Channel - sri/solo pattern, miner gets 100% === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: format!("sri/solo/{}/worker.1", MINER_COINBASE_REWARD_ADDR) .try_into() @@ -654,19 +690,24 @@ async fn pool_solo_mining_solo_pattern() { ) .await; - let channel_success_ext: OpenExtendedMiningChannelSuccess = loop { + let channel_success_ext: OpenExtendedMiningChannelSuccessOwned = loop { match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => break msg, _ => continue, } }; - let new_job_ext: NewExtendedMiningJob = loop { + let new_job_ext: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -694,9 +735,12 @@ async fn pool_solo_mining_solo_pattern() { .await; // === Wait for second job (from mempool) and verify payout === - let new_job_ext_second: NewExtendedMiningJob = loop { + let new_job_ext_second: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -731,9 +775,12 @@ async fn pool_solo_mining_solo_pattern() { .await; // === Wait for third job (from generate blocks) and verify payout === - let new_job_ext_third: NewExtendedMiningJob = loop { + let new_job_ext_third: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -758,8 +805,8 @@ async fn pool_solo_mining_solo_pattern() { ); // === Standard Channel - sri/solo pattern === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: format!("sri/solo/{}/worker.1", MINER_COINBASE_REWARD_ADDR) .try_into() @@ -802,8 +849,8 @@ async fn pool_solo_mining_full_donate() { .await; // === Extended Channel - sri/donate, pool gets 100% === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: "sri/donate/worker.1".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -820,19 +867,24 @@ async fn pool_solo_mining_full_donate() { ) .await; - let channel_success_ext: OpenExtendedMiningChannelSuccess = loop { + let channel_success_ext: OpenExtendedMiningChannelSuccessOwned = loop { match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => break msg, _ => continue, } }; - let new_job_ext: NewExtendedMiningJob = loop { + let new_job_ext: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -860,9 +912,12 @@ async fn pool_solo_mining_full_donate() { .await; // === Wait for second job (from mempool) and verify payout === - let new_job_ext_second: NewExtendedMiningJob = loop { + let new_job_ext_second: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -897,9 +952,12 @@ async fn pool_solo_mining_full_donate() { .await; // === Wait for third job (from generate blocks) and verify payout === - let new_job_ext_third: NewExtendedMiningJob = loop { + let new_job_ext_third: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -924,8 +982,8 @@ async fn pool_solo_mining_full_donate() { ); // === Standard Channel - sri/donate === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: "sri/donate/worker.1".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -966,8 +1024,8 @@ async fn pool_solo_mining_full_donate_no_worker_name() { .await; // === Extended Channel - sri/donate (no worker name), pool gets 100% === - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: "sri/donate".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -984,19 +1042,24 @@ async fn pool_solo_mining_full_donate_no_worker_name() { ) .await; - let channel_success_ext: OpenExtendedMiningChannelSuccess = loop { + let channel_success_ext: OpenExtendedMiningChannelSuccessOwned = loop { match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => break msg, _ => continue, } }; - let new_job_ext: NewExtendedMiningJob = loop { + let new_job_ext: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -1024,9 +1087,12 @@ async fn pool_solo_mining_full_donate_no_worker_name() { .await; // === Wait for second job (from mempool) and verify payout === - let new_job_ext_second: NewExtendedMiningJob = loop { + let new_job_ext_second: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -1061,9 +1127,12 @@ async fn pool_solo_mining_full_donate_no_worker_name() { .await; // === Wait for third job (from generate blocks) and verify payout === - let new_job_ext_third: NewExtendedMiningJob = loop { + let new_job_ext_third: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -1088,8 +1157,8 @@ async fn pool_solo_mining_full_donate_no_worker_name() { ); // === Standard Channel - sri/donate (no worker name) === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: "sri/donate".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -1131,8 +1200,8 @@ async fn pool_solo_mining_partial_donation() { // === Extended Channel - sri/donate/5%, pool gets 5%, miner gets 95% === let user_identity = format!("sri/donate/5/{}/worker.1", MINER_COINBASE_REWARD_ADDR); - let open_extended = AnyMessage::Mining(Mining::OpenExtendedMiningChannel( - OpenExtendedMiningChannel { + let open_extended = AnyMessageOwned::Mining(MiningOwned::OpenExtendedMiningChannel( + OpenExtendedMiningChannelOwned { request_id: 0u32, user_identity: user_identity.clone().try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -1149,19 +1218,24 @@ async fn pool_solo_mining_partial_donation() { ) .await; - let channel_success_ext: OpenExtendedMiningChannelSuccess = loop { + let channel_success_ext: OpenExtendedMiningChannelSuccessOwned = loop { match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => break msg, _ => continue, } }; - let new_job_ext: NewExtendedMiningJob = loop { + let new_job_ext: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -1197,9 +1271,12 @@ async fn pool_solo_mining_partial_donation() { .await; // === Wait for second job (from mempool) and verify payout === - let new_job_ext_second: NewExtendedMiningJob = loop { + let new_job_ext_second: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -1241,9 +1318,12 @@ async fn pool_solo_mining_partial_donation() { .await; // === Wait for third job (from generate blocks) and verify payout === - let new_job_ext_third: NewExtendedMiningJob = loop { + let new_job_ext_third: NewExtendedMiningJobOwned = loop { match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => { break msg; } _ => continue, @@ -1275,8 +1355,8 @@ async fn pool_solo_mining_partial_donation() { ); // === Standard Channel - sri/donate/5% === - let open_standard = AnyMessage::Mining(Mining::OpenStandardMiningChannel( - OpenStandardMiningChannel { + let open_standard = AnyMessageOwned::Mining(MiningOwned::OpenStandardMiningChannel( + OpenStandardMiningChannelOwned { request_id: 0u32, user_identity: user_identity.try_into().unwrap(), nominal_hash_rate: 1000.0, diff --git a/integration-tests/tests/sniffer_integration.rs b/integration-tests/tests/sniffer_integration.rs index 39ffc4b0a..855246aed 100644 --- a/integration-tests/tests/sniffer_integration.rs +++ b/integration-tests/tests/sniffer_integration.rs @@ -6,8 +6,8 @@ use integration_tests_sv2::{ }; use std::convert::TryInto; use stratum_apps::stratum_core::{ - common_messages_sv2::{Protocol, SetupConnection, SetupConnectionSuccess, *}, - parsers_sv2::{AnyMessage, CommonMessages}, + common_messages_sv2::{Protocol, SetupConnectionOwned, *}, + parsers_sv2::{AnyMessageOwned, CommonMessagesOwned}, template_distribution_sv2::*, }; @@ -20,14 +20,18 @@ async fn test_sniffer_interception() { let ignore_message = IgnoreMessage::new(MessageDirection::ToDownstream, MESSAGE_TYPE_NEW_TEMPLATE); let setup_connection_message = - AnyMessage::Common(CommonMessages::SetupConnection(SetupConnection { + AnyMessageOwned::Common(CommonMessagesOwned::SetupConnection(SetupConnectionOwned { protocol: Protocol::TemplateDistributionProtocol, min_version: 2, max_version: 2, flags: 0, - endpoint_host: "0.0.0.0".try_into().unwrap(), + endpoint_host: stratum_apps::stratum_core::binary_sv2::Str0255Owned::try_from( + "0.0.0.0", + ) + .unwrap(), endpoint_port: 8081, - vendor: "Bitmain".try_into().unwrap(), + vendor: stratum_apps::stratum_core::binary_sv2::Str0255Owned::try_from("Bitmain") + .unwrap(), hardware_version: "901".try_into().unwrap(), firmware: "abcX".try_into().unwrap(), device_id: "89567".try_into().unwrap(), @@ -37,8 +41,8 @@ async fn test_sniffer_interception() { MESSAGE_TYPE_SETUP_CONNECTION, setup_connection_message, ); - let setup_connection_error_message = AnyMessage::Common( - CommonMessages::SetupConnectionSuccess(SetupConnectionSuccess { + let setup_connection_error_message = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { flags: 0, used_version: 0, }), @@ -81,11 +85,11 @@ async fn test_sniffer_interception() { max_version, 2, endpoint_host, - "0.0.0.0".to_string().into_bytes().try_into().unwrap(), + stratum_apps::stratum_core::binary_sv2::Str0255Owned::try_from("0.0.0.0").unwrap(), endpoint_port, 8081, vendor, - "Bitmain".to_string().into_bytes().try_into().unwrap() + stratum_apps::stratum_core::binary_sv2::Str0255Owned::try_from("Bitmain").unwrap() ); sniffer_b .wait_for_message_type( diff --git a/integration-tests/tests/translator_integration.rs b/integration-tests/tests/translator_integration.rs index 7cab66f67..ed7b6b3ab 100644 --- a/integration-tests/tests/translator_integration.rs +++ b/integration-tests/tests/translator_integration.rs @@ -1,3 +1,4 @@ +use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, CommonMessagesOwned}; // This file contains integration tests for the `TranslatorSv2` module. use integration_tests_sv2::{ interceptor::{IgnoreMessage, MessageDirection, ReplaceMessage}, @@ -22,17 +23,17 @@ use std::{ time::Duration, }; use stratum_apps::stratum_core::{ - binary_sv2::{Seq0255, Sv2Option}, + binary_sv2::{Seq0255Owned, Sv2OptionOwned}, common_messages_sv2::{ - Protocol, SetupConnectionError, SetupConnectionSuccess, MESSAGE_TYPE_SETUP_CONNECTION, - MESSAGE_TYPE_SETUP_CONNECTION_ERROR, MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, + Protocol, SetupConnectionErrorOwned, SetupConnectionSuccessOwned, + MESSAGE_TYPE_SETUP_CONNECTION, MESSAGE_TYPE_SETUP_CONNECTION_ERROR, + MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, }, mining_sv2::{ - CloseChannel, OpenMiningChannelError, MESSAGE_TYPE_CLOSE_CHANNEL, - MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, + MESSAGE_TYPE_CLOSE_CHANNEL, MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS, }, - parsers_sv2::{self, AnyMessage, CommonMessages}, + parsers_sv2::{self}, sv1_api, template_distribution_sv2::MESSAGE_TYPE_SUBMIT_SOLUTION, }; @@ -206,20 +207,22 @@ async fn translator_mines_when_payout_matches_address_or_donation_identity() { MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match sniffer.next_message_from_downstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)), + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel( + msg, + )), )) => break msg, _ => continue, }; }; send_to_tproxy - .send(AnyMessage::Mining( - parsers_sv2::Mining::OpenExtendedMiningChannelSuccess( - OpenExtendedMiningChannelSuccess { + .send(AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { request_id: open_extended_mining_channel.request_id, channel_id: 0, target: hex::decode( @@ -238,14 +241,14 @@ async fn translator_mines_when_payout_matches_address_or_donation_identity() { .unwrap(); send_to_tproxy - .send(AnyMessage::Mining( - parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + .send(AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: 0, job_id: 1, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), coinbase_tx_prefix: coinbase_tx_prefix.try_into().unwrap(), coinbase_tx_suffix: coinbase_tx_suffix.try_into().unwrap(), }), @@ -260,8 +263,8 @@ async fn translator_mines_when_payout_matches_address_or_donation_identity() { .await; send_to_tproxy - .send(AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash( - SetNewPrevHash { + .send(AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::SetNewPrevHash(SetNewPrevHashOwned { channel_id: 0, job_id: 1, prev_hash: hex::decode( @@ -272,8 +275,8 @@ async fn translator_mines_when_payout_matches_address_or_donation_identity() { .unwrap(), min_ntime: 1766782170, nbits: 0x207fffff, - }, - ))) + }), + )) .await .unwrap(); sniffer @@ -359,19 +362,20 @@ async fn translator_falls_back_when_payout_does_not_match_user_identity() { MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match primary_sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => { - break msg - } + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel(msg)), + )) => break msg, _ => continue, }; }; primary_sender - .send(AnyMessage::Mining( - parsers_sv2::Mining::OpenExtendedMiningChannelSuccess( - OpenExtendedMiningChannelSuccess { + .send(AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { request_id: open_extended_mining_channel.request_id, channel_id: 0, target: hex::decode( @@ -390,13 +394,13 @@ async fn translator_falls_back_when_payout_does_not_match_user_identity() { .unwrap(); primary_sender - .send(AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + .send(AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: 0, job_id: 1, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff225200162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(), coinbase_tx_suffix: wrong_coinbase_tx_suffix.try_into().unwrap(), }))) @@ -442,8 +446,8 @@ async fn test_translator_fallback_on_setup_connection_error() { let setup_connection_success_replace = ReplaceMessage::new( MessageDirection::ToDownstream, MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS, - AnyMessage::Common(parsers_sv2::CommonMessages::SetupConnectionError( - SetupConnectionError { + AnyMessageOwned::Common(parsers_sv2::CommonMessagesOwned::SetupConnectionError( + SetupConnectionErrorOwned { flags: 0, error_code: random_error_code.try_into().unwrap(), }, @@ -526,8 +530,8 @@ async fn test_translator_fallback_on_open_mining_message_error() { let open_mining_channel_success_replace = ReplaceMessage::new( MessageDirection::ToDownstream, MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL_SUCCESS, - AnyMessage::Mining(parsers_sv2::Mining::OpenMiningChannelError( - OpenMiningChannelError { + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenMiningChannelError( + OpenMiningChannelErrorOwned { request_id: 0, error_code: random_error_code.try_into().unwrap(), }, @@ -795,7 +799,9 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { let (aggregated_channel_id, group_channel_id) = match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + msg, + )), )) => (msg.channel_id, msg.group_channel_id), msg => panic!( "Expected OpenExtendedMiningChannelSuccess message, found: {:?}", @@ -846,7 +852,7 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { .await; let share_channel_id = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => { + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)))) => { msg.channel_id } msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), @@ -881,7 +887,9 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { ) .await; let new_extended_mining_job = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)))) => { + msg + } msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; @@ -898,7 +906,10 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -922,7 +933,9 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { ) .await; let new_extended_mining_job = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)))) => { + msg + } msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; @@ -938,7 +951,7 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { ) .await; let set_new_prev_hash = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash(msg)))) => msg, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; @@ -955,7 +968,10 @@ async fn aggregated_translator_correctly_deals_with_group_channels() { ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1049,7 +1065,9 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { let open_extended_mining_channel_success = match sniffer.next_message_from_upstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(msg)), + AnyMessageOwned::Mining( + parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess(msg), + ), )) => msg, msg => panic!( "Expected OpenExtendedMiningChannelSuccess message, found: {:?}", @@ -1069,7 +1087,10 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let new_extended_mining_job = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)), + )) => msg, msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; assert_eq!(new_extended_mining_job.channel_id, channel_id); @@ -1088,7 +1109,9 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let set_new_prev_hash = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash(msg)))) => { + msg + } msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; assert_eq!(set_new_prev_hash.channel_id, channel_id); @@ -1105,7 +1128,10 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1132,7 +1158,9 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let new_extended_mining_job = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)))) => { + msg + } msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; assert_eq!( @@ -1150,7 +1178,10 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1198,7 +1229,9 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let new_extended_mining_job = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(msg)))) => { + msg + } msg => panic!("Expected NewExtendedMiningJob message, found: {:?}", msg), }; assert_eq!( @@ -1213,7 +1246,7 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let set_new_prev_hash = match sniffer.next_message_from_upstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(msg)))) => msg, + Some((_, AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash(msg)))) => msg, msg => panic!("Expected SetNewPrevHash message, found: {:?}", msg), }; assert_eq!(set_new_prev_hash.channel_id, EXPECTED_GROUP_CHANNEL_ID); @@ -1256,7 +1289,10 @@ async fn non_aggregated_translator_correctly_deals_with_group_channels() { ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1302,12 +1338,12 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { ) .await; - let setup_connection_success = AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + let setup_connection_success = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - )); + }), + ); send_to_tproxy.send(setup_connection_success).await.unwrap(); const N_EXTENDED_CHANNELS: u32 = 6; @@ -1329,11 +1365,13 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match sniffer.next_message_from_downstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)), + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel( + msg, + )), )) => { break msg; } @@ -1342,8 +1380,8 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { }; let open_extended_mining_channel_success = - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess( - OpenExtendedMiningChannelSuccess { + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { request_id: open_extended_mining_channel.request_id, channel_id: i, target: hex::decode( @@ -1370,13 +1408,13 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { ) .await; - let new_extended_mining_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + let new_extended_mining_job = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: i, job_id: 1, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), // scriptSig for a total of 8 bytes of extranonce coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff225200162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(), coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(), @@ -1390,8 +1428,8 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { ) .await; - let set_new_prev_hash = - AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash { + let set_new_prev_hash = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash( + SetNewPrevHashOwned { channel_id: i, job_id: 1, prev_hash: hex::decode( @@ -1402,7 +1440,8 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { .unwrap(), min_ntime: 1766782170, nbits: 0x207fffff, - })); + }, + )); send_to_tproxy.send(set_new_prev_hash).await.unwrap(); sniffer @@ -1424,21 +1463,22 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { .collect::>(); // send a SetGroupChannel message to set GROUP_CHANNEL_ID_B - let set_group_channel = - AnyMessage::Mining(parsers_sv2::Mining::SetGroupChannel(SetGroupChannel { + let set_group_channel = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetGroupChannel( + SetGroupChannelOwned { channel_ids: group_channel_b_ids.clone().try_into().unwrap(), group_channel_id: GROUP_CHANNEL_ID_B, - })); + }, + )); send_to_tproxy.send(set_group_channel).await.unwrap(); // send a NewExtendedMiningJob + SetNewPrevHash message pair ONLY to GROUP_CHANNEL_ID_B - let new_extended_mining_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + let new_extended_mining_job = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: GROUP_CHANNEL_ID_B, job_id: 2, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), // scriptSig for a total of 8 bytes of extranonce coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff225300162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(), coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(), @@ -1452,8 +1492,8 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { ) .await; - let set_new_prev_hash = - AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash { + let set_new_prev_hash = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash( + SetNewPrevHashOwned { channel_id: GROUP_CHANNEL_ID_B, job_id: 2, prev_hash: hex::decode( @@ -1464,7 +1504,8 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { .unwrap(), min_ntime: 1766782171, nbits: 0x207fffff, - })); + }, + )); send_to_tproxy.send(set_new_prev_hash).await.unwrap(); sniffer .wait_for_message_type_and_clean_queue( @@ -1484,7 +1525,10 @@ async fn non_aggregated_translator_handles_set_group_channel_message() { ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1532,12 +1576,12 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() ) .await; - let setup_connection_success = AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + let setup_connection_success = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - )); + }), + ); send_to_tproxy.send(setup_connection_success).await.unwrap(); const N_EXTENDED_CHANNELS: u32 = 3; @@ -1558,11 +1602,13 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match sniffer.next_message_from_downstream() { Some(( _, - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)), + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel( + msg, + )), )) => { break msg; } @@ -1571,8 +1617,8 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() }; let open_extended_mining_channel_success = - AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannelSuccess( - OpenExtendedMiningChannelSuccess { + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { request_id: open_extended_mining_channel.request_id, channel_id: i, target: hex::decode( @@ -1599,13 +1645,13 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() ) .await; - let new_extended_mining_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + let new_extended_mining_job = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: i, job_id: 1, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), // scriptSig for a total of 8 bytes of extranonce coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff225200162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(), coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(), @@ -1619,8 +1665,8 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() ) .await; - let set_new_prev_hash = - AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash { + let set_new_prev_hash = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash( + SetNewPrevHashOwned { channel_id: i, job_id: 1, prev_hash: hex::decode( @@ -1631,7 +1677,8 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() .unwrap(), min_ntime: 1766782170, nbits: 0x207fffff, - })); + }, + )); send_to_tproxy.send(set_new_prev_hash).await.unwrap(); sniffer @@ -1652,7 +1699,10 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1664,10 +1714,11 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() // let's close one of the channels const CLOSED_CHANNEL_ID: u32 = 0; - let close_channel = AnyMessage::Mining(parsers_sv2::Mining::CloseChannel(CloseChannel { - channel_id: CLOSED_CHANNEL_ID, - reason_code: "".try_into().unwrap(), - })); + let close_channel = + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::CloseChannel(CloseChannelOwned { + channel_id: CLOSED_CHANNEL_ID, + reason_code: "".try_into().unwrap(), + })); send_to_tproxy.send(close_channel).await.unwrap(); sniffer .wait_for_message_type_and_clean_queue( @@ -1695,7 +1746,10 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() ) .await; let submit_shares_extended = match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::SubmitSharesExtended(msg)))) => msg, + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SubmitSharesExtended(msg)), + )) => msg, msg => panic!("Expected SubmitSharesExtended message, found: {:?}", msg), }; @@ -1724,10 +1778,11 @@ async fn non_aggregated_translator_correctly_deals_with_close_channel_message() } // now let's send a CloseChannel for the group channel - let close_channel = AnyMessage::Mining(parsers_sv2::Mining::CloseChannel(CloseChannel { - channel_id: GROUP_CHANNEL_ID, - reason_code: "".try_into().unwrap(), - })); + let close_channel = + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::CloseChannel(CloseChannelOwned { + channel_id: GROUP_CHANNEL_ID, + reason_code: "".try_into().unwrap(), + })); send_to_tproxy.send(close_channel).await.unwrap(); sniffer .wait_for_message_type_and_clean_queue( @@ -1792,12 +1847,12 @@ async fn aggregated_translator_triggers_fallback_on_close_channel_message() { ) .await; - let setup_connection_success = AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + let setup_connection_success = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - )); + }), + ); send_to_tproxy_a .send(setup_connection_success) .await @@ -1816,29 +1871,35 @@ async fn aggregated_translator_triggers_fallback_on_close_channel_message() { MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match sniffer_a.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel(msg)), + )) => { break msg; } _ => continue, }; }; - let open_extended_mining_channel_success = AnyMessage::Mining( - parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(OpenExtendedMiningChannelSuccess { - request_id: open_extended_mining_channel.request_id, - channel_id: 0, - target: hex::decode("0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc") + let open_extended_mining_channel_success = + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { + request_id: open_extended_mining_channel.request_id, + channel_id: 0, + target: hex::decode( + "0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc", + ) .unwrap() .try_into() .unwrap(), - // full extranonce has a total of 12 bytes - extranonce_size: 8, - extranonce_prefix: vec![0x00, 0x01, 0x00, 0x00].try_into().unwrap(), - group_channel_id: 100, - }), - ); + // full extranonce has a total of 12 bytes + extranonce_size: 8, + extranonce_prefix: vec![0x00, 0x01, 0x00, 0x00].try_into().unwrap(), + group_channel_id: 100, + }, + )); send_to_tproxy_a .send(open_extended_mining_channel_success) .await @@ -1851,13 +1912,13 @@ async fn aggregated_translator_triggers_fallback_on_close_channel_message() { ) .await; - let new_extended_mining_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + let new_extended_mining_job = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: 0, job_id: 1, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), // scriptSig for a total of 8 bytes of extranonce coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff265200162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(), coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(), @@ -1874,8 +1935,8 @@ async fn aggregated_translator_triggers_fallback_on_close_channel_message() { ) .await; - let set_new_prev_hash = - AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash { + let set_new_prev_hash = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash( + SetNewPrevHashOwned { channel_id: 0, job_id: 1, prev_hash: hex::decode( @@ -1886,7 +1947,8 @@ async fn aggregated_translator_triggers_fallback_on_close_channel_message() { .unwrap(), min_ntime: 1766782170, nbits: 0x207fffff, - })); + }, + )); send_to_tproxy_a.send(set_new_prev_hash).await.unwrap(); sniffer_a @@ -1898,10 +1960,11 @@ async fn aggregated_translator_triggers_fallback_on_close_channel_message() { // up until now, we have done the usual channel initialization process // now, lets send a CloseChannel message for the channel - let close_channel = AnyMessage::Mining(parsers_sv2::Mining::CloseChannel(CloseChannel { - channel_id: 0, - reason_code: "".try_into().unwrap(), - })); + let close_channel = + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::CloseChannel(CloseChannelOwned { + channel_id: 0, + reason_code: "".try_into().unwrap(), + })); send_to_tproxy_a.send(close_channel).await.unwrap(); // this should trigger fallback @@ -1935,12 +1998,12 @@ async fn translator_does_not_shutdown_on_missing_downstream_channel() { ) .await; - let setup_connection_success = AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + let setup_connection_success = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - )); + }), + ); send_to_tproxy_a .send(setup_connection_success) .await @@ -1954,29 +2017,35 @@ async fn translator_does_not_shutdown_on_missing_downstream_channel() { MESSAGE_TYPE_OPEN_EXTENDED_MINING_CHANNEL, ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match sniffer_a.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel(msg)), + )) => { break msg; } _ => continue, }; }; - let open_extended_mining_channel_success = AnyMessage::Mining( - parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(OpenExtendedMiningChannelSuccess { - request_id: open_extended_mining_channel.request_id, - channel_id: 0, - target: hex::decode("0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc") + let open_extended_mining_channel_success = + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { + request_id: open_extended_mining_channel.request_id, + channel_id: 0, + target: hex::decode( + "0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc", + ) .unwrap() .try_into() .unwrap(), - // full extranonce has a total of 12 bytes - extranonce_size: 8, - extranonce_prefix: vec![0x00, 0x01, 0x00, 0x00].try_into().unwrap(), - group_channel_id: 100, - }), - ); + // full extranonce has a total of 12 bytes + extranonce_size: 8, + extranonce_prefix: vec![0x00, 0x01, 0x00, 0x00].try_into().unwrap(), + group_channel_id: 100, + }, + )); send_to_tproxy_a .send(open_extended_mining_channel_success) .await @@ -1989,13 +2058,13 @@ async fn translator_does_not_shutdown_on_missing_downstream_channel() { ) .await; - let new_extended_mining_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob(NewExtendedMiningJob { + let new_extended_mining_job = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob(NewExtendedMiningJobOwned { channel_id: 0, job_id: 1, - min_ntime: Sv2Option::new(None), + min_ntime: Sv2OptionOwned::new(None), version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), // scriptSig for a total of 8 bytes of extranonce coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff265200162f5374726174756d2056322053524920506f6f6c2f2f08").unwrap().try_into().unwrap(), coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(), @@ -2012,8 +2081,8 @@ async fn translator_does_not_shutdown_on_missing_downstream_channel() { ) .await; - let set_new_prev_hash = - AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash { + let set_new_prev_hash = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash( + SetNewPrevHashOwned { channel_id: 0, job_id: 1, prev_hash: hex::decode( @@ -2024,7 +2093,8 @@ async fn translator_does_not_shutdown_on_missing_downstream_channel() { .unwrap(), min_ntime: 1766782170, nbits: 0x207fffff, - })); + }, + )); send_to_tproxy_a.send(set_new_prev_hash).await.unwrap(); sniffer_a @@ -2035,7 +2105,7 @@ async fn translator_does_not_shutdown_on_missing_downstream_channel() { .await; // SetTarget message with channel id not present in downstream - let set_target = AnyMessage::Mining(parsers_sv2::Mining::SetTarget(SetTarget { + let set_target = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetTarget(SetTargetOwned { channel_id: 5, maximum_target: [0; 32].into(), })); @@ -2087,12 +2157,12 @@ async fn aggregated_translator_handles_downstream_connecting_during_future_job() ) .await; - let setup_connection_success = AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + let setup_connection_success = AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - )); + }), + ); send_to_tproxy.send(setup_connection_success).await.unwrap(); // Keep references to minerd processes and SV1 sniffers so they don't get dropped @@ -2113,9 +2183,12 @@ async fn aggregated_translator_handles_downstream_connecting_during_future_job() ) .await; - let open_extended_mining_channel: OpenExtendedMiningChannel = loop { + let open_extended_mining_channel: OpenExtendedMiningChannelOwned = loop { match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => { + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel(msg)), + )) => { break msg; } _ => continue, @@ -2123,20 +2196,23 @@ async fn aggregated_translator_handles_downstream_connecting_during_future_job() }; // Send OpenExtendedMiningChannelSuccess for the aggregated channel - let open_extended_mining_channel_success = AnyMessage::Mining( - parsers_sv2::Mining::OpenExtendedMiningChannelSuccess(OpenExtendedMiningChannelSuccess { - request_id: open_extended_mining_channel.request_id, - channel_id: 2, // aggregated channel ID - target: hex::decode("0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc") + let open_extended_mining_channel_success = + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { + request_id: open_extended_mining_channel.request_id, + channel_id: 2, // aggregated channel ID + target: hex::decode( + "0000137c578190689425e3ecf8449a1af39db0aed305d9206f45ac32fe8330fc", + ) .unwrap() .try_into() .unwrap(), - // full extranonce has a total of 12 bytes - extranonce_size: 8, - extranonce_prefix: vec![0x00, 0x01, 0x00, 0x00].try_into().unwrap(), - group_channel_id: 1, - }), - ); + // full extranonce has a total of 12 bytes + extranonce_size: 8, + extranonce_prefix: vec![0x00, 0x01, 0x00, 0x00].try_into().unwrap(), + group_channel_id: 1, + }, + )); send_to_tproxy .send(open_extended_mining_channel_success) .await @@ -2150,14 +2226,14 @@ async fn aggregated_translator_handles_downstream_connecting_during_future_job() .await; // Send a FUTURE job (min_ntime: None) - this job is not active yet! - let future_job = AnyMessage::Mining(parsers_sv2::Mining::NewExtendedMiningJob( - NewExtendedMiningJob { + let future_job = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::NewExtendedMiningJob( + NewExtendedMiningJobOwned { channel_id: 2, job_id: 1, - min_ntime: Sv2Option::new(None), // This makes it a future job! + min_ntime: Sv2OptionOwned::new(None), // This makes it a future job! version: 0x20000000, version_rolling_allowed: true, - merkle_path: Seq0255::new(vec![]).unwrap(), + merkle_path: Seq0255Owned::new(vec![]).unwrap(), coinbase_tx_prefix: hex::decode("02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff265200162f5374726174756d2056322053524920506f6f6c2f2f0c").unwrap().try_into().unwrap(), coinbase_tx_suffix: hex::decode("feffffff0200f2052a01000000160014ebe1b7dcc293ccaa0ee743a86f89df8258c208fc0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf901000000").unwrap().try_into().unwrap(), }, @@ -2188,8 +2264,8 @@ async fn aggregated_translator_handles_downstream_connecting_during_future_job() // Now send SetNewPrevHash to activate the future job // Without the fix, this would cause "Failed to set new prev hash: JobIdNotFound" // because the second downstream's channel wouldn't have the future job - let set_new_prev_hash = - AnyMessage::Mining(parsers_sv2::Mining::SetNewPrevHash(SetNewPrevHash { + let set_new_prev_hash = AnyMessageOwned::Mining(parsers_sv2::MiningOwned::SetNewPrevHash( + SetNewPrevHashOwned { channel_id: 2, job_id: 1, prev_hash: hex::decode( @@ -2200,7 +2276,8 @@ async fn aggregated_translator_handles_downstream_connecting_during_future_job() .unwrap(), min_ntime: 1766782170, nbits: 0x207fffff, - })); + }, + )); send_to_tproxy.send(set_new_prev_hash).await.unwrap(); sniffer @@ -2513,12 +2590,12 @@ async fn tproxy_sends_per_upstream_user_identity() { .await; send_to_tproxy - .send(AnyMessage::Common(CommonMessages::SetupConnectionSuccess( - SetupConnectionSuccess { + .send(AnyMessageOwned::Common( + CommonMessagesOwned::SetupConnectionSuccess(SetupConnectionSuccessOwned { used_version: 2, flags: 0, - }, - ))) + }), + )) .await .unwrap(); @@ -2533,9 +2610,10 @@ async fn tproxy_sends_per_upstream_user_identity() { let oemc = loop { match sniffer.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => { - break msg - } + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel(msg)), + )) => break msg, _ => continue, } }; @@ -2597,8 +2675,8 @@ async fn tproxy_per_upstream_user_identity_switches_on_fallback() { .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION) .await; send_to_tproxy - .send(AnyMessage::Common( - parsers_sv2::CommonMessages::SetupConnectionError(SetupConnectionError { + .send(AnyMessageOwned::Common( + parsers_sv2::CommonMessagesOwned::SetupConnectionError(SetupConnectionErrorOwned { flags: 0, error_code: "test-identity-fallback".try_into().unwrap(), }), @@ -2631,9 +2709,10 @@ async fn tproxy_per_upstream_user_identity_switches_on_fallback() { let oemc = loop { match sniffer_2.next_message_from_downstream() { - Some((_, AnyMessage::Mining(parsers_sv2::Mining::OpenExtendedMiningChannel(msg)))) => { - break msg - } + Some(( + _, + AnyMessageOwned::Mining(parsers_sv2::MiningOwned::OpenExtendedMiningChannel(msg)), + )) => break msg, _ => continue, } }; diff --git a/miner-apps/Cargo.lock b/miner-apps/Cargo.lock index b043632a8..5b771e16f 100644 --- a/miner-apps/Cargo.lock +++ b/miner-apps/Cargo.lock @@ -838,8 +838,8 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -1005,7 +1005,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", ] @@ -1135,8 +1135,8 @@ dependencies = [ [[package]] name = "channels_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -1227,8 +1227,8 @@ dependencies = [ [[package]] name = "codec_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1265,8 +1265,8 @@ dependencies = [ [[package]] name = "common_messages_sv2" -version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "9.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1475,8 +1475,8 @@ dependencies = [ [[package]] name = "derive_codec_sv2" -version = "1.1.3" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "2.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" [[package]] name = "digest" @@ -1643,8 +1643,8 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "extensions_sv2" -version = "0.2.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.3.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1711,8 +1711,8 @@ dependencies = [ [[package]] name = "framing_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1882,8 +1882,8 @@ dependencies = [ [[package]] name = "handlers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2404,8 +2404,8 @@ dependencies = [ [[package]] name = "job_declaration_sv2" -version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "10.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -2596,8 +2596,8 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" -version = "11.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "12.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -2637,7 +2637,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "1.4.2" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", "chacha20poly1305", @@ -2766,8 +2766,8 @@ dependencies = [ [[package]] name = "parsers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -3770,8 +3770,8 @@ dependencies = [ [[package]] name = "stratum-core" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -3793,8 +3793,8 @@ dependencies = [ [[package]] name = "stratum_translation" -version = "0.4.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.5.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -3840,8 +3840,8 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sv1_api" -version = "5.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "6.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -3896,8 +3896,8 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "template_distribution_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] diff --git a/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs index fb37cf530..2ebaacc3a 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs @@ -1,4 +1,15 @@ use std::sync::atomic::Ordering; +use stratum_apps::stratum_core::{ + job_declaration_sv2::PushSolutionOwned, + mining_sv2::{ + CloseChannelOwned, OpenExtendedMiningChannelOwned, OpenExtendedMiningChannelSuccessOwned, + OpenMiningChannelErrorOwned, OpenStandardMiningChannelOwned, + OpenStandardMiningChannelSuccessOwned, SetCustomMiningJobOwned, SetNewPrevHashOwned, + SetTargetOwned, SubmitSharesErrorOwned, SubmitSharesExtendedOwned, + SubmitSharesStandardOwned, SubmitSharesSuccessOwned, UpdateChannelErrorOwned, + UpdateChannelOwned, + }, +}; use stratum_apps::{ stratum_core::{ @@ -18,11 +29,13 @@ use stratum_apps::{ extensions_sv2::{ UserIdentity, EXTENSION_TYPE_WORKER_HASHRATE_TRACKING, TLV_FIELD_TYPE_USER_IDENTITY, }, - handlers_sv2::{HandleMiningMessagesFromClientAsync, SupportedChannelTypes}, - job_declaration_sv2::PushSolution, + handlers_sv2::{HandleMiningMessagesFromClientOwnedAsync, SupportedChannelTypes}, mining_sv2::*, - parsers_sv2::{AnyMessage, JobDeclaration, Mining, TemplateDistribution, Tlv, TlvField}, - template_distribution_sv2::SubmitSolution, + parsers_sv2::{ + AnyMessageOwned, JobDeclarationOwned, MiningOwned, TemplateDistributionOwned, Tlv, + TlvField, + }, + template_distribution_sv2::SubmitSolutionOwned, }, utils::types::Sv2Frame, }; @@ -50,43 +63,43 @@ use crate::{ /// - [`RouteMessageTo::Downstream`] → For messages destined to a specific downstream client, /// identified by its `u32` downstream ID. #[derive(Clone)] -pub enum RouteMessageTo<'a> { +pub enum RouteMessageTo { /// Route to the upstream (mining) channel. - Upstream(Mining<'a>), + Upstream(MiningOwned), /// Route to the job declarator subsystem. - JobDeclarator(JobDeclaration<'a>), + JobDeclarator(JobDeclarationOwned), /// Route to the template provider subsystem. - TemplateProvider(TemplateDistribution<'a>), + TemplateProvider(TemplateDistributionOwned), /// Route to a specific downstream client by ID, along with its mining message. - Downstream((usize, Mining<'a>)), + Downstream((usize, MiningOwned)), } -impl<'a> From> for RouteMessageTo<'a> { - fn from(value: Mining<'a>) -> Self { +impl From for RouteMessageTo { + fn from(value: MiningOwned) -> Self { Self::Upstream(value) } } -impl<'a> From> for RouteMessageTo<'a> { - fn from(value: JobDeclaration<'a>) -> Self { +impl From for RouteMessageTo { + fn from(value: JobDeclarationOwned) -> Self { Self::JobDeclarator(value) } } -impl<'a> From> for RouteMessageTo<'a> { - fn from(value: TemplateDistribution<'a>) -> Self { +impl From for RouteMessageTo { + fn from(value: TemplateDistributionOwned) -> Self { Self::TemplateProvider(value) } } -impl<'a> From<(usize, Mining<'a>)> for RouteMessageTo<'a> { - fn from(value: (usize, Mining<'a>)) -> Self { +impl From<(usize, MiningOwned)> for RouteMessageTo { + fn from(value: (usize, MiningOwned)) -> Self { Self::Downstream(value) } } #[cfg_attr(not(test), hotpath::measure_all)] -impl RouteMessageTo<'_> { +impl RouteMessageTo { /// Forwards the message to its corresponding destination channel. /// /// The result of this method can generally be ignored. A send failure @@ -110,27 +123,20 @@ impl RouteMessageTo<'_> { .downstream_sender .get_cloned(&downstream_id); if let Some(sender) = sender { - sender.send((message.into_static(), None)).await?; + sender.send((message, None)).await?; } else { debug!("Dropping message for downstream {downstream_id}: no longer connected"); } } RouteMessageTo::Upstream(message) => { - let message_static = message.into_static(); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message_static).try_into()?; + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message).try_into()?; channel_manager_io.upstream_sender.send(sv2_frame).await?; } RouteMessageTo::JobDeclarator(message) => { - channel_manager_io - .jd_sender - .send(message.into_static()) - .await?; + channel_manager_io.jd_sender.send(message).await?; } RouteMessageTo::TemplateProvider(message) => { - channel_manager_io - .tp_sender - .send(message.into_static()) - .await?; + channel_manager_io.tp_sender.send(message).await?; } } Ok(()) @@ -138,7 +144,7 @@ impl RouteMessageTo<'_> { } #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleMiningMessagesFromClientAsync for ChannelManager { +impl HandleMiningMessagesFromClientOwnedAsync for ChannelManager { type Error = JDCError; fn get_negotiated_extensions_with_client( @@ -176,10 +182,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_close_channel( &mut self, client_id: Option, - msg: CloseChannel<'_>, + msg: CloseChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); self.with_registered_downstream(downstream_id, |downstream| { @@ -220,10 +226,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_open_standard_mining_channel( &mut self, client_id: Option, - msg: OpenStandardMiningChannel<'_>, + msg: OpenStandardMiningChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - let request_id = msg.get_request_id_as_u32(); + let request_id = msg.request_id; let user_identity = msg.user_identity.as_utf8_or_hex(); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); @@ -233,10 +239,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let mut coinbase_outputs = deserialize_outputs(coinbase_outputs) .map_err(|_| JDCError::shutdown(JDCErrorKind::ChannelManagerHasBadCoinbaseOutputs))?; - info!(downstream_id, "Received: {}", msg); + info!(downstream_id, "Received: {:?}", msg); let build_error = |code: &str| { - Mining::OpenMiningChannelError(OpenMiningChannelError { + MiningOwned::OpenMiningChannelError(OpenMiningChannelErrorOwned { request_id, error_code: code.try_into().expect("valid error code"), }) @@ -317,7 +323,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { if let Some(mut standard_channel) = standard_channel { let extranonce_prefix_size = standard_channel.get_extranonce_prefix().len(); - let open_standard_mining_channel_success = OpenStandardMiningChannelSuccess { + let open_standard_mining_channel_success = OpenStandardMiningChannelSuccessOwned { request_id: msg.request_id, channel_id: standard_channel_id, target: standard_channel.get_target().to_le_bytes().into(), @@ -327,13 +333,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .try_into() .map_err(JDCError::shutdown)?, group_channel_id, - } - .into_static(); + }; messages.push( ( downstream_id, - Mining::OpenStandardMiningChannelSuccess( + MiningOwned::OpenStandardMiningChannelSuccess( open_standard_mining_channel_success, ), ) @@ -354,17 +359,16 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .get_future_job(future_standard_job_id) .expect("future job must exist") .get_job_message() - .clone() - .into_static(); + .clone(); messages.push( ( downstream_id, - Mining::NewMiningJob(future_standard_job_message), + MiningOwned::NewMiningJob(future_standard_job_message), ) .into(), ); - let set_new_prev_hash_mining = SetNewPrevHash { + let set_new_prev_hash_mining = SetNewPrevHashOwned { channel_id: standard_channel_id, job_id: future_standard_job_id, prev_hash: last_new_prev_hash.prev_hash.clone(), @@ -381,7 +385,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetNewPrevHash(set_new_prev_hash_mining), + MiningOwned::SetNewPrevHash(set_new_prev_hash_mining), ) .into(), ); @@ -446,22 +450,22 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_open_extended_mining_channel( &mut self, client_id: Option, - msg: OpenExtendedMiningChannel<'_>, + msg: OpenExtendedMiningChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let user_identity = msg.user_identity.as_utf8_or_hex(); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); - info!(downstream_id, "Received: {}", msg); - let request_id = msg.get_request_id_as_u32(); + info!(downstream_id, "Received: {:?}", msg); + let request_id = msg.request_id; let nominal_hash_rate = msg.nominal_hash_rate; let requested_max_target = Target::from_le_bytes(msg.max_target.to_array()); let requested_min_rollable_extranonce_size = msg.min_extranonce_size; let build_error = |code: &str| { - Mining::OpenMiningChannelError(OpenMiningChannelError { + MiningOwned::OpenMiningChannelError(OpenMiningChannelErrorOwned { request_id, error_code: code.try_into().expect("valid error code"), }) @@ -578,7 +582,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .group_channel .with(|channel| channel.get_group_channel_id()) .map_err(JDCError::shutdown)?; - let open_extended_mining_channel_success = OpenExtendedMiningChannelSuccess { + let open_extended_mining_channel_success = OpenExtendedMiningChannelSuccessOwned { request_id, channel_id: extended_channel_id, target: extended_channel.get_target().to_le_bytes().into(), @@ -590,13 +594,13 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { extranonce_size: extended_channel.get_rollable_extranonce_size(), group_channel_id, } - .into_static(); + ; let full_extranonce_size = extended_channel.get_full_extranonce_size(); messages.push( ( downstream_id, - Mining::OpenExtendedMiningChannelSuccess( + MiningOwned::OpenExtendedMiningChannelSuccess( open_extended_mining_channel_success, ), ) @@ -625,11 +629,11 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("future job must exist") .get_job_message() .clone() - .into_static(); + ; messages.push( ( downstream_id, - Mining::NewExtendedMiningJob(future_extended_job_message), + MiningOwned::NewExtendedMiningJob(future_extended_job_message), ) .into(), ); @@ -637,7 +641,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let prev_hash = last_new_prev_hash.prev_hash.clone(); let header_timestamp = last_new_prev_hash.header_timestamp; let n_bits = last_new_prev_hash.n_bits; - let set_new_prev_hash_mining = SetNewPrevHash { + let set_new_prev_hash_mining = SetNewPrevHashOwned { channel_id: extended_channel_id, job_id: future_extended_job_id, prev_hash, @@ -653,7 +657,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetNewPrevHash(set_new_prev_hash_mining), + MiningOwned::SetNewPrevHash(set_new_prev_hash_mining), ) .into(), ); @@ -713,10 +717,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_update_channel( &mut self, client_id: Option, - msg: UpdateChannel<'_>, + msg: UpdateChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let channel_id = msg.channel_id; let new_nominal_hash_rate = msg.nominal_hash_rate; let requested_maximum_target = Target::from_le_bytes(msg.maximum_target.to_array()); @@ -725,7 +729,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let build_error = |code: &str| { error!(channel_id, error_code = code, "UpdateChannelError"); - Mining::UpdateChannelError(UpdateChannelError { + MiningOwned::UpdateChannelError(UpdateChannelErrorOwned { channel_id, error_code: code.to_string().try_into().expect("valid error code"), }) @@ -757,7 +761,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetTarget(SetTarget { + MiningOwned::SetTarget(SetTargetOwned { channel_id, maximum_target: new_target.to_le_bytes().into(), }), @@ -793,7 +797,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetTarget(SetTarget { + MiningOwned::SetTarget(SetTargetOwned { channel_id, maximum_target: new_target.to_le_bytes().into(), }), @@ -844,7 +848,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { upstream_channel.set_nominal_hashrate(downstream_hashrate); info!("Sending update channel message upstream"); messages.push( - Mining::UpdateChannel(UpdateChannel { + MiningOwned::UpdateChannel(UpdateChannelOwned { channel_id: upstream_channel.get_channel_id(), nominal_hash_rate: downstream_hashrate, maximum_target: min_target.to_le_bytes().into(), @@ -881,7 +885,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_submit_shares_standard( &mut self, client_id: Option, - msg: SubmitSharesStandard, + msg: SubmitSharesStandardOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { info!("Received SubmitSharesStandard"); @@ -891,7 +895,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { client_id.expect("client_id must be present for downstream_id extraction"); let build_error = |code: &str| { - Mining::SubmitSharesError(SubmitSharesError { + MiningOwned::SubmitSharesError(SubmitSharesErrorOwned { channel_id, sequence_number: msg.sequence_number, error_code: code.try_into().expect("valid error code"), @@ -918,14 +922,14 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Ok(ShareValidationResult::Valid(share_hash)) => { let share_accounting = standard_channel.get_share_accounting(); if share_accounting.should_acknowledge() { - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting.get_last_share_sequence_number(), new_submits_accepted_count: share_accounting.get_last_batch_accepted(), new_shares_sum: share_accounting.get_last_batch_work_sum(), }; info!("SubmitSharesStandard on downstream channel: {} ✅", success); - messages.push((downstream.downstream_id, Mining::SubmitSharesSuccess(success)).into()); + messages.push((downstream.downstream_id, MiningOwned::SubmitSharesSuccess(success)).into()); } else { info!( "SubmitSharesStandard on downstream channel: valid share | channel_id: {}, sequence_number: {}, share_hash: {} ☑️", @@ -941,23 +945,23 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { is_downstream_share_valid = true; if let Some(template_id) = template_id { info!("SubmitSharesStandard: Propagating solution to the Template Provider."); - let solution = SubmitSolution { + let solution = SubmitSolutionOwned { template_id, version: msg.version, header_timestamp: msg.ntime, header_nonce: msg.nonce, coinbase_tx: coinbase.try_into().map_err(JDCError::shutdown)?, }; - messages.push(TemplateDistribution::SubmitSolution(solution).into()); + messages.push(TemplateDistributionOwned::SubmitSolution(solution).into()); } let share_accounting = standard_channel.get_share_accounting().clone(); - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting.get_last_share_sequence_number(), new_submits_accepted_count: share_accounting.get_last_batch_accepted(), new_shares_sum: share_accounting.get_last_batch_work_sum(), }; - messages.push((downstream.downstream_id, Mining::SubmitSharesSuccess(success)).into()); + messages.push((downstream.downstream_id, MiningOwned::SubmitSharesSuccess(success)).into()); } Err(err) => { let code = match err { @@ -998,7 +1002,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let upstream_extranonce_prefix = upstream_channel.get_extranonce_prefix(); let extranonce = &extranonce_prefix[upstream_extranonce_prefix.len()..]; - let mut upstream_message = SubmitSharesExtended { + let mut upstream_message = SubmitSharesExtendedOwned { channel_id: upstream_channel.get_channel_id(), job_id: 0, // set later if known extranonce: extranonce.to_vec().try_into().map_err(JDCError::shutdown)?, @@ -1031,13 +1035,13 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { "SubmitSharesStandard, forwarding it to upstream: valid share | channel_id: {}, sequence_number: {}, share_hash: {} ✅", channel_id, upstream_message.sequence_number, share_hash ); - messages.push(Mining::SubmitSharesExtended(upstream_message).into()); + messages.push(MiningOwned::SubmitSharesExtended(upstream_message).into()); } Ok(client::share_accounting::ShareValidationResult::BlockFound(share_hash)) => { upstream_message.sequence_number = self.sequence_number_factory.fetch_add(1, Ordering::Relaxed); info!("SubmitSharesStandard forwarding it to upstream: 💰 Block Found!!! 💰{share_hash}"); - let push_solution = PushSolution { + let push_solution = PushSolutionOwned { extranonce: standard_channel .get_extranonce_prefix() .to_vec() @@ -1049,8 +1053,8 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { nbits: prev_hash.n_bits, prev_hash: prev_hash.prev_hash.clone(), }; - messages.push(JobDeclaration::PushSolution(push_solution).into()); - messages.push(Mining::SubmitSharesExtended(upstream_message).into()); + messages.push(JobDeclarationOwned::PushSolution(push_solution).into()); + messages.push(MiningOwned::SubmitSharesExtended(upstream_message).into()); } Err(err) => { let code = match err { @@ -1076,7 +1080,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { "downstream_share_hash must be set when downstream share is valid", ); let entry = - SharesOrderedByDiff::new(upstream_message.into_static(), hash); + SharesOrderedByDiff::new(upstream_message, hash); self.cached_shares.with_mut_or_default(template_id, |heap| { add_share_to_cache(heap, entry); }); @@ -1106,7 +1110,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { { return Ok(vec![( downstream_id, - Mining::CloseChannel(create_close_channel_msg( + MiningOwned::CloseChannel(create_close_channel_msg( channel_id, "invalid-channel-id", )), @@ -1149,7 +1153,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_submit_shares_extended( &mut self, client_id: Option, - msg: SubmitSharesExtended<'_>, + msg: SubmitSharesExtendedOwned, tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { info!("Received SubmitSharesExtended"); @@ -1160,7 +1164,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let negotiated_extensions = self.get_negotiated_extensions_with_client(client_id); let build_error = |code: &str| { - Mining::SubmitSharesError(SubmitSharesError { + MiningOwned::SubmitSharesError(SubmitSharesErrorOwned { channel_id, sequence_number: msg.sequence_number, error_code: code.try_into().expect("valid error code"), @@ -1204,14 +1208,14 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Ok(ShareValidationResult::Valid(share_hash)) => { let share_accounting = extended_channel.get_share_accounting(); if share_accounting.should_acknowledge() { - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting.get_last_share_sequence_number(), new_submits_accepted_count: share_accounting.get_last_batch_accepted(), new_shares_sum: share_accounting.get_last_batch_work_sum(), }; info!("SubmitSharesExtended on downstream channel: {} ✅", success); - messages.push((downstream.downstream_id, Mining::SubmitSharesSuccess(success)).into()); + messages.push((downstream.downstream_id, MiningOwned::SubmitSharesSuccess(success)).into()); } else { info!( "SubmitSharesExtended on downstream channel: valid share | channel_id: {}, sequence_number: {}, share_hash: {} ☑️", @@ -1226,24 +1230,24 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { downstream_share_hash = Some(share_hash); if let Some(template_id) = template_id { info!("SubmitSharesExtended: Propagating solution to the Template Provider."); - let solution = SubmitSolution { + let solution = SubmitSolutionOwned { template_id, version: msg.version, header_timestamp: msg.ntime, header_nonce: msg.nonce, coinbase_tx: coinbase.try_into().map_err(JDCError::shutdown)?, }; - messages.push(TemplateDistribution::SubmitSolution(solution).into()); + messages.push(TemplateDistributionOwned::SubmitSolution(solution).into()); } let share_accounting = extended_channel.get_share_accounting().clone(); - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting.get_last_share_sequence_number(), new_submits_accepted_count: share_accounting.get_last_batch_accepted(), new_shares_sum: share_accounting.get_last_batch_work_sum(), }; is_downstream_share_valid = true; - messages.push((downstream.downstream_id, Mining::SubmitSharesSuccess(success)).into()); + messages.push((downstream.downstream_id, MiningOwned::SubmitSharesSuccess(success)).into()); } Err(err) => { let code = match err { @@ -1319,7 +1323,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { channel_id, upstream_message.sequence_number, share_hash ); messages.push( - Mining::SubmitSharesExtended(upstream_message.into_static()).into(), + MiningOwned::SubmitSharesExtended(upstream_message).into(), ); } Ok(client::share_accounting::ShareValidationResult::BlockFound(share_hash)) => { @@ -1330,7 +1334,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { upstream_channel.get_extranonce_prefix().to_vec(); channel_extranonce .extend_from_slice(upstream_message.extranonce.as_bytes()); - let push_solution = PushSolution { + let push_solution = PushSolutionOwned { extranonce: channel_extranonce .try_into() .map_err(JDCError::shutdown)?, @@ -1340,9 +1344,9 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { nbits: prev_hash.n_bits, prev_hash: prev_hash.prev_hash.clone(), }; - messages.push(JobDeclaration::PushSolution(push_solution).into()); + messages.push(JobDeclarationOwned::PushSolution(push_solution).into()); messages.push( - Mining::SubmitSharesExtended(upstream_message.into_static()).into(), + MiningOwned::SubmitSharesExtended(upstream_message).into(), ); } Err(err) => { @@ -1370,7 +1374,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { "downstream_share_hash must be set when downstream share is valid", ); let entry = - SharesOrderedByDiff::new(upstream_message.into_static(), hash); + SharesOrderedByDiff::new(upstream_message, hash); self.cached_shares.with_mut_or_default(template_id, |heap| { add_share_to_cache(heap, entry); }); @@ -1400,7 +1404,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { { return Ok(vec![( downstream_id, - Mining::CloseChannel(create_close_channel_msg( + MiningOwned::CloseChannel(create_close_channel_msg( channel_id, "invalid-channel-id", )), @@ -1433,10 +1437,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_set_custom_mining_job( &mut self, _client_id: Option, - msg: SetCustomMiningJob<'_>, + msg: SetCustomMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); Err(JDCError::log(JDCErrorKind::UnexpectedMessage( 0, MESSAGE_TYPE_SET_CUSTOM_MINING_JOB, diff --git a/miner-apps/jd-client/src/lib/channel_manager/extensions_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/extensions_message_handler.rs index 733c3cd16..7e34a36c5 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/extensions_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/extensions_message_handler.rs @@ -4,17 +4,19 @@ use crate::{ }; use stratum_apps::{ stratum_core::{ - binary_sv2::Seq064K, - extensions_sv2::{RequestExtensions, RequestExtensionsError, RequestExtensionsSuccess}, - handlers_sv2::HandleExtensionsFromServerAsync, - parsers_sv2::{AnyMessage, Tlv}, + binary_sv2::Seq064KOwned, + extensions_sv2::{ + RequestExtensionsErrorOwned, RequestExtensionsOwned, RequestExtensionsSuccessOwned, + }, + handlers_sv2::HandleExtensionsFromServerOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::{error, info}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleExtensionsFromServerAsync for ChannelManager { +impl HandleExtensionsFromServerOwnedAsync for ChannelManager { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -29,7 +31,7 @@ impl HandleExtensionsFromServerAsync for ChannelManager { async fn handle_request_extensions_success( &mut self, _server_id: Option, - msg: RequestExtensionsSuccess<'_>, + msg: RequestExtensionsSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let supported: Vec = msg.supported_extensions.into_inner(); @@ -69,7 +71,7 @@ impl HandleExtensionsFromServerAsync for ChannelManager { async fn handle_request_extensions_error( &mut self, _server_id: Option, - msg: RequestExtensionsError<'_>, + msg: RequestExtensionsErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let unsupported: Vec = msg.unsupported_extensions.into_inner(); @@ -131,15 +133,14 @@ impl HandleExtensionsFromServerAsync for ChannelManager { can_support ); - let new_require_extensions = RequestExtensions { + let new_require_extensions = RequestExtensionsOwned { request_id: msg.request_id + 1, - requested_extensions: Seq064K::new(can_support).unwrap(), + requested_extensions: Seq064KOwned::new(can_support).unwrap(), }; - let sv2_frame: Sv2Frame = - AnyMessage::Extensions(new_require_extensions.into_static().into()) - .try_into() - .map_err(JDCError::shutdown)?; + let sv2_frame: Sv2Frame = AnyMessageOwned::Extensions(new_require_extensions.into()) + .try_into() + .map_err(JDCError::shutdown)?; self.channel_manager_io .upstream_sender diff --git a/miner-apps/jd-client/src/lib/channel_manager/jd_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/jd_message_handler.rs index 339497297..4d7c94a03 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/jd_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/jd_message_handler.rs @@ -1,19 +1,21 @@ use stratum_apps::{ stratum_core::{ - binary_sv2::{Seq064K, B016M}, + binary_sv2::{B016MOwned, Seq064KOwned}, bitcoin::{ self, absolute::LockTime, transaction::Version, OutPoint, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Witness, }, channels_sv2::outputs::deserialize_outputs, - handlers_sv2::HandleJobDeclarationMessagesFromServerAsync, + handlers_sv2::HandleJobDeclarationMessagesFromServerOwnedAsync, job_declaration_sv2::{ - AllocateMiningJobTokenSuccess, DeclareMiningJobError, DeclareMiningJobSuccess, - ProvideMissingTransactions, ProvideMissingTransactionsSuccess, - ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, + AllocateMiningJobTokenSuccessOwned, DeclareMiningJobErrorOwned, + DeclareMiningJobSuccessOwned, ProvideMissingTransactionsOwned, + ProvideMissingTransactionsSuccessOwned, ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, }, - parsers_sv2::{AnyMessage, JobDeclaration, Mining, TemplateDistribution, Tlv}, - template_distribution_sv2::CoinbaseOutputConstraints, + parsers_sv2::{ + AnyMessageOwned, JobDeclarationOwned, MiningOwned, TemplateDistributionOwned, Tlv, + }, + template_distribution_sv2::CoinbaseOutputConstraintsOwned, }, utils::types::Sv2Frame, }; @@ -25,7 +27,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { +impl HandleJobDeclarationMessagesFromServerOwnedAsync for ChannelManager { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -49,10 +51,10 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { async fn handle_allocate_mining_job_token_success( &mut self, _server_id: Option, - msg: AllocateMiningJobTokenSuccess<'_>, + msg: AllocateMiningJobTokenSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let new_coinbase_outputs = msg.coinbase_outputs.to_owned_bytes(); let coinbase_changed = self @@ -64,7 +66,7 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { }) .map_err(JDCError::shutdown)?; self.allocate_tokens - .with(|tokens| tokens.push_back(msg.clone().into_static())) + .with(|tokens| tokens.push_back(msg.clone())) .map_err(JDCError::shutdown)?; if coinbase_changed { @@ -100,10 +102,12 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { ); let coinbase_output_constraints_message = - TemplateDistribution::CoinbaseOutputConstraints(CoinbaseOutputConstraints { - coinbase_output_max_additional_size: max_additional_size as u32, - coinbase_output_max_additional_sigops: max_additional_sigops, - }); + TemplateDistributionOwned::CoinbaseOutputConstraints( + CoinbaseOutputConstraintsOwned { + coinbase_output_max_additional_size: max_additional_size as u32, + coinbase_output_max_additional_sigops: max_additional_sigops, + }, + ); self.channel_manager_io .tp_sender @@ -133,10 +137,10 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { async fn handle_declare_mining_job_error( &mut self, _server_id: Option, - msg: DeclareMiningJobError<'_>, + msg: DeclareMiningJobErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); let error_code = msg.error_code.as_utf8_or_hex(); if error_code == ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP { @@ -170,10 +174,10 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { async fn handle_declare_mining_job_success( &mut self, _server_id: Option, - msg: DeclareMiningJobSuccess<'_>, + msg: DeclareMiningJobSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let Some(last_declare_job) = self.last_declare_job_store.get_cloned(&msg.request_id) else { error!( @@ -238,7 +242,7 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { let updated = self .last_declare_job_store .with_mut(&msg.request_id, |value| { - value.set_custom_mining_job = Some(custom_job.clone().into_static()); + value.set_custom_mining_job = Some(custom_job.clone()); }); if updated.is_none() { return Err(JDCError::log(JDCErrorKind::LastDeclareJobNotFound( @@ -249,8 +253,8 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { let channel_id = custom_job.channel_id; debug!("Sending SetCustomMiningJob to the upstream with channel_id: {channel_id}"); - let message = Mining::SetCustomMiningJob(custom_job).into_static(); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message) + let message = MiningOwned::SetCustomMiningJob(custom_job); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message) .try_into() .map_err(JDCError::shutdown)?; self.channel_manager_io @@ -274,12 +278,12 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { async fn handle_provide_missing_transactions( &mut self, _server_id: Option, - msg: ProvideMissingTransactions<'_>, + msg: ProvideMissingTransactionsOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let request_id = msg.request_id; - info!("Received: {}", msg); + info!("Received: {:?}", msg); let tx_store_entry = self.last_declare_job_store.get_cloned(&request_id); @@ -293,7 +297,7 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { ))); }; - let full_tx_list: Vec> = entry + let full_tx_list: Vec = entry .tx_list .iter() .cloned() @@ -307,7 +311,7 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { "Resolving missing transactions" ); - let missing_txns: Vec> = unknown_positions + let missing_txns: Vec = unknown_positions .iter() .filter_map(|&pos| full_tx_list.get(pos as usize).cloned()) .collect(); @@ -316,11 +320,11 @@ impl HandleJobDeclarationMessagesFromServerAsync for ChannelManager { warn!("No matching transactions found for request_id={request_id}"); } - let response = ProvideMissingTransactionsSuccess { + let response = ProvideMissingTransactionsSuccessOwned { request_id: msg.request_id, - transaction_list: Seq064K::new(missing_txns).map_err(JDCError::shutdown)?, + transaction_list: Seq064KOwned::new(missing_txns).map_err(JDCError::shutdown)?, }; - let message = JobDeclaration::ProvideMissingTransactionsSuccess(response); + let message = JobDeclarationOwned::ProvideMissingTransactionsSuccess(response); self.channel_manager_io .jd_sender diff --git a/miner-apps/jd-client/src/lib/channel_manager/mod.rs b/miner-apps/jd-client/src/lib/channel_manager/mod.rs index 3f4431ec6..8a79c28f5 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/mod.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/mod.rs @@ -6,6 +6,10 @@ use std::{ Arc, OnceLock, }, }; +use stratum_apps::stratum_core::{ + job_declaration_sv2::{AllocateMiningJobTokenOwned, AllocateMiningJobTokenSuccessOwned}, + mining_sv2::{OpenExtendedMiningChannelOwned, SetTargetOwned, UpdateChannelOwned}, +}; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ @@ -26,16 +30,16 @@ use stratum_apps::{ }, framing_sv2, handlers_sv2::{ - HandleExtensionsFromServerAsync, HandleJobDeclarationMessagesFromServerAsync, - HandleMiningMessagesFromClientAsync, HandleMiningMessagesFromServerAsync, - HandleTemplateDistributionMessagesFromServerAsync, + HandleExtensionsFromServerOwnedAsync, HandleJobDeclarationMessagesFromServerOwnedAsync, + HandleMiningMessagesFromClientOwnedAsync, HandleMiningMessagesFromServerOwnedAsync, + HandleTemplateDistributionMessagesFromServerOwnedAsync, }, - job_declaration_sv2::{ - AllocateMiningJobToken, AllocateMiningJobTokenSuccess, DeclareMiningJob, + job_declaration_sv2::DeclareMiningJobOwned, + mining_sv2::SetCustomMiningJobOwned, + parsers_sv2::{ + AnyMessageOwned, JobDeclarationOwned, MiningOwned, TemplateDistributionOwned, Tlv, }, - mining_sv2::{OpenExtendedMiningChannel, SetCustomMiningJob, SetTarget, UpdateChannel}, - parsers_sv2::{AnyMessage, JobDeclaration, Mining, TemplateDistribution, Tlv}, - template_distribution_sv2::{NewTemplate, SetNewPrevHash as SetNewPrevHashTdp}, + template_distribution_sv2::{NewTemplateOwned, SetNewPrevHashOwned as SetNewPrevHashTdp}, }, sync::{SharedLock, SharedMap}, task_manager::TaskManager, @@ -114,14 +118,14 @@ pub const SOLO_FULL_EXTRANONCE_SIZE: u8 = 20; pub struct DeclaredJob { // The original `DeclareMiningJob` message associated with this job, // if one was sent. - declare_mining_job: Option>, + declare_mining_job: Option, // The template associated with the declared job. - template: NewTemplate<'static>, + template: NewTemplateOwned, // The `SetNewPrevHashTdp` message associated with this job, if available. - prev_hash: Option>, + prev_hash: Option, // The `SetCustomMiningJob` message associated with this job, // if a custom job was created. - set_custom_mining_job: Option>, + set_custom_mining_job: Option, // The coinbase output for this job. coinbase_output: Vec, // The list of transactions included in the job’s template. @@ -158,12 +162,12 @@ pub struct DeclaredJob { pub struct ChannelManagerIo { upstream_sender: Sender, upstream_receiver: Receiver, - jd_sender: Sender>, - jd_receiver: Receiver>, - tp_sender: Sender>, - tp_receiver: Receiver>, + jd_sender: Sender, + jd_receiver: Receiver, + tp_sender: Sender, + tp_receiver: Receiver, downstream_sender: SharedMap>, - downstream_receiver: Receiver<(DownstreamId, Mining<'static>, Option>)>, + downstream_receiver: Receiver<(DownstreamId, MiningOwned, Option>)>, } impl ChannelManagerIo { @@ -206,14 +210,14 @@ pub struct ChannelManager { // submitted from the JDC to the upstream. pub sequence_number_factory: Arc, // The last future template received from the template provider. - pub last_future_template: SharedLock>>, + pub last_future_template: SharedLock>, // The last new-prevhash received from the template provider. - pub last_new_prev_hash: SharedLock>>, + pub last_new_prev_hash: SharedLock>, // FIFO buffer of allocation tokens received from the JDS. // Oldest token is consumed first to minimize risk of JDS-side expiration. - pub allocate_tokens: SharedLock>>, + pub allocate_tokens: SharedLock>, // Stores templates as they arrive, keyed by template ID. - pub template_store: SharedMap>, + pub template_store: SharedMap, // Stores the last declared job, keyed by the request ID used // when declaring the job to the JDS. pub last_declare_job_store: SharedMap, @@ -225,7 +229,7 @@ pub struct ChannelManager { // The coinbase outputs currently in use. pub coinbase_outputs: SharedLock>, // The active upstream extended channel (client-side instance), if any. - pub upstream_channel: SharedLock>>, + pub upstream_channel: SharedLock>, // Optional "pool tag" string identifying the upstream pool. pub pool_tag_string: SharedLock>, // Pending downstream open-channel requests buffered while JDC is @@ -380,11 +384,11 @@ impl ChannelManager { config: JobDeclaratorClientConfig, upstream_sender: Sender, upstream_receiver: Receiver, - jd_sender: Sender>, - jd_receiver: Receiver>, - tp_sender: Sender>, - tp_receiver: Receiver>, - downstream_receiver: Receiver<(DownstreamId, Mining<'static>, Option>)>, + jd_sender: Sender, + jd_receiver: Receiver, + tp_sender: Sender, + tp_receiver: Receiver, + downstream_receiver: Receiver<(DownstreamId, MiningOwned, Option>)>, coinbase_outputs: Vec, supported_extensions: Vec, required_extensions: Vec, @@ -461,7 +465,7 @@ impl ChannelManager { // Returns a `GroupChannel` if successful, otherwise returns `None`. // // To be called before calling Downstream::new. - fn bootstrap_group_channel(&self, channel_id: ChannelId) -> Option> { + fn bootstrap_group_channel(&self, channel_id: ChannelId) -> Option { let full_extranonce_size = match self.upstream_channel.with(|channel| { channel .as_ref() @@ -555,7 +559,7 @@ impl ChannelManager { task_manager: Arc, cancellation_token: CancellationToken, fallback_coordinator: FallbackCoordinator, - channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, + channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, supported_extensions: Vec, required_extensions: Vec, ) -> JDCResult<(), error::ChannelManager> { @@ -980,8 +984,8 @@ impl ChannelManager { .map_err(JDCError::shutdown)?; match message { - Mining::OpenExtendedMiningChannel(downstream_channel_request) => { - let downstream_msg = downstream_channel_request.clone().into_static(); + MiningOwned::OpenExtendedMiningChannel(downstream_channel_request) => { + let downstream_msg = downstream_channel_request.clone(); match self.upstream_state.get() { UpstreamState::NoChannel => { @@ -999,7 +1003,7 @@ impl ChannelManager { let mut upstream_message = downstream_channel_request; let identity = self.user_identity().to_string(); upstream_message.user_identity = - identity.try_into().map_err(JDCError::shutdown)?; + identity.as_str().try_into().map_err(JDCError::shutdown)?; upstream_message.request_id = 1; // The upstream extended channel is opened once and its // `extranonce_size` is fixed. Size its rollable region to fit: @@ -1018,8 +1022,8 @@ impl ChannelManager { ); upstream_message.min_extranonce_size = upstream_min as u16; let upstream_message = - Mining::OpenExtendedMiningChannel(upstream_message).into_static(); - let sv2_frame: Sv2Frame = AnyMessage::Mining(upstream_message) + MiningOwned::OpenExtendedMiningChannel(upstream_message); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(upstream_message) .try_into() .map_err(JDCError::shutdown)?; self.channel_manager_io @@ -1041,7 +1045,7 @@ impl ChannelManager { UpstreamState::Connected => { self.handle_mining_message_from_client( Some(downstream_id), - Mining::OpenExtendedMiningChannel(downstream_msg), + MiningOwned::OpenExtendedMiningChannel(downstream_msg), tlvs.as_deref(), ) .await?; @@ -1049,15 +1053,15 @@ impl ChannelManager { UpstreamState::SoloMining => { self.handle_mining_message_from_client( Some(downstream_id), - Mining::OpenExtendedMiningChannel(downstream_msg), + MiningOwned::OpenExtendedMiningChannel(downstream_msg), tlvs.as_deref(), ) .await?; } } } - Mining::OpenStandardMiningChannel(downstream_channel_request) => { - let downstream_msg = downstream_channel_request.clone().into_static(); + MiningOwned::OpenStandardMiningChannel(downstream_channel_request) => { + let downstream_msg = downstream_channel_request.clone(); match self.upstream_state.get() { UpstreamState::NoChannel => { @@ -1079,17 +1083,16 @@ impl ChannelManager { let upstream_min_extranonce_size = (JDC_LOCAL_PREFIX_BYTES as u16) + self.reserved_downstream_rollable_extranonce_size as u16; let identity = self.user_identity().to_string(); - let upstream_open = OpenExtendedMiningChannel { - user_identity: identity.try_into().unwrap(), + let upstream_open = OpenExtendedMiningChannelOwned { + user_identity: identity.as_str().try_into().unwrap(), request_id: 1, nominal_hash_rate: downstream_channel_request.nominal_hash_rate, max_target: downstream_channel_request.max_target, min_extranonce_size: upstream_min_extranonce_size, }; - let message = - Mining::OpenExtendedMiningChannel(upstream_open).into_static(); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message) + let message = MiningOwned::OpenExtendedMiningChannel(upstream_open); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message) .try_into() .map_err(JDCError::shutdown)?; self.channel_manager_io @@ -1109,7 +1112,7 @@ impl ChannelManager { UpstreamState::Connected => { self.handle_mining_message_from_client( Some(downstream_id), - Mining::OpenStandardMiningChannel(downstream_msg), + MiningOwned::OpenStandardMiningChannel(downstream_msg), tlvs.as_deref(), ) .await?; @@ -1117,7 +1120,7 @@ impl ChannelManager { UpstreamState::SoloMining => { self.handle_mining_message_from_client( Some(downstream_id), - Mining::OpenStandardMiningChannel(downstream_msg), + MiningOwned::OpenStandardMiningChannel(downstream_msg), tlvs.as_deref(), ) .await?; @@ -1155,12 +1158,14 @@ impl ChannelManager { ); let identifier = self.user_identity().to_string(); - let message = JobDeclaration::AllocateMiningJobToken(AllocateMiningJobToken { - user_identifier: identifier - .try_into() - .expect("Static string should always convert"), - request_id, - }); + let message = + JobDeclarationOwned::AllocateMiningJobToken(AllocateMiningJobTokenOwned { + user_identifier: identifier + .as_str() + .try_into() + .expect("Static string should always convert"), + request_id, + }); self.channel_manager_io .jd_sender @@ -1180,7 +1185,7 @@ impl ChannelManager { fn run_vardiff_on_extended_channel( downstream_id: DownstreamId, channel_id: ChannelId, - channel_state: &mut stratum_apps::stratum_core::channels_sv2::server::extended::ExtendedChannel<'static>, + channel_state: &mut stratum_apps::stratum_core::channels_sv2::server::extended::ExtendedChannel, vardiff_state: &mut VardiffState, updates: &mut Vec, ) { @@ -1209,7 +1214,7 @@ impl ChannelManager { updates.push( ( downstream_id, - Mining::SetTarget(SetTarget { + MiningOwned::SetTarget(SetTargetOwned { channel_id, maximum_target: updated_target.to_le_bytes().into(), }), @@ -1228,7 +1233,7 @@ impl ChannelManager { fn run_vardiff_on_standard_channel( downstream_id: DownstreamId, channel_id: ChannelId, - channel: &mut StandardChannel<'static>, + channel: &mut StandardChannel, vardiff_state: &mut VardiffState, updates: &mut Vec, ) { @@ -1254,7 +1259,7 @@ impl ChannelManager { updates.push( ( downstream_id, - Mining::SetTarget(SetTarget { + MiningOwned::SetTarget(SetTargetOwned { channel_id, maximum_target: updated_target.to_le_bytes().into(), }), @@ -1367,7 +1372,7 @@ impl ChannelManager { info!("Sending update channel message upstream"); messages.push( - Mining::UpdateChannel(UpdateChannel { + MiningOwned::UpdateChannel(UpdateChannelOwned { channel_id: upstream_channel.get_channel_id(), nominal_hash_rate: downstream_hashrate, maximum_target: min_target.into(), @@ -1439,7 +1444,7 @@ impl ChannelManager { self.channel_manager_io .tp_sender - .send(TemplateDistribution::CoinbaseOutputConstraints(msg)) + .send(TemplateDistributionOwned::CoinbaseOutputConstraints(msg)) .await .map_err(|e| { error!(error = ?e, "Failed to send CoinbaseOutputConstraints message to TP"); diff --git a/miner-apps/jd-client/src/lib/channel_manager/template_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/template_message_handler.rs index 2c6506fa6..751c91ea5 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/template_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/template_message_handler.rs @@ -1,14 +1,21 @@ use std::sync::atomic::Ordering; +use stratum_apps::stratum_core::{ + binary_sv2::{Seq064KOwned, U256Owned}, + job_declaration_sv2::DeclareMiningJobOwned, + parsers_sv2::{JobDeclarationOwned, MiningOwned, TemplateDistributionOwned}, + template_distribution_sv2::{ + NewTemplateOwned, RequestTransactionDataErrorOwned, RequestTransactionDataOwned, + RequestTransactionDataSuccessOwned, + }, +}; use stratum_apps::stratum_core::{ - binary_sv2::{Seq064K, U256}, bitcoin::{consensus, hashes::Hash, Amount, Transaction}, channels_sv2::{chain_tip::ChainTip, outputs::deserialize_outputs}, - handlers_sv2::HandleTemplateDistributionMessagesFromServerAsync, - job_declaration_sv2::DeclareMiningJob, - mining_sv2::SetNewPrevHash as SetNewPrevHashMp, - parsers_sv2::{JobDeclaration, Mining, TemplateDistribution, Tlv}, - template_distribution_sv2::*, + handlers_sv2::HandleTemplateDistributionMessagesFromServerOwnedAsync, + mining_sv2::SetNewPrevHashOwned as SetNewPrevHashMp, + parsers_sv2::Tlv, + template_distribution_sv2::{SetNewPrevHashOwned as SetNewPrevHashTdpOwned, *}, }; use tracing::{error, info, warn}; @@ -18,7 +25,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { +impl HandleTemplateDistributionMessagesFromServerOwnedAsync for ChannelManager { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -33,16 +40,15 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { async fn handle_new_template( &mut self, _server_id: Option, - msg: NewTemplate<'_>, + msg: NewTemplateOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); - self.template_store - .insert(msg.template_id, msg.clone().into_static()); + self.template_store.insert(msg.template_id, msg.clone()); if msg.future_template { self.last_future_template - .set(Some(msg.clone().into_static())) + .set(Some(msg.clone())) .map_err(JDCError::shutdown)?; } @@ -55,8 +61,8 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { if self.mode.is_full_template() { self.channel_manager_io .tp_sender - .send(TemplateDistribution::RequestTransactionData( - RequestTransactionData { + .send(TemplateDistributionOwned::RequestTransactionData( + RequestTransactionDataOwned { template_id: msg.template_id, }, )) @@ -109,7 +115,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .group_channel .with(|group_channel| { group_channel - .on_new_template(msg.clone().into_static(), coinbase_outputs.clone()) + .on_new_template(msg.clone(), coinbase_outputs.clone()) .map_err(|e| { tracing::error!("Error while adding template to group channel: {e:?}"); JDCError::shutdown(e) @@ -161,14 +167,14 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { request_id, DeclaredJob { declare_mining_job: None, - template: msg.clone().into_static(), + template: msg.clone(), prev_hash: Some(prevhash), - set_custom_mining_job: Some(custom_job.clone().into_static()), + set_custom_mining_job: Some(custom_job.clone()), coinbase_output: coinbase_output_bytes.clone(), tx_list: Vec::new(), }, ); - messages.push(Mining::SetCustomMiningJob(custom_job).into()); + messages.push(MiningOwned::SetCustomMiningJob(custom_job).into()); } } @@ -181,7 +187,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { messages.push( ( downstream_id, - Mining::NewExtendedMiningJob(group_channel_job.get_job_message().clone()), + MiningOwned::NewExtendedMiningJob(group_channel_job.get_job_message().clone()), ) .into(), ); @@ -207,7 +213,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { })?; } else { standard_channel - .on_new_template(msg.clone().into_static(), coinbase_outputs.clone()) + .on_new_template(msg.clone(), coinbase_outputs.clone()) .map_err(|e| { tracing::error!( "Error while adding template to standard channel: {channel_id:?} {e:?}" @@ -225,7 +231,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { messages.push( ( downstream_id, - Mining::NewMiningJob(job.get_job_message().clone()), + MiningOwned::NewMiningJob(job.get_job_message().clone()), ) .into(), ); @@ -238,7 +244,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { messages.push( ( downstream_id, - Mining::NewMiningJob(job.get_job_message().clone()), + MiningOwned::NewMiningJob(job.get_job_message().clone()), ) .into(), ); @@ -287,10 +293,10 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { async fn handle_request_tx_data_error( &mut self, _server_id: Option, - msg: RequestTransactionDataError<'_>, + msg: RequestTransactionDataErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); let error_code = msg.error_code.as_utf8_or_hex(); if matches!( @@ -306,10 +312,10 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { async fn handle_request_tx_data_success( &mut self, _server_id: Option, - msg: RequestTransactionDataSuccess<'_>, + msg: RequestTransactionDataSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let transactions_data = msg.transaction_list; let excess_data = msg.excess_data; @@ -357,14 +363,14 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .map(|raw_tx| consensus::deserialize(raw_tx).expect("invalid tx")) .collect(); - let wtxids_as_u256: Vec> = tx_list + let wtxids_as_u256: Vec = tx_list .iter() .map(|tx| { let txid = tx.compute_wtxid(); - U256::from(*txid.as_byte_array()) + U256Owned::from(*txid.as_byte_array()) }) .collect(); - let wtx_ids = Seq064K::new(wtxids_as_u256).map_err(JDCError::shutdown)?; + let wtx_ids = Seq064KOwned::new(wtxids_as_u256).map_err(JDCError::shutdown)?; let is_activated_future_template = template_message.future_template && prevhash @@ -392,7 +398,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { full_extranonce_size, ) { - let declare_job = DeclareMiningJob { + let declare_job = DeclareMiningJobOwned { request_id, mining_job_token: mining_token, version: template_message.version, @@ -400,8 +406,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { coinbase_tx_suffix: coinbase_tx_suffix.try_into().unwrap(), wtxid_list: wtx_ids, excess_data, - } - .into_static(); + }; self.last_declare_job_store.insert( request_id, @@ -435,7 +440,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { _ = self .channel_manager_io .jd_sender - .send(JobDeclaration::DeclareMiningJob(declare_job)) + .send(JobDeclarationOwned::DeclareMiningJob(declare_job)) .await; } @@ -445,10 +450,10 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { async fn handle_set_new_prev_hash( &mut self, _server_id: Option, - msg: SetNewPrevHash<'_>, + msg: SetNewPrevHashTdpOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let outputs = deserialize_outputs(self.coinbase_outputs.get().map_err(JDCError::shutdown)?) .map_err(|_| JDCError::shutdown(JDCErrorKind::ChannelManagerHasBadCoinbaseOutputs))?; @@ -479,20 +484,20 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { if let Some(Some(job)) = declare_job { self.channel_manager_io .jd_sender - .send(JobDeclaration::DeclareMiningJob(job)) + .send(JobDeclarationOwned::DeclareMiningJob(job)) .await .map_err(|_e| JDCError::fallback(JDCErrorKind::ChannelErrorSender))?; } } self.last_new_prev_hash - .set(Some(msg.clone().into_static())) + .set(Some(msg.clone())) .map_err(JDCError::shutdown)?; self.last_declare_job_store.for_each_mut(|_, declared_job| { if declared_job.template.future_template && declared_job.template.template_id == msg.template_id { - declared_job.prev_hash = Some(msg.clone().into_static()); + declared_job.prev_hash = Some(msg.clone()); declared_job.template.future_template = false; } }); @@ -522,11 +527,8 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .clone() .expect("future_template checked above"); let request_id = self.request_id_factory.fetch_add(1, Ordering::Relaxed); - let chain_tip = ChainTip::new( - msg.prev_hash.clone().into_static(), - msg.n_bits, - msg.header_timestamp, - ); + let chain_tip = + ChainTip::new(msg.prev_hash.clone(), msg.n_bits, msg.header_timestamp); let custom_job = self .job_factory @@ -550,9 +552,9 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { request_id, DeclaredJob { declare_mining_job: None, - template: template.into_static(), - prev_hash: Some(msg.clone().into_static()), - set_custom_mining_job: Some(custom_job.clone().into_static()), + template, + prev_hash: Some(msg.clone()), + set_custom_mining_job: Some(custom_job.clone()), coinbase_output: self .coinbase_outputs .get() @@ -560,7 +562,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { tx_list: vec![], }, ); - messages.push(Mining::SetCustomMiningJob(custom_job).into()); + messages.push(MiningOwned::SetCustomMiningJob(custom_job).into()); } } } @@ -571,7 +573,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .group_channel .with(|group_channel| { group_channel - .on_set_new_prev_hash(msg.clone().into_static()) + .on_set_new_prev_hash(msg.clone()) .map_err(|e| { tracing::error!( "Error while adding new prev hash to group channel: {e:?}" @@ -607,7 +609,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetNewPrevHash(SetNewPrevHashMp { + MiningOwned::SetNewPrevHash(SetNewPrevHashMp { channel_id: group_channel_id, job_id: activated_group_job_id, prev_hash: msg.prev_hash.clone(), @@ -623,7 +625,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .standard_channels .try_for_each_mut(|channel_id, standard_channel| { standard_channel - .on_set_new_prev_hash(msg.clone().into_static()) + .on_set_new_prev_hash(msg.clone()) .map_err(|e| { tracing::error!( "Error while adding new prev hash to standard channel: {channel_id:?} {e:?}" @@ -643,7 +645,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetNewPrevHash(SetNewPrevHashMp { + MiningOwned::SetNewPrevHash(SetNewPrevHashMp { channel_id, job_id: activated_standard_job_id, prev_hash: msg.prev_hash.clone(), @@ -661,7 +663,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .extended_channels .try_for_each_mut(|_, extended_channel| { extended_channel - .on_set_new_prev_hash(msg.clone().into_static()) + .on_set_new_prev_hash(msg.clone()) .map_err(|e| { tracing::error!( "Error while adding new prev hash to extended channel: {e:?}" diff --git a/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs b/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs index 4297d72f6..7df4bfd6c 100644 --- a/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs +++ b/miner-apps/jd-client/src/lib/channel_manager/upstream_message_handler.rs @@ -1,4 +1,12 @@ use std::sync::atomic::Ordering; +use stratum_apps::stratum_core::mining_sv2::{ + CloseChannelOwned, NewExtendedMiningJobOwned, NewMiningJobOwned, + OpenExtendedMiningChannelSuccessOwned, OpenMiningChannelErrorOwned, + OpenStandardMiningChannelSuccessOwned, SetCustomMiningJobErrorOwned, + SetCustomMiningJobSuccessOwned, SetExtranoncePrefixOwned, SetGroupChannelOwned, + SetNewPrevHashOwned, SetTargetOwned, SubmitSharesErrorOwned, SubmitSharesSuccessOwned, + UpdateChannelErrorOwned, +}; use stratum_apps::{ stratum_core::{ @@ -10,12 +18,12 @@ use stratum_apps::{ server::jobs::factory::JobFactory, }, handlers_sv2::{ - HandleMiningMessagesFromClientAsync, HandleMiningMessagesFromServerAsync, + HandleMiningMessagesFromClientOwnedAsync, HandleMiningMessagesFromServerOwnedAsync, SupportedChannelTypes, }, mining_sv2::*, - parsers_sv2::{AnyMessage, Mining, TemplateDistribution, Tlv}, - template_distribution_sv2::RequestTransactionData, + parsers_sv2::{AnyMessageOwned, MiningOwned, TemplateDistributionOwned, Tlv}, + template_distribution_sv2::RequestTransactionDataOwned, }, utils::types::Sv2Frame, }; @@ -31,7 +39,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleMiningMessagesFromServerAsync for ChannelManager { +impl HandleMiningMessagesFromServerOwnedAsync for ChannelManager { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -61,10 +69,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_open_standard_mining_channel_success( &mut self, _server_id: Option, - msg: OpenStandardMiningChannelSuccess<'_>, + msg: OpenStandardMiningChannelSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); info!( "⚠️ JDC can only open extended channels with the upstream server, preparing fallback." ); @@ -87,10 +95,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_open_extended_mining_channel_success( &mut self, _server_id: Option, - msg: OpenExtendedMiningChannelSuccess<'_>, + msg: OpenExtendedMiningChannelSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let coinbase_outputs = self.coinbase_outputs.get().map_err(JDCError::shutdown)?; @@ -121,8 +129,8 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { self.upstream_state.set(UpstreamState::NoChannel); let close_channel = create_close_channel_msg(msg.channel_id, "downstream not available"); - let close_channel = Mining::CloseChannel(close_channel); - let sv2_frame: Sv2Frame = AnyMessage::Mining(close_channel) + let close_channel = MiningOwned::CloseChannel(close_channel); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(close_channel) .try_into() .map_err(JDCError::shutdown)?; self.channel_manager_io @@ -154,8 +162,8 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { self.upstream_state.set(UpstreamState::NoChannel); let close_channel = create_close_channel_msg(msg.channel_id, "downstream not available"); - let close_channel = Mining::CloseChannel(close_channel); - let sv2_frame: Sv2Frame = AnyMessage::Mining(close_channel) + let close_channel = MiningOwned::CloseChannel(close_channel); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(close_channel) .try_into() .map_err(JDCError::shutdown)?; self.channel_manager_io @@ -224,9 +232,9 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { request_id, DeclaredJob { declare_mining_job: None, - template: template.into_static(), - prev_hash: Some(prevhash.into_static()), - set_custom_mining_job: Some(custom_job.clone().into_static()), + template, + prev_hash: Some(prevhash), + set_custom_mining_job: Some(custom_job.clone()), coinbase_output: self .coinbase_outputs .get() @@ -275,10 +283,11 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { if channel_state == UpstreamState::Connected { if self.mode.is_full_template() { if let Some(template) = template { - let tx_data_request = - TemplateDistribution::RequestTransactionData(RequestTransactionData { + let tx_data_request = TemplateDistributionOwned::RequestTransactionData( + RequestTransactionDataOwned { template_id: template.template_id, - }); + }, + ); self.channel_manager_io .tp_sender .send(tx_data_request) @@ -289,8 +298,8 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { if self.mode.is_coinbase_only() { if let Some(custom_job) = set_custom_job { - let set_custom_job = Mining::SetCustomMiningJob(custom_job); - let sv2_frame: Sv2Frame = AnyMessage::Mining(set_custom_job) + let set_custom_job = MiningOwned::SetCustomMiningJob(custom_job); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(set_custom_job) .try_into() .map_err(JDCError::shutdown)?; self.channel_manager_io @@ -326,10 +335,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_open_mining_channel_error( &mut self, _server_id: Option, - msg: OpenMiningChannelError<'_>, + msg: OpenMiningChannelErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); warn!("⚠️ Cannot open extended channel with the upstream server, preparing fallback."); Err(JDCError::fallback(JDCErrorKind::OpenMiningChannelError)) @@ -339,10 +348,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_update_channel_error( &mut self, _server_id: Option, - msg: UpdateChannelError<'_>, + msg: UpdateChannelErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); Ok(()) } @@ -353,10 +362,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_close_channel( &mut self, _server_id: Option, - msg: CloseChannel<'_>, + msg: CloseChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); self.upstream_channel .set(None) @@ -372,10 +381,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_extranonce_prefix( &mut self, _server_id: Option, - msg: SetExtranoncePrefix<'_>, + msg: SetExtranoncePrefixOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let mut messages_results: Vec> = vec![]; self.upstream_channel .with(|upstream_channel| -> Result<(), Self::Error> { @@ -456,10 +465,12 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { }; messages_results.push(Ok(( downstream_id, - Mining::SetExtranoncePrefix(SetExtranoncePrefix { - channel_id, - extranonce_prefix, - }), + MiningOwned::SetExtranoncePrefix( + SetExtranoncePrefixOwned { + channel_id, + extranonce_prefix, + }, + ), ) .into())); } @@ -496,10 +507,12 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { }; messages_results.push(Ok(( downstream_id, - Mining::SetExtranoncePrefix(SetExtranoncePrefix { - channel_id, - extranonce_prefix, - }), + MiningOwned::SetExtranoncePrefix( + SetExtranoncePrefixOwned { + channel_id, + extranonce_prefix, + }, + ), ) .into())); } @@ -533,10 +546,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_submit_shares_success( &mut self, _server_id: Option, - msg: SubmitSharesSuccess, + msg: SubmitSharesSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {} ✅", msg); + info!("Received: {:?} ✅", msg); self.upstream_channel .with(|upstream_channel| { @@ -556,10 +569,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_submit_shares_error( &mut self, _server_id: Option, - msg: SubmitSharesError<'_>, + msg: SubmitSharesErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {} ❌", msg); + warn!("Received: {:?} ❌", msg); let error_code = msg.error_code.as_utf8_or_hex(); self.upstream_channel @@ -577,10 +590,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_new_mining_job( &mut self, _server_id: Option, - msg: NewMiningJob<'_>, + msg: NewMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); warn!("⚠️ JDC does not expect jobs from the upstream server — ignoring."); Ok(()) } @@ -589,10 +602,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_new_extended_mining_job( &mut self, _server_id: Option, - msg: NewExtendedMiningJob<'_>, + msg: NewExtendedMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); warn!("⚠️ JDC does not expect jobs from the upstream server — ignoring."); Ok(()) } @@ -601,10 +614,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_new_prev_hash( &mut self, _server_id: Option, - msg: SetNewPrevHash<'_>, + msg: SetNewPrevHashOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); warn!("⚠️ JDC does not expect prevhash updates from the upstream server — ignoring."); Ok(()) } @@ -618,10 +631,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_custom_mining_job_success( &mut self, _server_id: Option, - msg: SetCustomMiningJobSuccess, + msg: SetCustomMiningJobSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {} ✅", msg); + info!("Received: {:?} ✅", msg); let mut shares_to_submit_upstream = Vec::new(); @@ -658,8 +671,13 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { return Err(JDCError::shutdown(JDCErrorKind::CustomJobError)); }; - if let Err(e) = - upstream_channel.on_set_custom_mining_job_success(set_custom_job, msg) + let set_custom_job_success = SetCustomMiningJobSuccess { + channel_id: msg.channel_id, + request_id: msg.request_id, + job_id: msg.job_id, + }; + if let Err(e) = upstream_channel + .on_set_custom_mining_job_success(set_custom_job, set_custom_job_success) { error!("SetCustomMiningJob.Success validation failed: {e:#?}"); return match e { @@ -709,10 +727,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_custom_mining_job_error( &mut self, _server_id: Option, - msg: SetCustomMiningJobError<'_>, + msg: SetCustomMiningJobErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); let error_code = msg.error_code.as_utf8_or_hex(); if error_code == ERROR_CODE_SET_CUSTOM_MINING_JOB_STALE_CHAIN_TIP { @@ -739,10 +757,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_target( &mut self, _server_id: Option, - msg: SetTarget<'_>, + msg: SetTargetOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); self.upstream_channel .with(|upstream_channel| { if let Some(upstream) = upstream_channel.as_mut() { @@ -759,10 +777,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_group_channel( &mut self, _server_id: Option, - msg: SetGroupChannel<'_>, + msg: SetGroupChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); warn!("⚠️ JDC does not expect group channel updates from the upstream server — ignoring."); Ok(()) } diff --git a/miner-apps/jd-client/src/lib/config.rs b/miner-apps/jd-client/src/lib/config.rs index 9003ca109..059b3c688 100644 --- a/miner-apps/jd-client/src/lib/config.rs +++ b/miner-apps/jd-client/src/lib/config.rs @@ -178,7 +178,7 @@ impl JobDeclaratorClientConfig { pub fn get_txout(&self) -> TxOut { TxOut { value: Amount::from_sat(0), - script_pubkey: self.coinbase_reward_script.script_pubkey().to_owned(), + script_pubkey: self.coinbase_reward_script.script_pubkey(), } } diff --git a/miner-apps/jd-client/src/lib/downstream/common_message_handler.rs b/miner-apps/jd-client/src/lib/downstream/common_message_handler.rs index 23b16aee4..cd05247d0 100644 --- a/miner-apps/jd-client/src/lib/downstream/common_message_handler.rs +++ b/miner-apps/jd-client/src/lib/downstream/common_message_handler.rs @@ -6,20 +6,20 @@ use std::{convert::TryInto, sync::atomic::Ordering}; use stratum_apps::{ stratum_core::{ common_messages_sv2::{ - has_requires_std_job, has_work_selection, Protocol, SetupConnection, - SetupConnectionError, SetupConnectionSuccess, + has_requires_std_job, has_work_selection, Protocol, SetupConnectionErrorOwned, + SetupConnectionOwned, SetupConnectionSuccess, ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_FEATURE_FLAGS, ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL, }, - handlers_sv2::HandleCommonMessagesFromClientAsync, - parsers_sv2::{AnyMessage, Tlv}, + handlers_sv2::HandleCommonMessagesFromClientOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::{error, info}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromClientAsync for Downstream { +impl HandleCommonMessagesFromClientOwnedAsync for Downstream { type Error = JDCError; fn get_negotiated_extensions_with_client( @@ -52,21 +52,21 @@ impl HandleCommonMessagesFromClientAsync for Downstream { async fn handle_setup_connection( &mut self, _client_id: Option, - msg: SetupConnection<'_>, + msg: SetupConnectionOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); if msg.protocol != Protocol::MiningProtocol { info!("Rejecting connection: SetupConnection asking for other protocols than mining protocol."); - let response = SetupConnectionError { + let response = SetupConnectionErrorOwned { flags: 0, error_code: ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL .to_string() .try_into() .map_err(JDCError::shutdown)?, }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(JDCError::shutdown)?; if let Err(e) = self.downstream_io.downstream_sender.send(frame).await { @@ -84,14 +84,14 @@ impl HandleCommonMessagesFromClientAsync for Downstream { if has_work_selection(msg.flags) { info!("Rejecting: work selection not allowed."); - let response = SetupConnectionError { + let response = SetupConnectionErrorOwned { flags: 0b0000_0000_0000_0010, error_code: ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_FEATURE_FLAGS .to_string() .try_into() .map_err(JDCError::shutdown)?, }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(JDCError::shutdown)?; if let Err(e) = self.downstream_io.downstream_sender.send(frame).await { @@ -114,7 +114,7 @@ impl HandleCommonMessagesFromClientAsync for Downstream { used_version: 2, flags: 0, // !REQUIRES_FIXED_VERSION, !REQUIRES_EXTENDED_CHANNELS }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(JDCError::shutdown)?; diff --git a/miner-apps/jd-client/src/lib/downstream/extensions_message_handler.rs b/miner-apps/jd-client/src/lib/downstream/extensions_message_handler.rs index 3d5f2286a..bc3e63dbd 100644 --- a/miner-apps/jd-client/src/lib/downstream/extensions_message_handler.rs +++ b/miner-apps/jd-client/src/lib/downstream/extensions_message_handler.rs @@ -5,17 +5,19 @@ use crate::{ use std::convert::TryInto; use stratum_apps::{ stratum_core::{ - binary_sv2::Seq064K, - extensions_sv2::{RequestExtensions, RequestExtensionsError, RequestExtensionsSuccess}, - handlers_sv2::HandleExtensionsFromClientAsync, - parsers_sv2::{AnyMessage, Tlv}, + binary_sv2::Seq064KOwned, + extensions_sv2::{ + RequestExtensionsErrorOwned, RequestExtensionsOwned, RequestExtensionsSuccessOwned, + }, + handlers_sv2::HandleExtensionsFromClientOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::{error, info}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleExtensionsFromClientAsync for Downstream { +impl HandleExtensionsFromClientOwnedAsync for Downstream { type Error = JDCError; fn get_negotiated_extensions_with_client( @@ -28,7 +30,7 @@ impl HandleExtensionsFromClientAsync for Downstream { async fn handle_request_extensions( &mut self, _client_id: Option, - msg: RequestExtensions<'_>, + msg: RequestExtensionsOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let requested: Vec = msg.requested_extensions.clone().into_inner(); @@ -70,17 +72,17 @@ impl HandleExtensionsFromClientAsync for Downstream { self.downstream_id, requested, supported, unsupported, missing_required ); - let error = RequestExtensionsError { + let error = RequestExtensionsErrorOwned { request_id: msg.request_id, - unsupported_extensions: Seq064K::new(unsupported).map_err(|_| { + unsupported_extensions: Seq064KOwned::new(unsupported).map_err(|_| { JDCError::shutdown(JDCErrorKind::InvalidUnsupportedExtensionsSequence) })?, - required_extensions: Seq064K::new(missing_required.clone()).map_err(|_| { + required_extensions: Seq064KOwned::new(missing_required.clone()).map_err(|_| { JDCError::shutdown(JDCErrorKind::InvalidRequiredExtensionsSequence) })?, }; - let frame: Sv2Frame = AnyMessage::Extensions(error.into()) + let frame: Sv2Frame = AnyMessageOwned::Extensions(error.into()) .try_into() .map_err(JDCError::shutdown)?; if let Err(e) = self.downstream_io.downstream_sender.send(frame).await { @@ -114,14 +116,14 @@ impl HandleExtensionsFromClientAsync for Downstream { .set(supported.clone()) .map_err(JDCError::shutdown)?; - let success = RequestExtensionsSuccess { + let success = RequestExtensionsSuccessOwned { request_id: msg.request_id, - supported_extensions: Seq064K::new(supported.clone()).map_err(|_| { + supported_extensions: Seq064KOwned::new(supported.clone()).map_err(|_| { JDCError::shutdown(JDCErrorKind::InvalidSupportedExtensionsSequence) })?, }; - let frame: Sv2Frame = AnyMessage::Extensions(success.into()) + let frame: Sv2Frame = AnyMessageOwned::Extensions(success.into()) .try_into() .map_err(JDCError::shutdown)?; if let Err(e) = self.downstream_io.downstream_sender.send(frame).await { diff --git a/miner-apps/jd-client/src/lib/downstream/mod.rs b/miner-apps/jd-client/src/lib/downstream/mod.rs index b474199a0..a75c2e697 100644 --- a/miner-apps/jd-client/src/lib/downstream/mod.rs +++ b/miner-apps/jd-client/src/lib/downstream/mod.rs @@ -5,6 +5,7 @@ use std::{ }, time::Duration, }; +use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, MiningOwned}; #[cfg(feature = "monitoring")] use std::net::IpAddr; @@ -20,8 +21,10 @@ use stratum_apps::{ extended::ExtendedChannel, group::GroupChannel, standard::StandardChannel, }, common_messages_sv2::MESSAGE_TYPE_SETUP_CONNECTION, - handlers_sv2::{HandleCommonMessagesFromClientAsync, HandleExtensionsFromClientAsync}, - parsers_sv2::{parse_message_frame_with_tlvs, AnyMessage, Mining, Tlv}, + handlers_sv2::{ + HandleCommonMessagesFromClientOwnedAsync, HandleExtensionsFromClientOwnedAsync, + }, + parsers_sv2::{parse_message_frame_with_tlvs, Tlv}, }, sync::{SharedLock, SharedMap}, task_manager::TaskManager, @@ -49,8 +52,8 @@ mod extensions_message_handler; /// - `downstream_receiver`: receives frames from the downstream. #[derive(Clone)] pub struct DownstreamIo { - channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, + channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, downstream_sender: Sender, downstream_receiver: Receiver, } @@ -70,9 +73,9 @@ pub struct Downstream { pub connection_ip: IpAddr, /// Whether the downstream requires standard jobs. pub require_std_job: Arc, - pub group_channel: SharedLock>, - pub extended_channels: SharedMap>, - pub standard_channels: SharedMap>, + pub group_channel: SharedLock, + pub extended_channels: SharedMap, + pub standard_channels: SharedMap, pub channel_id_factory: Arc, /// Extensions that have been successfully negotiated with this client. pub negotiated_extensions: SharedLock>, @@ -159,9 +162,9 @@ impl Downstream { pub fn new( downstream_id: DownstreamId, channel_id_factory: AtomicU32, - group_channel: GroupChannel<'static>, - channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, + group_channel: GroupChannel, + channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, noise_stream: NoiseTcpStream, cancellation_token: CancellationToken, fallback_coordinator: FallbackCoordinator, @@ -340,7 +343,7 @@ impl Downstream { } }; - let message = AnyMessage::Mining(message); + let message = AnyMessageOwned::Mining(message); let sv2_frame: Sv2Frame = message.try_into().map_err(JDCError::shutdown)?; self.downstream_io @@ -374,8 +377,8 @@ impl Downstream { let (any_message, tlv_fields) = parse_message_frame_with_tlvs(header, payload, &negotiated_extensions) .map_err(|error| JDCError::disconnect(error, self.downstream_id))?; - match any_message { - AnyMessage::Mining(message) => { + match any_message.into_owned() { + AnyMessageOwned::Mining(message) => { self.downstream_io .channel_manager_sender .send((self.downstream_id, message, tlv_fields)) @@ -385,7 +388,7 @@ impl Downstream { JDCError::shutdown(JDCErrorKind::ChannelErrorSender) })?; } - AnyMessage::Extensions(message) => { + AnyMessageOwned::Extensions(message) => { self.handle_extensions_message_from_client(None, message, tlv_fields.as_deref()) .await?; } diff --git a/miner-apps/jd-client/src/lib/job_declarator/message_handler.rs b/miner-apps/jd-client/src/lib/job_declarator/message_handler.rs index a8a7948c0..99351678d 100644 --- a/miner-apps/jd-client/src/lib/job_declarator/message_handler.rs +++ b/miner-apps/jd-client/src/lib/job_declarator/message_handler.rs @@ -1,8 +1,9 @@ use stratum_apps::stratum_core::{ common_messages_sv2::{ - ChannelEndpointChanged, Reconnect, SetupConnectionError, SetupConnectionSuccess, + ChannelEndpointChangedOwned, ReconnectOwned, SetupConnectionErrorOwned, + SetupConnectionSuccessOwned, }, - handlers_sv2::HandleCommonMessagesFromServerAsync, + handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, parsers_sv2::Tlv, }; use tracing::{info, warn}; @@ -13,7 +14,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromServerAsync for JobDeclarator { +impl HandleCommonMessagesFromServerOwnedAsync for JobDeclarator { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -26,10 +27,10 @@ impl HandleCommonMessagesFromServerAsync for JobDeclarator { async fn handle_setup_connection_success( &mut self, _server_id: Option, - msg: SetupConnectionSuccess, + msg: SetupConnectionSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); self.mode.activate(); Ok(()) } @@ -37,30 +38,30 @@ impl HandleCommonMessagesFromServerAsync for JobDeclarator { async fn handle_channel_endpoint_changed( &mut self, _server_id: Option, - msg: ChannelEndpointChanged, + msg: ChannelEndpointChangedOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_reconnect( &mut self, _server_id: Option, - msg: Reconnect<'_>, + msg: ReconnectOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_setup_connection_error( &mut self, _server_id: Option, - msg: SetupConnectionError<'_>, + msg: SetupConnectionErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); Err(JDCError::fallback(JDCErrorKind::SetupConnectionError)) } } diff --git a/miner-apps/jd-client/src/lib/job_declarator/mod.rs b/miner-apps/jd-client/src/lib/job_declarator/mod.rs index df67828fc..6ecf1b623 100644 --- a/miner-apps/jd-client/src/lib/job_declarator/mod.rs +++ b/miner-apps/jd-client/src/lib/job_declarator/mod.rs @@ -1,4 +1,5 @@ use std::{net::SocketAddr, sync::Arc}; +use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, JobDeclarationOwned}; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ @@ -7,9 +8,8 @@ use stratum_apps::{ fallback_coordinator::FallbackCoordinator, network_helpers::{connect_with_noise, resolve_host, TCP_CONNECT_TIMEOUT}, stratum_core::{ - framing_sv2, - handlers_sv2::HandleCommonMessagesFromServerAsync, - parsers_sv2::{AnyMessage, JobDeclaration}, + framing_sv2, handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, + parsers_sv2::JobDeclaration, }, task_manager::TaskManager, utils::{ @@ -32,8 +32,8 @@ mod message_handler; /// Holds all channels required for Job Declarator communication. #[derive(Clone)] pub struct JobDeclaratorIo { - channel_manager_sender: Sender>, - channel_manager_receiver: Receiver>, + channel_manager_sender: Sender, + channel_manager_receiver: Receiver, jds_sender: Sender, jds_receiver: Receiver, } @@ -126,8 +126,8 @@ impl JobDeclarator { /// - Spawns background IO tasks for reading/writing frames. pub async fn new( upstream_entry: &UpstreamEntry, - channel_manager_sender: Sender>, - channel_manager_receiver: Receiver>, + channel_manager_sender: Sender, + channel_manager_receiver: Receiver, cancellation_token: CancellationToken, fallback_coordinator: FallbackCoordinator, mode: JDMode, @@ -319,7 +319,7 @@ impl JobDeclarator { match self.job_declarator_io.channel_manager_receiver.recv().await { Ok(msg) => { debug!("Forwarding message from channel manager to JDS."); - let message = AnyMessage::JobDeclaration(msg); + let message = AnyMessageOwned::JobDeclaration(msg); let sv2_frame: Sv2Frame = message.try_into().map_err(JDCError::shutdown)?; self.job_declarator_io .jds_sender @@ -367,7 +367,7 @@ impl JobDeclarator { MessageType::JobDeclaration => { let message = JobDeclaration::try_from((message_type, sv2_frame.payload())) .map_err(JDCError::fallback)? - .into_static(); + .into_owned(); self.job_declarator_io .channel_manager_sender .send(message) diff --git a/miner-apps/jd-client/src/lib/mod.rs b/miner-apps/jd-client/src/lib/mod.rs index c672f8de4..69e37f6d2 100644 --- a/miner-apps/jd-client/src/lib/mod.rs +++ b/miner-apps/jd-client/src/lib/mod.rs @@ -8,12 +8,13 @@ use std::{ thread::JoinHandle, time::Duration, }; +use stratum_apps::stratum_core::parsers_sv2::JobDeclarationOwned; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ bitcoin_core_sv2::CancellationToken, fallback_coordinator::FallbackCoordinator, - stratum_core::{bitcoin::consensus::Encodable, parsers_sv2::JobDeclaration}, + stratum_core::bitcoin::consensus::Encodable, task_manager::TaskManager, tp_type::TemplateProviderType, utils::types::{Sv2Frame, GRACEFUL_SHUTDOWN_TIMEOUT_SECONDS}, @@ -660,8 +661,8 @@ impl JobDeclaratorClient { upstreams: &mut [UpstreamEntry], channel_manager_to_upstream_receiver: Receiver, upstream_to_channel_manager_sender: Sender, - channel_manager_to_jd_receiver: Receiver>, - jd_to_channel_manager_sender: Sender>, + channel_manager_to_jd_receiver: Receiver, + jd_to_channel_manager_sender: Sender, cancellation_token: CancellationToken, fallback_coordinator: FallbackCoordinator, mode: JDMode, @@ -773,8 +774,8 @@ async fn try_initialize_single( upstream_entry: &UpstreamEntry, upstream_to_channel_manager_sender: Sender, channel_manager_to_upstream_receiver: Receiver, - jd_to_channel_manager_sender: Sender>, - channel_manager_to_jd_receiver: Receiver>, + jd_to_channel_manager_sender: Sender, + channel_manager_to_jd_receiver: Receiver, cancellation_token: CancellationToken, fallback_coordinator: FallbackCoordinator, mode: JDMode, diff --git a/miner-apps/jd-client/src/lib/template_receiver/bitcoin_core.rs b/miner-apps/jd-client/src/lib/template_receiver/bitcoin_core.rs index e697fa7c1..1742462b5 100644 --- a/miner-apps/jd-client/src/lib/template_receiver/bitcoin_core.rs +++ b/miner-apps/jd-client/src/lib/template_receiver/bitcoin_core.rs @@ -5,7 +5,7 @@ use stratum_apps::{ runtime_api::{template_distribution_protocol, BitcoinCoreVersion}, CancellationToken, }, - stratum_core::parsers_sv2::TemplateDistribution, + stratum_core::parsers_sv2::TemplateDistributionOwned, task_manager::TaskManager, }; @@ -15,8 +15,8 @@ pub struct BitcoinCoreSv2TDPConfig { pub unix_socket_path: PathBuf, pub fee_threshold: u64, pub min_interval: u8, - pub incoming_tdp_receiver: Receiver>, - pub outgoing_tdp_sender: Sender>, + pub incoming_tdp_receiver: Receiver, + pub outgoing_tdp_sender: Sender, pub cancellation_token: CancellationToken, } diff --git a/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/message_handler.rs b/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/message_handler.rs index e24878d95..d0686afc2 100644 --- a/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/message_handler.rs +++ b/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/message_handler.rs @@ -1,8 +1,9 @@ use stratum_apps::stratum_core::{ common_messages_sv2::{ - ChannelEndpointChanged, Reconnect, SetupConnectionError, SetupConnectionSuccess, + ChannelEndpointChangedOwned, ReconnectOwned, SetupConnectionErrorOwned, + SetupConnectionSuccessOwned, }, - handlers_sv2::HandleCommonMessagesFromServerAsync, + handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, parsers_sv2::Tlv, }; use tracing::{info, warn}; @@ -13,7 +14,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromServerAsync for Sv2Tp { +impl HandleCommonMessagesFromServerOwnedAsync for Sv2Tp { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -26,10 +27,10 @@ impl HandleCommonMessagesFromServerAsync for Sv2Tp { async fn handle_setup_connection_success( &mut self, _server_id: Option, - msg: SetupConnectionSuccess, + msg: SetupConnectionSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } @@ -37,30 +38,30 @@ impl HandleCommonMessagesFromServerAsync for Sv2Tp { async fn handle_channel_endpoint_changed( &mut self, _server_id: Option, - msg: ChannelEndpointChanged, + msg: ChannelEndpointChangedOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_reconnect( &mut self, _server_id: Option, - msg: Reconnect<'_>, + msg: ReconnectOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_setup_connection_error( &mut self, _server_id: Option, - msg: SetupConnectionError<'_>, + msg: SetupConnectionErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); Err(JDCError::shutdown(JDCErrorKind::SetupConnectionError)) } } diff --git a/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/mod.rs b/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/mod.rs index 0645178a3..aa21c030d 100644 --- a/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/mod.rs +++ b/miner-apps/jd-client/src/lib/template_receiver/sv2_tp/mod.rs @@ -11,6 +11,7 @@ //! - Send [`CoinbaseOutputConstraints`] to the template provider use std::sync::Arc; +use stratum_apps::stratum_core::parsers_sv2::AnyMessageOwned; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ @@ -20,9 +21,9 @@ use stratum_apps::{ network_helpers::{self, connect_with_noise, resolve_host_port, TCP_CONNECT_TIMEOUT}, stratum_core::{ framing_sv2, - handlers_sv2::HandleCommonMessagesFromServerAsync, + handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, noise_sv2, - parsers_sv2::{AnyMessage, TemplateDistribution}, + parsers_sv2::{TemplateDistribution, TemplateDistributionOwned}, }, task_manager::TaskManager, utils::{ @@ -50,8 +51,8 @@ mod message_handler; /// - `inbound_rx` → receives frames from the template provider #[derive(Clone)] pub struct Sv2TpIo { - channel_manager_sender: Sender>, - channel_manager_receiver: Receiver>, + channel_manager_sender: Sender, + channel_manager_receiver: Receiver, tp_sender: Sender, tp_receiver: Receiver, } @@ -134,8 +135,8 @@ impl Sv2Tp { pub async fn new( tp_address: String, public_key: Option, - channel_manager_receiver: Receiver>, - channel_manager_sender: Sender>, + channel_manager_receiver: Receiver, + channel_manager_sender: Sender, cancellation_token: CancellationToken, task_manager: Arc, ) -> JDCResult { @@ -324,7 +325,7 @@ impl Sv2Tp { MessageType::TemplateDistribution => { let message = TemplateDistribution::try_from((message_type, sv2_frame.payload())) .map_err(JDCError::shutdown)? - .into_static(); + .into_owned(); self.sv2_tp_io .channel_manager_sender .send(message) @@ -345,7 +346,7 @@ impl Sv2Tp { /// /// Forwards outbound frames upstream pub async fn handle_channel_manager_message(&self) -> JDCResult<(), error::TemplateProvider> { - let msg = AnyMessage::TemplateDistribution( + let msg = AnyMessageOwned::TemplateDistribution( self.sv2_tp_io .channel_manager_receiver .recv() diff --git a/miner-apps/jd-client/src/lib/upstream/message_handler.rs b/miner-apps/jd-client/src/lib/upstream/message_handler.rs index 2181bfa1d..0c1e184b4 100644 --- a/miner-apps/jd-client/src/lib/upstream/message_handler.rs +++ b/miner-apps/jd-client/src/lib/upstream/message_handler.rs @@ -1,8 +1,9 @@ use stratum_apps::stratum_core::{ common_messages_sv2::{ - ChannelEndpointChanged, Reconnect, SetupConnectionError, SetupConnectionSuccess, + ChannelEndpointChangedOwned, ReconnectOwned, SetupConnectionErrorOwned, + SetupConnectionSuccessOwned, }, - handlers_sv2::HandleCommonMessagesFromServerAsync, + handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, parsers_sv2::Tlv, }; use tracing::{info, warn}; @@ -13,7 +14,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromServerAsync for Upstream { +impl HandleCommonMessagesFromServerOwnedAsync for Upstream { type Error = JDCError; fn get_negotiated_extensions_with_server( @@ -26,10 +27,10 @@ impl HandleCommonMessagesFromServerAsync for Upstream { async fn handle_setup_connection_success( &mut self, _server_id: Option, - msg: SetupConnectionSuccess, + msg: SetupConnectionSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } @@ -37,30 +38,30 @@ impl HandleCommonMessagesFromServerAsync for Upstream { async fn handle_channel_endpoint_changed( &mut self, _server_id: Option, - msg: ChannelEndpointChanged, + msg: ChannelEndpointChangedOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_reconnect( &mut self, _server_id: Option, - msg: Reconnect<'_>, + msg: ReconnectOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_setup_connection_error( &mut self, _server_id: Option, - msg: SetupConnectionError<'_>, + msg: SetupConnectionErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); Err(JDCError::fallback(JDCErrorKind::SetupConnectionError)) } } diff --git a/miner-apps/jd-client/src/lib/upstream/mod.rs b/miner-apps/jd-client/src/lib/upstream/mod.rs index d2e4dcfca..759f27eb6 100644 --- a/miner-apps/jd-client/src/lib/upstream/mod.rs +++ b/miner-apps/jd-client/src/lib/upstream/mod.rs @@ -10,6 +10,9 @@ //! - Handle common messages from upstream use std::{net::SocketAddr, sync::Arc}; +use stratum_apps::stratum_core::{ + binary_sv2::Seq064KOwned, extensions_sv2::RequestExtensionsOwned, +}; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ @@ -18,8 +21,8 @@ use stratum_apps::{ fallback_coordinator::FallbackCoordinator, network_helpers::{connect_with_noise, resolve_host, TCP_CONNECT_TIMEOUT}, stratum_core::{ - binary_sv2::Seq064K, extensions_sv2::RequestExtensions, framing_sv2, - handlers_sv2::HandleCommonMessagesFromServerAsync, parsers_sv2::AnyMessage, + framing_sv2, handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, + parsers_sv2::AnyMessageOwned, }, task_manager::TaskManager, utils::{ @@ -272,9 +275,9 @@ impl Upstream { } let requested_extensions = - Seq064K::new(self.required_extensions.clone()).map_err(JDCError::shutdown)?; + Seq064KOwned::new(self.required_extensions.clone()).map_err(JDCError::shutdown)?; - let request_extensions = RequestExtensions { + let request_extensions = RequestExtensionsOwned { request_id: 0, requested_extensions, }; @@ -284,7 +287,7 @@ impl Upstream { self.required_extensions ); - let sv2_frame: Sv2Frame = AnyMessage::Extensions(request_extensions.into_static().into()) + let sv2_frame: Sv2Frame = AnyMessageOwned::Extensions(request_extensions.into()) .try_into() .map_err(JDCError::shutdown)?; diff --git a/miner-apps/jd-client/src/lib/utils.rs b/miner-apps/jd-client/src/lib/utils.rs index d2a22a2ac..118f1c365 100644 --- a/miner-apps/jd-client/src/lib/utils.rs +++ b/miner-apps/jd-client/src/lib/utils.rs @@ -19,21 +19,23 @@ use std::{ Arc, }, }; +use stratum_apps::stratum_core::{ + binary_sv2::Str0255Owned, + job_declaration_sv2::PushSolutionOwned, + mining_sv2::{ + CloseChannelOwned, OpenExtendedMiningChannelOwned, OpenStandardMiningChannelOwned, + }, +}; use stratum_apps::{ key_utils::Secp256k1PublicKey, stratum_core::{ - binary_sv2::Str0255, bitcoin::hashes::sha256d, - channels_sv2::{client, client::extended::ExtendedChannel}, - common_messages_sv2::{Protocol, SetupConnection}, - job_declaration_sv2::PushSolution, - mining_sv2::{ - CloseChannel, OpenExtendedMiningChannel, OpenStandardMiningChannel, - SubmitSharesExtended, - }, - parsers_sv2::{JobDeclaration, Mining, Tlv}, - template_distribution_sv2::SetNewPrevHash as SetNewPrevHashTdp, + channels_sv2::client::{self, extended::ExtendedChannel}, + common_messages_sv2::{Protocol, SetupConnectionOwned}, + mining_sv2::SubmitSharesExtendedOwned, + parsers_sv2::{JobDeclarationOwned, MiningOwned, Tlv}, + template_distribution_sv2::SetNewPrevHashOwned as SetNewPrevHashTdp, }, utils::types::{ChannelId, DownstreamId, Hashrate, JobId}, }; @@ -44,7 +46,7 @@ use crate::{ jd_mode::JDMode, }; -pub(crate) type DownstreamMessage = (Mining<'static>, Option>); +pub(crate) type DownstreamMessage = (MiningOwned, Option>); /// Represents a single upstream entry (Pool + JDS pair) with raw address strings /// that are resolved via DNS at connection time. @@ -66,14 +68,15 @@ pub fn get_setup_connection_message( min_version: u16, max_version: u16, address: &SocketAddr, -) -> Result, JDCErrorKind> { - let endpoint_host = address.ip().to_string().try_into()?; +) -> Result { + let address_str = address.ip().to_string(); + let endpoint_host = address_str.as_str().try_into()?; let vendor = "".try_into()?; let hardware_version = "".try_into()?; let firmware = "".try_into()?; let device_id = "".try_into()?; let flags = 0b0000_0000_0000_0000_0000_0000_0000_0110; - Ok(SetupConnection { + Ok(SetupConnectionOwned { protocol: Protocol::MiningProtocol, min_version, max_version, @@ -91,13 +94,14 @@ pub fn get_setup_connection_message( pub fn get_setup_connection_message_jds( proxy_address: &SocketAddr, mode: &JDMode, -) -> SetupConnection<'static> { - let endpoint_host = proxy_address.ip().to_string().try_into().unwrap(); +) -> SetupConnectionOwned { + let address_str = proxy_address.ip().to_string(); + let endpoint_host = address_str.as_str().try_into().unwrap(); let vendor = "".try_into().unwrap(); let hardware_version = "".try_into().unwrap(); let firmware = "".try_into().unwrap(); let device_id = "".try_into().unwrap(); - let mut setup_connection = SetupConnection { + let mut setup_connection = SetupConnectionOwned { protocol: Protocol::JobDeclarationProtocol, min_version: 2, max_version: 2, @@ -118,13 +122,14 @@ pub fn get_setup_connection_message_jds( } /// Constructs a `SetupConnection` message for the Template Provider (TP). -pub fn get_setup_connection_message_tp(address: SocketAddr) -> SetupConnection<'static> { - let endpoint_host = address.ip().to_string().try_into().unwrap(); +pub fn get_setup_connection_message_tp(address: SocketAddr) -> SetupConnectionOwned { + let address_str = address.ip().to_string(); + let endpoint_host = address_str.as_str().try_into().unwrap(); let vendor = "".try_into().unwrap(); let hardware_version = "".try_into().unwrap(); let firmware = "".try_into().unwrap(); let device_id = "".try_into().unwrap(); - SetupConnection { + SetupConnectionOwned { protocol: Protocol::TemplateDistributionProtocol, min_version: 2, max_version: 2, @@ -215,17 +220,17 @@ pub enum PendingChannelRequest { /// A request to open an extended mining channel. ExtendedChannel { downstream_id: DownstreamId, - message: OpenExtendedMiningChannel<'static>, + message: OpenExtendedMiningChannelOwned, }, /// A request to open a standard mining channel. StandardChannel { downstream_id: DownstreamId, - message: OpenStandardMiningChannel<'static>, + message: OpenStandardMiningChannelOwned, }, } -impl From<(DownstreamId, OpenExtendedMiningChannel<'static>)> for PendingChannelRequest { - fn from(value: (DownstreamId, OpenExtendedMiningChannel<'static>)) -> Self { +impl From<(DownstreamId, OpenExtendedMiningChannelOwned)> for PendingChannelRequest { + fn from(value: (DownstreamId, OpenExtendedMiningChannelOwned)) -> Self { PendingChannelRequest::ExtendedChannel { downstream_id: value.0, message: value.1, @@ -233,8 +238,8 @@ impl From<(DownstreamId, OpenExtendedMiningChannel<'static>)> for PendingChannel } } -impl From<(DownstreamId, OpenStandardMiningChannel<'static>)> for PendingChannelRequest { - fn from(value: (DownstreamId, OpenStandardMiningChannel<'static>)) -> Self { +impl From<(DownstreamId, OpenStandardMiningChannelOwned)> for PendingChannelRequest { + fn from(value: (DownstreamId, OpenStandardMiningChannelOwned)) -> Self { PendingChannelRequest::StandardChannel { downstream_id: value.0, message: value.1, @@ -256,16 +261,16 @@ impl PendingChannelRequest { } } - pub fn message(self) -> Mining<'static> { + pub fn message(self) -> MiningOwned { match self { PendingChannelRequest::ExtendedChannel { downstream_id: _, message: open_channel_message, - } => Mining::OpenExtendedMiningChannel(open_channel_message), + } => MiningOwned::OpenExtendedMiningChannel(open_channel_message), PendingChannelRequest::StandardChannel { downstream_id: _, message: open_channel_message, - } => Mining::OpenStandardMiningChannel(open_channel_message), + } => MiningOwned::OpenStandardMiningChannel(open_channel_message), } } @@ -287,10 +292,10 @@ impl PendingChannelRequest { /// /// The `msg` is converted into a [`Str0255`] reason code. /// If conversion fails, this function will panic. -pub(crate) fn create_close_channel_msg(channel_id: ChannelId, msg: &str) -> CloseChannel<'_> { - CloseChannel { +pub(crate) fn create_close_channel_msg(channel_id: ChannelId, msg: &str) -> CloseChannelOwned { + CloseChannelOwned { channel_id, - reason_code: Str0255::try_from(msg.to_string()).expect("Could not convert message."), + reason_code: Str0255Owned::try_from(msg).expect("Could not convert message."), } } @@ -315,9 +320,9 @@ impl From<(DownstreamId, ChannelId, JobId)> for DownstreamChannelJobId { /// arrives. This method also appends response to route queue to be sent /// to upstream. pub fn validate_cached_share( - mut upstream_message: SubmitSharesExtended<'static>, - upstream_channel: &mut ExtendedChannel<'static>, - prev_hash: &SetNewPrevHashTdp<'static>, + mut upstream_message: SubmitSharesExtendedOwned, + upstream_channel: &mut ExtendedChannel, + prev_hash: &SetNewPrevHashTdp, sequence_number_factory: &AtomicU32, messages: &mut Vec, ) { @@ -330,7 +335,7 @@ pub fn validate_cached_share( "Cached SubmitSharesExtended: valid share, forwarding it to upstream | channel_id: {}, sequence_number: {}, share_hash: {} ✅", upstream_message.channel_id, upstream_message.sequence_number, share_hash ); - messages.push(Mining::SubmitSharesExtended(upstream_message.into_static()).into()); + messages.push(MiningOwned::SubmitSharesExtended(upstream_message).into()); } Ok(client::share_accounting::ShareValidationResult::BlockFound(share_hash)) => { @@ -342,7 +347,7 @@ pub fn validate_cached_share( let mut channel_extranonce = upstream_channel.get_extranonce_prefix().to_vec(); channel_extranonce.extend_from_slice(upstream_message.extranonce.as_bytes()); - let push_solution = PushSolution { + let push_solution = PushSolutionOwned { extranonce: channel_extranonce.try_into().expect("extranonce"), ntime: upstream_message.ntime, nonce: upstream_message.nonce, @@ -351,8 +356,8 @@ pub fn validate_cached_share( prev_hash: prev_hash.prev_hash.clone(), }; - messages.push(JobDeclaration::PushSolution(push_solution).into()); - messages.push(Mining::SubmitSharesExtended(upstream_message.into_static()).into()); + messages.push(JobDeclarationOwned::PushSolution(push_solution).into()); + messages.push(MiningOwned::SubmitSharesExtended(upstream_message).into()); } Err(err) => { @@ -380,12 +385,12 @@ const CACHED_SHARES_CAPACITY: usize = 100; /// A wrapper around [`SubmitSharesExtended`] that adds ordering by share difficulty. #[derive(Clone, Debug)] pub struct SharesOrderedByDiff { - pub share: SubmitSharesExtended<'static>, + pub share: SubmitSharesExtendedOwned, share_hash: sha256d::Hash, } impl SharesOrderedByDiff { - pub fn new(share: SubmitSharesExtended<'static>, share_hash: sha256d::Hash) -> Self { + pub fn new(share: SubmitSharesExtendedOwned, share_hash: sha256d::Hash) -> Self { Self { share, share_hash } } } diff --git a/miner-apps/translator/src/lib/error.rs b/miner-apps/translator/src/lib/error.rs index d641d79ec..c06a19555 100644 --- a/miner-apps/translator/src/lib/error.rs +++ b/miner-apps/translator/src/lib/error.rs @@ -365,8 +365,8 @@ impl From for TproxyErrorKind { } } -impl<'a> From> for TproxyErrorKind { - fn from(_: stratum_apps::stratum_core::sv1_api::error::Error<'a>) -> Self { +impl From for TproxyErrorKind { + fn from(_: stratum_apps::stratum_core::sv1_api::error::Error) -> Self { TproxyErrorKind::SV1Error } } diff --git a/miner-apps/translator/src/lib/monitoring.rs b/miner-apps/translator/src/lib/monitoring.rs index c7e6ae28f..8ed850b55 100644 --- a/miner-apps/translator/src/lib/monitoring.rs +++ b/miner-apps/translator/src/lib/monitoring.rs @@ -136,7 +136,7 @@ mod tests { ) } - fn create_extended_channel(channel_id: u32, user_identity: &str) -> ExtendedChannel<'static> { + fn create_extended_channel(channel_id: u32, user_identity: &str) -> ExtendedChannel { let prefix = ExtranoncePrefix::from_wire(vec![0x01, channel_id as u8]).unwrap(); ExtendedChannel::new( channel_id, diff --git a/miner-apps/translator/src/lib/sv1/downstream.rs b/miner-apps/translator/src/lib/sv1/downstream.rs index bac342bfe..347626d34 100644 --- a/miner-apps/translator/src/lib/sv1/downstream.rs +++ b/miner-apps/translator/src/lib/sv1/downstream.rs @@ -66,7 +66,7 @@ impl DownstreamIo { #[derive(Debug)] pub struct DownstreamData { pub channel_id: Option, - pub extranonce1: Extranonce<'static>, + pub extranonce1: Extranonce, pub extranonce2_len: usize, pub target: Target, pub hashrate: Option, diff --git a/miner-apps/translator/src/lib/sv1/sv1_server/difficulty_manager.rs b/miner-apps/translator/src/lib/sv1/sv1_server/difficulty_manager.rs index f666be2da..5170a933e 100644 --- a/miner-apps/translator/src/lib/sv1/sv1_server/difficulty_manager.rs +++ b/miner-apps/translator/src/lib/sv1/sv1_server/difficulty_manager.rs @@ -1,4 +1,8 @@ use std::sync::Arc; +use stratum_apps::stratum_core::{ + mining_sv2::{SetTargetOwned, UpdateChannelOwned}, + parsers_sv2::MiningOwned, +}; use crate::sv1::sv1_server::{ PendingTargetUpdate, SV1_MIN_DIFFICULTY_FOR_INTEGER_POWER_OF_TWO_ROUNDING, @@ -8,8 +12,6 @@ use stratum_apps::{ stratum_core::{ bitcoin::Target, channels_sv2::{target::hash_rate_to_target, Vardiff}, - mining_sv2::{SetTarget, UpdateChannel}, - parsers_sv2::Mining, stratum_translation::sv2_to_sv1::build_sv1_set_difficulty_from_sv2_target_with_integer_power_of_two_rounding, }, utils::types::{ChannelId, DownstreamId, Hashrate}, @@ -248,7 +250,7 @@ impl Sv1Server { let min_target = min_target.expect("at least one downstream must exist"); let downstream_count = self.downstreams.len(); - let update_channel = UpdateChannel { + let update_channel = UpdateChannelOwned { channel_id: *channel_id, nominal_hash_rate: total_hashrate, maximum_target: min_target.to_le_bytes().into(), @@ -266,7 +268,7 @@ impl Sv1Server { if let Err(e) = self .sv1_server_io .channel_manager_sender - .send((Mining::UpdateChannel(update_channel), None)) + .send((MiningOwned::UpdateChannel(update_channel), None)) .await { error!("Failed to send aggregated UpdateChannel: {:?}", e); @@ -278,7 +280,7 @@ impl Sv1Server { all_updates: Vec<(DownstreamId, ChannelId, Target, Hashrate)>, ) { for (downstream_id, channel_id, new_target, new_hashrate) in all_updates { - let update_channel = UpdateChannel { + let update_channel = UpdateChannelOwned { channel_id, nominal_hash_rate: new_hashrate, maximum_target: new_target.to_le_bytes().into(), @@ -292,7 +294,7 @@ impl Sv1Server { if let Err(e) = self .sv1_server_io .channel_manager_sender - .send((Mining::UpdateChannel(update_channel), None)) + .send((MiningOwned::UpdateChannel(update_channel), None)) .await { error!( @@ -308,7 +310,7 @@ impl Sv1Server { /// Aggregated mode: Single SetTarget updates all downstreams and processes all pending updates /// Non-aggregated mode: Each SetTarget updates one specific downstream and processes its /// pending update - pub(super) async fn handle_set_target_message(&self, set_target: SetTarget<'_>) { + pub(super) async fn handle_set_target_message(&self, set_target: SetTargetOwned) { let new_upstream_target = Target::from_le_bytes(set_target.maximum_target.to_array()); debug!( "Received SetTarget for channel {}: new_upstream_target = {}", @@ -513,13 +515,13 @@ impl Sv1Server { AggregatedSnapshot::Active { total_hashrate, min_target, - } => UpdateChannel { + } => UpdateChannelOwned { channel_id: 0, // ChannelManager will rewrite to upstream extended channel id nominal_hash_rate: total_hashrate, maximum_target: min_target.to_le_bytes().into(), }, - AggregatedSnapshot::NoDownstreams => UpdateChannel { + AggregatedSnapshot::NoDownstreams => UpdateChannelOwned { channel_id: 0, nominal_hash_rate: 0.0, maximum_target: [0xFF; 32].into(), @@ -529,7 +531,7 @@ impl Sv1Server { if let Err(e) = self .sv1_server_io .channel_manager_sender - .send((Mining::UpdateChannel(update), None)) + .send((MiningOwned::UpdateChannel(update), None)) .await { error!( diff --git a/miner-apps/translator/src/lib/sv1/sv1_server/downstream_message_handler.rs b/miner-apps/translator/src/lib/sv1/sv1_server/downstream_message_handler.rs index 267ce74ca..811c7fb0b 100644 --- a/miner-apps/translator/src/lib/sv1/sv1_server/downstream_message_handler.rs +++ b/miner-apps/translator/src/lib/sv1/sv1_server/downstream_message_handler.rs @@ -19,13 +19,12 @@ use crate::{ // Implements `IsServer` for `Sv1Server` to handle the Sv1 messages. #[cfg_attr(not(test), hotpath::measure_all)] -impl IsServer<'static> for Sv1Server { +impl IsServer for Sv1Server { fn handle_configure( &mut self, client_id: Option, request: &client_to_server::Configure, - ) -> Result<(Option, Option), Error<'static>> - { + ) -> Result<(Option, Option), Error> { let downstream_id = client_id.expect("Downstream id should exist"); info!("Received mining.configure from SV1 downstream"); @@ -64,7 +63,7 @@ impl IsServer<'static> for Sv1Server { &self, client_id: Option, request: &client_to_server::Subscribe, - ) -> Result, Error<'static>> { + ) -> Result, Error> { let downstream_id = client_id.expect("Downstream id should exist"); info!("Received mining.subscribe from Sv1 downstream"); @@ -87,7 +86,7 @@ impl IsServer<'static> for Sv1Server { &self, client_id: Option, request: &client_to_server::Authorize, - ) -> Result> { + ) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); info!("Received mining.authorize from Sv1 downstream {downstream_id}"); debug!("Down: Handling mining.authorize: {}", request); @@ -97,8 +96,8 @@ impl IsServer<'static> for Sv1Server { fn handle_submit( &self, client_id: Option, - request: &client_to_server::Submit<'static>, - ) -> Result> { + request: &client_to_server::Submit, + ) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { @@ -120,8 +119,7 @@ impl IsServer<'static> for Sv1Server { channel_id }; - let find_job = - |jobs: &[Notify<'static>]| jobs.iter().find(|j| j.job_id == *job_id).cloned(); + let find_job = |jobs: &[Notify]| jobs.iter().find(|j| j.job_id == *job_id).cloned(); let job = self .valid_sv1_jobs @@ -178,12 +176,12 @@ impl IsServer<'static> for Sv1Server { } /// Indicates to the server that the client supports the mining.set_extranonce method. - fn handle_extranonce_subscribe(&self) -> Result<(), Error<'static>> { + fn handle_extranonce_subscribe(&self) -> Result<(), Error> { Ok(()) } /// Checks if a Downstream role is authorized. - fn is_authorized(&self, client_id: Option, name: &str) -> Result> { + fn is_authorized(&self, client_id: Option, name: &str) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -195,7 +193,7 @@ impl IsServer<'static> for Sv1Server { } /// Authorizes a Downstream role. - fn authorize(&mut self, client_id: Option, name: &str) -> Result<(), Error<'static>> { + fn authorize(&mut self, client_id: Option, name: &str) -> Result<(), Error> { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -220,8 +218,8 @@ impl IsServer<'static> for Sv1Server { fn set_extranonce1( &mut self, client_id: Option, - _extranonce1: Option>, - ) -> Result, Error<'static>> { + _extranonce1: Option, + ) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -232,7 +230,7 @@ impl IsServer<'static> for Sv1Server { } /// Returns the `Downstream`'s `extranonce1` value. - fn extranonce1(&self, client_id: Option) -> Result, Error<'static>> { + fn extranonce1(&self, client_id: Option) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -248,7 +246,7 @@ impl IsServer<'static> for Sv1Server { &mut self, client_id: Option, _extra_nonce2_size: Option, - ) -> Result> { + ) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -259,7 +257,7 @@ impl IsServer<'static> for Sv1Server { } /// Returns the `Downstream`'s `extranonce2_size` value. - fn extranonce2_size(&self, client_id: Option) -> Result> { + fn extranonce2_size(&self, client_id: Option) -> Result { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -270,10 +268,7 @@ impl IsServer<'static> for Sv1Server { } /// Returns the version rolling mask. - fn version_rolling_mask( - &self, - client_id: Option, - ) -> Result, Error<'static>> { + fn version_rolling_mask(&self, client_id: Option) -> Result, Error> { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -288,7 +283,7 @@ impl IsServer<'static> for Sv1Server { &mut self, client_id: Option, mask: Option, - ) -> Result<(), Error<'static>> { + ) -> Result<(), Error> { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -306,7 +301,7 @@ impl IsServer<'static> for Sv1Server { &mut self, client_id: Option, mask: Option, - ) -> Result<(), Error<'static>> { + ) -> Result<(), Error> { let downstream_id = client_id.expect("Downstream id should exist"); let Some(downstream) = self.downstreams.get(&downstream_id) else { return Err(Error::UnknownID(downstream_id as u64)); @@ -317,7 +312,7 @@ impl IsServer<'static> for Sv1Server { Ok(()) } - fn notify(&'_ mut self, _client_id: Option) -> Result> { + fn notify(&'_ mut self, _client_id: Option) -> Result { warn!("notify() called on Sv1Server - this method is not implemented for Sv1Server"); Err( stratum_apps::stratum_core::sv1_api::error::Error::UnexpectedMessage( diff --git a/miner-apps/translator/src/lib/sv1/sv1_server/mod.rs b/miner-apps/translator/src/lib/sv1/sv1_server/mod.rs index e19cf1b8d..3fa4842e5 100644 --- a/miner-apps/translator/src/lib/sv1/sv1_server/mod.rs +++ b/miner-apps/translator/src/lib/sv1/sv1_server/mod.rs @@ -15,6 +15,11 @@ //! maintaining state for multiple downstream connections and ensuring seamless translation //! between SV1 and SV2 protocols. +use stratum_apps::stratum_core::{ + binary_sv2::Str0255Owned, + mining_sv2::{CloseChannelOwned, SetNewPrevHashOwned, SetTargetOwned}, + parsers_sv2::MiningOwned, +}; mod difficulty_manager; pub mod downstream_message_handler; @@ -46,15 +51,13 @@ use stratum_apps::{ fallback_coordinator::FallbackCoordinator, network_helpers::sv1_connection::ConnectionSV1, stratum_core::{ - binary_sv2::Str0255, bitcoin::Target, channels_sv2::{ target::{hash_rate_from_target, hash_rate_to_target}, Vardiff, VardiffState, }, extensions_sv2::UserIdentity, - mining_sv2::{CloseChannel, SetNewPrevHash, SetTarget}, - parsers_sv2::{Mining, Tlv, TlvField}, + parsers_sv2::{Tlv, TlvField}, stratum_translation::{ sv1_to_sv2::{ build_sv2_open_extended_mining_channel, @@ -81,15 +84,15 @@ struct Sv1ServerIo { sv1_server_to_downstream_sender: Arc>>>, downstream_to_sv1_server_sender: Sender<(DownstreamId, json_rpc::Message)>, downstream_to_sv1_server_receiver: Receiver<(DownstreamId, json_rpc::Message)>, - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, - channel_manager_sender: Sender<(Mining<'static>, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, + channel_manager_sender: Sender<(MiningOwned, Option>)>, } #[cfg_attr(not(test), hotpath::measure_all)] impl Sv1ServerIo { fn new( - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, - channel_manager_sender: Sender<(Mining<'static>, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, + channel_manager_sender: Sender<(MiningOwned, Option>)>, ) -> Self { let (downstream_to_sv1_server_sender, downstream_to_sv1_server_receiver) = unbounded(); @@ -146,12 +149,12 @@ pub struct Sv1Server { pub(crate) vardiff: Arc>>>, /// HashMap to store the SetNewPrevHash for each channel /// Used in both aggregated and non-aggregated mode - pub(crate) prevhashes: Arc>>, + pub(crate) prevhashes: Arc>, /// Tracks pending target updates that are waiting for SetTarget response from upstream pub(crate) pending_target_updates: Arc>>, /// Valid Sv1 jobs storage, containing only a single shared entry (AGGREGATED_CHANNEL_ID) in /// case of channels aggregation (aggregated mode) - pub(crate) valid_sv1_jobs: Arc>>>, + pub(crate) valid_sv1_jobs: Arc>>, pub(crate) mode: TproxyMode, user_identity: Arc>, } @@ -297,8 +300,8 @@ impl Sv1Server { /// A new Sv1Server instance ready to accept connections pub fn new( listener_addr: SocketAddr, - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, - channel_manager_sender: Sender<(Mining<'static>, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, + channel_manager_sender: Sender<(MiningOwned, Option>)>, config: TranslatorConfig, mode: TproxyMode, ) -> Self { @@ -696,7 +699,7 @@ impl Sv1Server { self.sv1_server_io .channel_manager_sender .send(( - Mining::SubmitSharesExtended(submit_share_extended), + MiningOwned::SubmitSharesExtended(submit_share_extended), tlv_fields, )) .await @@ -762,7 +765,7 @@ impl Sv1Server { .map_err(TproxyError::shutdown)?; match message { - Mining::OpenExtendedMiningChannelSuccess(m) => { + MiningOwned::OpenExtendedMiningChannelSuccess(m) => { debug!( "Received OpenExtendedMiningChannelSuccess for channel id: {}", m.channel_id @@ -879,7 +882,7 @@ impl Sv1Server { } } - Mining::NewExtendedMiningJob(m) => { + MiningOwned::NewExtendedMiningJob(m) => { debug!( "Received NewExtendedMiningJob for channel id: {}", m.channel_id @@ -890,11 +893,9 @@ impl Sv1Server { .get(&m.channel_id) .map(|r| r.value().clone()) { - let prevhash = prevhash.as_static(); let clean_jobs = m.job_id == prevhash.job_id; - let notify = - build_sv1_notify_from_sv2(prevhash, m.clone().into_static(), clean_jobs) - .map_err(TproxyError::shutdown)?; + let notify = build_sv1_notify_from_sv2(prevhash, m.clone(), clean_jobs) + .map_err(TproxyError::shutdown)?; // Update job storage based on the configured mode let notify_parsed = notify.clone(); @@ -919,13 +920,12 @@ impl Sv1Server { } } - Mining::SetNewPrevHash(m) => { + MiningOwned::SetNewPrevHash(m) => { debug!("Received SetNewPrevHash for channel id: {}", m.channel_id); - self.prevhashes - .insert(m.channel_id, m.clone().into_static()); + self.prevhashes.insert(m.channel_id, m.clone()); } - Mining::SetTarget(m) => { + MiningOwned::SetTarget(m) => { debug!("Received SetTarget for channel id: {}", m.channel_id); if self.config.downstream_difficulty_config.enable_vardiff { // Vardiff enabled - use full difficulty management @@ -1014,7 +1014,10 @@ impl Sv1Server { ) { self.sv1_server_io .channel_manager_sender - .send((Mining::OpenExtendedMiningChannel(open_channel_msg), None)) + .send(( + MiningOwned::OpenExtendedMiningChannel(open_channel_msg), + None, + )) .await .map_err(|_| TproxyError::shutdown(TproxyErrorKind::ChannelErrorSender))?; } else { @@ -1068,12 +1071,13 @@ impl Sv1Server { // in aggregated mode the upstream channel is shared across // all downstreams and must stay open. info!("Sending CloseChannel message: {channel_id} for downstream: {downstream_id}"); - let reason_code = Str0255::try_from("downstream disconnected".to_string()).unwrap(); + let reason_code = + Str0255Owned::try_from("downstream disconnected".to_string()).unwrap(); _ = self .sv1_server_io .channel_manager_sender .send(( - Mining::CloseChannel(CloseChannel { + MiningOwned::CloseChannel(CloseChannelOwned { channel_id, reason_code, }), @@ -1095,7 +1099,7 @@ impl Sv1Server { /// meaningful SV1 downstream hashrate values. async fn handle_set_target_without_vardiff( &self, - set_target: SetTarget<'_>, + set_target: SetTargetOwned, ) -> TproxyResult<(), error::Sv1Server> { let new_target = Target::from_le_bytes(set_target.maximum_target.to_array()); debug!( @@ -1105,7 +1109,7 @@ impl Sv1Server { // Derive hashrate from the upstream target so monitoring can report it let derived_hashrate = match hash_rate_from_target( - set_target.maximum_target.clone().into_static(), + set_target.maximum_target.clone(), self.shares_per_minute as f64, ) { Ok(hr) => { @@ -1225,11 +1229,12 @@ impl Sv1Server { channel_id ); info!("Sending CloseChannel message: Channel id {channel_id}"); - let reason_code = Str0255::try_from("downstream disconnected".to_string()).unwrap(); + let reason_code = + Str0255Owned::try_from("downstream disconnected".to_string()).unwrap(); self.sv1_server_io .channel_manager_sender .send(( - Mining::CloseChannel(CloseChannel { + MiningOwned::CloseChannel(CloseChannelOwned { channel_id, reason_code, }), @@ -1451,7 +1456,7 @@ impl Sv1Server { /// Gets the last job from the jobs storage. /// In aggregated mode, returns the last job from the shared job list. /// In non-aggregated mode, returns the last job for the specified channel. - fn get_last_job(&self, channel_id: Option) -> Option> { + fn get_last_job(&self, channel_id: Option) -> Option { let channel_id = if self.mode.is_aggregated() { AGGREGATED_CHANNEL_ID } else { @@ -1469,7 +1474,7 @@ impl Sv1Server { &self, job_id: &str, channel_id: Option, - ) -> Option> { + ) -> Option { let channel_id = if self.mode.is_aggregated() { AGGREGATED_CHANNEL_ID } else { @@ -1599,7 +1604,7 @@ mod tests { let server = Sv1Server::new(addr, cm_receiver, cm_sender, config, tproxy_mode); let target: Target = hash_rate_to_target(200.0, 5.0).unwrap(); - let set_target = SetTarget { + let set_target = SetTargetOwned { channel_id: 1, maximum_target: target.to_le_bytes().into(), }; @@ -1620,7 +1625,7 @@ mod tests { let server = Sv1Server::new(addr, cm_receiver, cm_sender, config, tproxy_mode); let target: Target = hash_rate_to_target(200.0, 5.0).unwrap(); - let set_target = SetTarget { + let set_target = SetTargetOwned { channel_id: 1, maximum_target: target.to_le_bytes().into(), }; diff --git a/miner-apps/translator/src/lib/sv2/channel_manager/extensions_message_handler.rs b/miner-apps/translator/src/lib/sv2/channel_manager/extensions_message_handler.rs index 3b9188713..af9cc31d7 100644 --- a/miner-apps/translator/src/lib/sv2/channel_manager/extensions_message_handler.rs +++ b/miner-apps/translator/src/lib/sv2/channel_manager/extensions_message_handler.rs @@ -4,17 +4,19 @@ use crate::{ }; use stratum_apps::{ stratum_core::{ - binary_sv2::Seq064K, - extensions_sv2::{RequestExtensions, RequestExtensionsError, RequestExtensionsSuccess}, - handlers_sv2::HandleExtensionsFromServerAsync, - parsers_sv2::{AnyMessage, Tlv}, + binary_sv2::Seq064KOwned, + extensions_sv2::{ + RequestExtensionsErrorOwned, RequestExtensionsOwned, RequestExtensionsSuccessOwned, + }, + handlers_sv2::HandleExtensionsFromServerOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::{error, info}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleExtensionsFromServerAsync for ChannelManager { +impl HandleExtensionsFromServerOwnedAsync for ChannelManager { type Error = TproxyError; fn get_negotiated_extensions_with_server( @@ -29,7 +31,7 @@ impl HandleExtensionsFromServerAsync for ChannelManager { async fn handle_request_extensions_success( &mut self, _server_id: Option, - msg: RequestExtensionsSuccess<'_>, + msg: RequestExtensionsSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let supported: Vec = msg.supported_extensions.into_inner(); @@ -67,7 +69,7 @@ impl HandleExtensionsFromServerAsync for ChannelManager { async fn handle_request_extensions_error( &mut self, _server_id: Option, - msg: RequestExtensionsError<'_>, + msg: RequestExtensionsErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let unsupported: Vec = msg.unsupported_extensions.into_inner(); @@ -128,15 +130,14 @@ impl HandleExtensionsFromServerAsync for ChannelManager { can_support ); - let new_require_extensions = RequestExtensions { + let new_require_extensions = RequestExtensionsOwned { request_id: msg.request_id + 1, - requested_extensions: Seq064K::new(can_support).unwrap(), + requested_extensions: Seq064KOwned::new(can_support).unwrap(), }; - let sv2_frame: Sv2Frame = - AnyMessage::Extensions(new_require_extensions.into_static().into()) - .try_into() - .map_err(TproxyError::shutdown)?; + let sv2_frame: Sv2Frame = AnyMessageOwned::Extensions(new_require_extensions.into()) + .try_into() + .map_err(TproxyError::shutdown)?; self.channel_manager_io .upstream_sender diff --git a/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs b/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs index d3d255b7d..c89ccf247 100644 --- a/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs +++ b/miner-apps/translator/src/lib/sv2/channel_manager/mining_message_handler.rs @@ -13,23 +13,24 @@ use stratum_apps::{ client::{extended::ExtendedChannel, group::GroupChannel}, extranonce_manager::{bytes_needed, ExtranonceAllocator, ExtranoncePrefix}, }, - handlers_sv2::{HandleMiningMessagesFromServerAsync, SupportedChannelTypes}, + handlers_sv2::{HandleMiningMessagesFromServerOwnedAsync, SupportedChannelTypes}, mining_sv2::{ - CloseChannel, NewExtendedMiningJob, NewMiningJob, OpenExtendedMiningChannelSuccess, - OpenMiningChannelError, OpenStandardMiningChannelSuccess, SetCustomMiningJobError, - SetCustomMiningJobSuccess, SetExtranoncePrefix, SetGroupChannel, SetNewPrevHash, - SetTarget, SubmitSharesError, SubmitSharesSuccess, UpdateChannelError, - MESSAGE_TYPE_OPEN_STANDARD_MINING_CHANNEL_SUCCESS, + CloseChannelOwned, NewExtendedMiningJobOwned, NewMiningJobOwned, + OpenExtendedMiningChannelSuccessOwned, OpenMiningChannelErrorOwned, + OpenStandardMiningChannelSuccessOwned, SetCustomMiningJobErrorOwned, + SetCustomMiningJobSuccessOwned, SetExtranoncePrefixOwned, SetGroupChannelOwned, + SetNewPrevHashOwned, SetTargetOwned, SubmitSharesErrorOwned, SubmitSharesSuccessOwned, + UpdateChannelErrorOwned, MESSAGE_TYPE_OPEN_STANDARD_MINING_CHANNEL_SUCCESS, MESSAGE_TYPE_SET_CUSTOM_MINING_JOB_ERROR, MESSAGE_TYPE_SET_CUSTOM_MINING_JOB_SUCCESS, }, - parsers_sv2::{Mining, Tlv}, + parsers_sv2::{MiningOwned, Tlv}, }, utils::types::{DownstreamId, Hashrate}, }; use tracing::{error, info, warn}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleMiningMessagesFromServerAsync for ChannelManager { +impl HandleMiningMessagesFromServerOwnedAsync for ChannelManager { type Error = TproxyError; fn get_channel_type_for_server(&self, _server_id: Option) -> SupportedChannelTypes { @@ -52,10 +53,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_open_standard_mining_channel_success( &mut self, _server_id: Option, - m: OpenStandardMiningChannelSuccess<'_>, + m: OpenStandardMiningChannelSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); Err(TproxyError::log(TproxyErrorKind::UnexpectedMessage( 0, MESSAGE_TYPE_OPEN_STANDARD_MINING_CHANNEL_SUCCESS, @@ -65,7 +66,7 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_open_extended_mining_channel_success( &mut self, _server_id: Option, - m: OpenExtendedMiningChannelSuccess<'_>, + m: OpenExtendedMiningChannelSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { // Retrieve the pending channel request data. @@ -82,7 +83,7 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { let success = { info!( - "Received: {}, user_identity: {}, nominal_hashrate: {}", + "Received: {:?}, user_identity: {}, nominal_hashrate: {}", m, user_identity, nominal_hashrate ); @@ -218,18 +219,19 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { self.aggregated_channel_state .set(AggregatedState::Connected); - let new_open_extended_mining_channel_success = OpenExtendedMiningChannelSuccess { - request_id: m.request_id, - channel_id: 1, - extranonce_prefix: downstream_extranonce_prefix_bytes - .try_into() - .map_err(TproxyError::shutdown)?, - extranonce_size: downstream_extranonce_len as u16, - target: m.target.clone(), - group_channel_id: m.group_channel_id, - }; - Ok::, Self::Error>( - new_open_extended_mining_channel_success.into_static(), + let new_open_extended_mining_channel_success = + OpenExtendedMiningChannelSuccessOwned { + request_id: m.request_id, + channel_id: 1, + extranonce_prefix: downstream_extranonce_prefix_bytes + .try_into() + .map_err(TproxyError::shutdown)?, + extranonce_size: downstream_extranonce_len as u16, + target: m.target.clone(), + group_channel_id: m.group_channel_id, + }; + Ok::( + new_open_extended_mining_channel_success, ) } else { // Non-aggregated: we asked upstream for exactly @@ -341,18 +343,19 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { self.extended_channels .insert(m.channel_id, new_downstream_extended_channel); - let new_open_extended_mining_channel_success = OpenExtendedMiningChannelSuccess { - request_id: m.request_id, - channel_id: m.channel_id, - extranonce_prefix: downstream_prefix_bytes_for_success - .try_into() - .map_err(TproxyError::shutdown)?, - extranonce_size: downstream_extranonce_len as u16, - target: m.target.clone(), - group_channel_id: m.group_channel_id, - }; - Ok::, Self::Error>( - new_open_extended_mining_channel_success.into_static(), + let new_open_extended_mining_channel_success = + OpenExtendedMiningChannelSuccessOwned { + request_id: m.request_id, + channel_id: m.channel_id, + extranonce_prefix: downstream_prefix_bytes_for_success + .try_into() + .map_err(TproxyError::shutdown)?, + extranonce_size: downstream_extranonce_len as u16, + target: m.target.clone(), + group_channel_id: m.group_channel_id, + }; + Ok::( + new_open_extended_mining_channel_success, ) } }?; @@ -360,7 +363,7 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { self.channel_manager_io .sv1_server_sender .send(( - Mining::OpenExtendedMiningChannelSuccess(success.clone()), + MiningOwned::OpenExtendedMiningChannelSuccess(success.clone()), None, )) .await @@ -403,10 +406,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_open_mining_channel_error( &mut self, _server_id: Option, - m: OpenMiningChannelError<'_>, + m: OpenMiningChannelErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); Err(TproxyError::fallback( TproxyErrorKind::OpenMiningChannelError, )) @@ -415,20 +418,20 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_update_channel_error( &mut self, _server_id: Option, - m: UpdateChannelError<'_>, + m: UpdateChannelErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); Ok(()) } async fn handle_close_channel( &mut self, _server_id: Option, - m: CloseChannel<'_>, + m: CloseChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", m); + info!("Received: {:?}", m); // are we working in aggregated mode? if self.mode.is_aggregated() { // even if aggregated channel_id != m.channel_id, we should trigger fallback @@ -473,10 +476,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_extranonce_prefix( &mut self, _server_id: Option, - m: SetExtranoncePrefix<'_>, + m: SetExtranoncePrefixOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); warn!("⚠️ Cannot process SetExtranoncePrefix since set_extranonce is not supported for majority of sv1 clients. Ignoring."); Ok(()) } @@ -484,10 +487,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_submit_shares_success( &mut self, _server_id: Option, - m: SubmitSharesSuccess, + m: SubmitSharesSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {} ✅", m); + info!("Received: {:?} ✅", m); // In aggregated mode, the Pool responds with the upstream channel ID, but the // channel is stored under AGGREGATED_CHANNEL_ID in the DashMap. @@ -509,10 +512,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_submit_shares_error( &mut self, _server_id: Option, - m: SubmitSharesError<'_>, + m: SubmitSharesErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {} ❌", m); + warn!("Received: {:?} ❌", m); let error_code = m.error_code.as_utf8_or_hex(); let key = if self.mode.is_aggregated() { @@ -532,10 +535,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_new_mining_job( &mut self, _server_id: Option, - m: NewMiningJob<'_>, + m: NewMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); warn!("⚠️ Cannot process NewMiningJob since Translator Proxy supports only extended mining jobs. Ignoring."); Ok(()) } @@ -543,11 +546,11 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_new_extended_mining_job( &mut self, _server_id: Option, - m: NewExtendedMiningJob<'_>, + m: NewExtendedMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", m); - let m_static = m.clone().into_static(); + info!("Received: {:?}", m); + let m_static = m.clone(); // we update the channel states and keep track of the messages that need to be sent to the // SV1Server @@ -680,14 +683,14 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { new_extended_mining_job_messages.push(new_extended_mining_job_message); } } - Ok::>, Self::Error>(new_extended_mining_job_messages) + Ok::, Self::Error>(new_extended_mining_job_messages) }?; // now we need to send the NewExtendedMiningJob message(s) to the SV1Server for message in new_extended_mining_job_messages_sv1_server { self.channel_manager_io .sv1_server_sender - .send((Mining::NewExtendedMiningJob(message), None)) + .send((MiningOwned::NewExtendedMiningJob(message), None)) .await .map_err(|e| { error!("Failed to send immediate NewExtendedMiningJob: {:?}", e); @@ -700,11 +703,11 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_new_prev_hash( &mut self, _server_id: Option, - m: SetNewPrevHash<'_>, + m: SetNewPrevHashOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", m); - let mut m_static = m.clone().into_static(); + info!("Received: {:?}", m); + let mut m_static = m.clone(); // we update the channel states and keep track of the messages that need to be sent to the // SV1Server @@ -845,20 +848,17 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { .clone(); new_extended_mining_job_messages.push(new_extended_mining_job_message.0); } - Ok::< - ( - Vec>, - Vec>, - ), - Self::Error, - >((set_new_prev_hash_messages, new_extended_mining_job_messages)) + Ok::<(Vec, Vec), Self::Error>(( + set_new_prev_hash_messages, + new_extended_mining_job_messages, + )) }?; // we need to send the SetNewPrevHash message(s) to the SV1Server for message in set_new_prev_hash_messages_sv1_server { self.channel_manager_io .sv1_server_sender - .send((Mining::SetNewPrevHash(message), None)) + .send((MiningOwned::SetNewPrevHash(message), None)) .await .map_err(|e| { error!("Failed to send SetNewPrevHash: {:?}", e); @@ -870,7 +870,7 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { for message in new_extended_mining_job_messages_sv1_server { self.channel_manager_io .sv1_server_sender - .send((Mining::NewExtendedMiningJob(message), None)) + .send((MiningOwned::NewExtendedMiningJob(message), None)) .await .map_err(|e| { error!("Failed to send NewExtendedMiningJob: {:?}", e); @@ -884,10 +884,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_custom_mining_job_success( &mut self, _server_id: Option, - m: SetCustomMiningJobSuccess, + m: SetCustomMiningJobSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); warn!("⚠️ Cannot process SetCustomMiningJobSuccess since Translator Proxy does not support custom mining jobs. Ignoring."); Err(TproxyError::log(TproxyErrorKind::UnexpectedMessage( 0, @@ -898,10 +898,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_custom_mining_job_error( &mut self, _server_id: Option, - m: SetCustomMiningJobError<'_>, + m: SetCustomMiningJobErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", m); + warn!("Received: {:?}", m); warn!("⚠️ Cannot process SetCustomMiningJobError since Translator Proxy does not support custom mining jobs. Ignoring."); Err(TproxyError::log(TproxyErrorKind::UnexpectedMessage( 0, @@ -912,12 +912,12 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_target( &mut self, _server_id: Option, - m: SetTarget<'_>, + m: SetTargetOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", m); + info!("Received: {:?}", m); - let m_static = m.clone().into_static(); + let m_static = m.clone(); // Update the channel targets in the channel manager let set_target_messages_sv1_server = { @@ -996,14 +996,14 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { set_target_messages.push(m_static.clone()); } - Ok::>, Self::Error>(set_target_messages) + Ok::, Self::Error>(set_target_messages) }?; // now we need to send the SetTarget message(s) to the SV1Server for message in set_target_messages_sv1_server { self.channel_manager_io .sv1_server_sender - .send((Mining::SetTarget(message), None)) + .send((MiningOwned::SetTarget(message), None)) .await .map_err(|e| { error!("Failed to send SetTarget: {:?}", e); @@ -1017,10 +1017,10 @@ impl HandleMiningMessagesFromServerAsync for ChannelManager { async fn handle_set_group_channel( &mut self, _server_id: Option, - m: SetGroupChannel<'_>, + m: SetGroupChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", m); + info!("Received: {:?}", m); // remove every channel from any group channels that end up empty let mut group_channels_to_remove = Vec::new(); @@ -1115,7 +1115,7 @@ impl ChannelManager { #[allow(clippy::result_large_err)] fn verify_payout_distribution( &self, - job: &NewExtendedMiningJob<'_>, + job: &NewExtendedMiningJobOwned, full_extranonce_size: usize, ) -> Result<(), TproxyError> { if let Some(expected_payout_distribution) = self.expected_payout_distribution() { diff --git a/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs b/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs index 7fee33296..a608b6a02 100644 --- a/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs +++ b/miner-apps/translator/src/lib/sv2/channel_manager/mod.rs @@ -1,3 +1,7 @@ +use stratum_apps::stratum_core::{ + mining_sv2::OpenExtendedMiningChannelSuccessOwned, + parsers_sv2::{AnyMessageOwned, MiningOwned}, +}; mod extensions_message_handler; mod mining_message_handler; @@ -22,9 +26,10 @@ use stratum_apps::{ codec_sv2::StandardSv2Frame, extensions_sv2::{EXTENSION_TYPE_WORKER_HASHRATE_TRACKING, TLV_FIELD_TYPE_USER_IDENTITY}, framing_sv2, - handlers_sv2::{HandleExtensionsFromServerAsync, HandleMiningMessagesFromServerAsync}, - mining_sv2::OpenExtendedMiningChannelSuccess, - parsers_sv2::{AnyMessage, Mining, Tlv, TlvList}, + handlers_sv2::{ + HandleExtensionsFromServerOwnedAsync, HandleMiningMessagesFromServerOwnedAsync, + }, + parsers_sv2::{Tlv, TlvList}, }, task_manager::TaskManager, utils::{ @@ -69,8 +74,8 @@ pub(crate) const NON_AGGREGATED_TPROXY_MAX_CHANNELS: u32 = 1; struct ChannelManagerIo { upstream_sender: Sender, upstream_receiver: Receiver, - sv1_server_sender: Sender<(Mining<'static>, Option>)>, - sv1_server_receiver: Receiver<(Mining<'static>, Option>)>, + sv1_server_sender: Sender<(MiningOwned, Option>)>, + sv1_server_receiver: Receiver<(MiningOwned, Option>)>, } #[cfg_attr(not(test), hotpath::measure_all)] @@ -78,8 +83,8 @@ impl ChannelManagerIo { fn new( upstream_sender: Sender, upstream_receiver: Receiver, - sv1_server_sender: Sender<(Mining<'static>, Option>)>, - sv1_server_receiver: Receiver<(Mining<'static>, Option>)>, + sv1_server_sender: Sender<(MiningOwned, Option>)>, + sv1_server_receiver: Receiver<(MiningOwned, Option>)>, ) -> Self { Self { upstream_sender, @@ -147,9 +152,9 @@ pub struct ChannelManager { /// Map of active extended channels by channel ID. /// In aggregated mode, the shared upstream channel is stored under AGGREGATED_CHANNEL_ID. /// In non-aggregated mode, each downstream has its own channel with its assigned ID. - pub extended_channels: Arc>>, + pub extended_channels: Arc>, /// Map of active group channels by group channel ID - pub group_channels: Arc>>, + pub group_channels: Arc>, /// Share sequence number counter for tracking valid shares forwarded upstream. /// In aggregated mode: single counter for all shares going to the upstream channel. /// In non-aggregated mode: one counter per downstream channel. @@ -278,8 +283,8 @@ impl ChannelManager { pub fn new( upstream_sender: Sender, upstream_receiver: Receiver, - sv1_server_sender: Sender<(Mining<'static>, Option>)>, - sv1_server_receiver: Receiver<(Mining<'static>, Option>)>, + sv1_server_sender: Sender<(MiningOwned, Option>)>, + sv1_server_receiver: Receiver<(MiningOwned, Option>)>, supported_extensions: Vec, required_extensions: Vec, tproxy_mode: TproxyMode, @@ -470,7 +475,7 @@ impl ChannelManager { .await .map_err(TproxyError::shutdown)?; match message { - Mining::OpenExtendedMiningChannel(m) => { + MiningOwned::OpenExtendedMiningChannel(m) => { let mut open_channel_msg = m.clone(); let mut user_identity = m.user_identity.as_utf8_or_hex(); let hashrate = m.nominal_hash_rate; @@ -547,12 +552,12 @@ impl ChannelManager { } info!( - "Sending OpenExtendedMiningChannel message to upstream: {}", + "Sending OpenExtendedMiningChannel message to upstream: {:?}", open_channel_msg ); - let message = Mining::OpenExtendedMiningChannel(open_channel_msg); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message) + let message = MiningOwned::OpenExtendedMiningChannel(open_channel_msg); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message) .try_into() .map_err(TproxyError::shutdown)?; self.channel_manager_io @@ -564,7 +569,7 @@ impl ChannelManager { TproxyError::fallback(TproxyErrorKind::ChannelErrorSender) })?; } - Mining::SubmitSharesExtended(mut m) => { + MiningOwned::SubmitSharesExtended(mut m) => { if self.mode.is_aggregated() && self.extended_channels.contains_key(&AGGREGATED_CHANNEL_ID) { @@ -691,7 +696,9 @@ impl ChannelManager { TproxyError::shutdown(e) })?; let frame_bytes = tlv_list - .build_frame_bytes_with_tlvs(Mining::SubmitSharesExtended(m.clone())) + .build_frame_bytes_with_tlvs(MiningOwned::SubmitSharesExtended( + m.clone(), + )) .map_err(|e| { error!("Failed to build frame bytes with TLVs: {:?}", e); TproxyError::shutdown(e) @@ -722,8 +729,8 @@ impl ChannelManager { } if !sent { - let message = Mining::SubmitSharesExtended(m); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message) + let message = MiningOwned::SubmitSharesExtended(m); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message) .try_into() .map_err(TproxyError::shutdown)?; self.channel_manager_io @@ -739,8 +746,8 @@ impl ChannelManager { })?; } } - Mining::UpdateChannel(mut m) => { - debug!("Received UpdateChannel from SV1Server: {}", m); + MiningOwned::UpdateChannel(mut m) => { + debug!("Received UpdateChannel from SV1Server: {:?}", m); if self.mode.is_aggregated() { // Update the aggregated channel's nominal hashrate so @@ -753,7 +760,7 @@ impl ChannelManager { m.channel_id = aggregated_extended_channel.get_channel_id(); } else { warn!( - "Ignoring aggregated UpdateChannel before upstream channel is open: {}", + "Ignoring aggregated UpdateChannel before upstream channel is open: {:?}", m ); return Ok(()); @@ -770,8 +777,8 @@ impl ChannelManager { m.channel_id ); // Forward UpdateChannel message to upstream - let message = Mining::UpdateChannel(m); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message) + let message = MiningOwned::UpdateChannel(m); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message) .try_into() .map_err(TproxyError::shutdown)?; @@ -784,8 +791,8 @@ impl ChannelManager { TproxyError::fallback(TproxyErrorKind::ChannelErrorSender) })?; } - Mining::CloseChannel(m) => { - debug!("Received CloseChannel from Sv1Server: {m}"); + MiningOwned::CloseChannel(m) => { + debug!("Received CloseChannel from Sv1Server: {m:?}"); // Guard: never remove the aggregated upstream sentinel entry // here. `AGGREGATED_CHANNEL_ID` represents the single shared @@ -829,8 +836,8 @@ impl ChannelManager { // across all SV1 miners and must stay open when any one of // them disconnects. if !self.mode.is_aggregated() { - let message = Mining::CloseChannel(m); - let sv2_frame: Sv2Frame = AnyMessage::Mining(message) + let message = MiningOwned::CloseChannel(m); + let sv2_frame: Sv2Frame = AnyMessageOwned::Mining(message) .try_into() .map_err(TproxyError::shutdown)?; @@ -914,8 +921,8 @@ impl ChannelManager { ); self.extended_channels .insert(next_channel_id, new_downstream_extended_channel); - let success_message = - Mining::OpenExtendedMiningChannelSuccess(OpenExtendedMiningChannelSuccess { + let success_message = MiningOwned::OpenExtendedMiningChannelSuccess( + OpenExtendedMiningChannelSuccessOwned { request_id, channel_id: next_channel_id, target: target.to_le_bytes().into(), @@ -926,7 +933,8 @@ impl ChannelManager { group_channel_id: 0, /* use a dummy value, this * shouldn't * matter for the Sv1 server */ - }); + }, + ); self.channel_manager_io .sv1_server_sender @@ -986,7 +994,7 @@ impl ChannelManager { if let Some(job) = active_job_for_sv1_server() { self.channel_manager_io .sv1_server_sender - .send((Mining::NewExtendedMiningJob(job), None)) + .send((MiningOwned::NewExtendedMiningJob(job), None)) .await .map_err(|e| { error!( @@ -1020,7 +1028,7 @@ mod tests { use super::*; use async_channel::unbounded; use stratum_apps::stratum_core::mining_sv2::{ - OpenExtendedMiningChannel, SubmitSharesExtended, UpdateChannel, + OpenExtendedMiningChannelOwned, SubmitSharesExtendedOwned, UpdateChannelOwned, }; fn create_test_channel_manager() -> ChannelManager { @@ -1047,7 +1055,7 @@ mod tests { let manager = create_test_channel_manager(); // Create an OpenExtendedMiningChannel message - let open_channel = OpenExtendedMiningChannel { + let open_channel = OpenExtendedMiningChannelOwned { request_id: 1, user_identity: "test_user".try_into().unwrap(), nominal_hash_rate: 1000.0, @@ -1063,11 +1071,11 @@ mod tests { // Test that the message can be handled without panicking // In a real test environment, we would need to mock the upstream sender // For now, we just verify the channel manager can process the message type - let mining_message = Mining::OpenExtendedMiningChannel(open_channel); + let mining_message = MiningOwned::OpenExtendedMiningChannel(open_channel); // Verify the message can be processed (would normally be sent to upstream) match mining_message { - Mining::OpenExtendedMiningChannel(msg) => { + MiningOwned::OpenExtendedMiningChannel(msg) => { assert_eq!(msg.request_id, 1); assert_eq!(msg.nominal_hash_rate, 1000.0); assert_eq!(msg.min_extranonce_size, 4); @@ -1081,7 +1089,7 @@ mod tests { let _manager = create_test_channel_manager(); // Create a SubmitSharesExtended message - let submit_shares = SubmitSharesExtended { + let submit_shares = SubmitSharesExtendedOwned { channel_id: 1, sequence_number: 100, job_id: 42, @@ -1092,11 +1100,11 @@ mod tests { }; // Test that the message can be handled - let mining_message = Mining::SubmitSharesExtended(submit_shares); + let mining_message = MiningOwned::SubmitSharesExtended(submit_shares); // Verify the message structure match mining_message { - Mining::SubmitSharesExtended(msg) => { + MiningOwned::SubmitSharesExtended(msg) => { assert_eq!(msg.channel_id, 1); assert_eq!(msg.sequence_number, 100); assert_eq!(msg.job_id, 42); @@ -1111,18 +1119,18 @@ mod tests { let _manager = create_test_channel_manager(); // Create an UpdateChannel message - let update_channel = UpdateChannel { + let update_channel = UpdateChannelOwned { channel_id: 1, nominal_hash_rate: 2000.0, maximum_target: [0xFFu8; 32].into(), }; // Test that the message can be handled - let mining_message = Mining::UpdateChannel(update_channel); + let mining_message = MiningOwned::UpdateChannel(update_channel); // Verify the message structure match mining_message { - Mining::UpdateChannel(msg) => { + MiningOwned::UpdateChannel(msg) => { assert_eq!(msg.channel_id, 1); assert_eq!(msg.nominal_hash_rate, 2000.0); } @@ -1149,14 +1157,14 @@ mod tests { true, )); - let update_channel = UpdateChannel { + let update_channel = UpdateChannelOwned { channel_id: 0, nominal_hash_rate: 0.0, maximum_target: [0xFFu8; 32].into(), }; sv1_server_sender_for_test - .send((Mining::UpdateChannel(update_channel), None)) + .send((MiningOwned::UpdateChannel(update_channel), None)) .await .unwrap(); diff --git a/miner-apps/translator/src/lib/sv2/upstream/common_message_handler.rs b/miner-apps/translator/src/lib/sv2/upstream/common_message_handler.rs index 7a89c211c..b8e98f6c1 100644 --- a/miner-apps/translator/src/lib/sv2/upstream/common_message_handler.rs +++ b/miner-apps/translator/src/lib/sv2/upstream/common_message_handler.rs @@ -4,15 +4,16 @@ use crate::{ }; use stratum_apps::stratum_core::{ common_messages_sv2::{ - ChannelEndpointChanged, Reconnect, SetupConnectionError, SetupConnectionSuccess, + ChannelEndpointChangedOwned, ReconnectOwned, SetupConnectionErrorOwned, + SetupConnectionSuccessOwned, }, - handlers_sv2::HandleCommonMessagesFromServerAsync, + handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, parsers_sv2::Tlv, }; use tracing::{error, info}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromServerAsync for Upstream { +impl HandleCommonMessagesFromServerOwnedAsync for Upstream { type Error = TproxyError; fn get_negotiated_extensions_with_server( @@ -25,40 +26,40 @@ impl HandleCommonMessagesFromServerAsync for Upstream { async fn handle_setup_connection_error( &mut self, _server_id: Option, - msg: SetupConnectionError<'_>, + msg: SetupConnectionErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - error!("Received: {}", msg); + error!("Received: {:?}", msg); Err(TproxyError::fallback(TproxyErrorKind::SetupConnectionError)) } async fn handle_setup_connection_success( &mut self, _server_id: Option, - msg: SetupConnectionSuccess, + msg: SetupConnectionSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_channel_endpoint_changed( &mut self, _server_id: Option, - msg: ChannelEndpointChanged, + msg: ChannelEndpointChangedOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); todo!() } async fn handle_reconnect( &mut self, _server_id: Option, - msg: Reconnect<'_>, + msg: ReconnectOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); todo!() } } diff --git a/miner-apps/translator/src/lib/sv2/upstream/mod.rs b/miner-apps/translator/src/lib/sv2/upstream/mod.rs index fb3e9873e..5c7bb0eda 100644 --- a/miner-apps/translator/src/lib/sv2/upstream/mod.rs +++ b/miner-apps/translator/src/lib/sv2/upstream/mod.rs @@ -1,3 +1,7 @@ +use stratum_apps::stratum_core::{ + binary_sv2::Seq064KOwned, common_messages_sv2::SetupConnectionOwned, + extensions_sv2::RequestExtensionsOwned, parsers_sv2::AnyMessageOwned, +}; pub mod common_message_handler; use crate::{ @@ -12,11 +16,7 @@ use stratum_apps::{ fallback_coordinator::FallbackCoordinator, network_helpers::{self, connect_with_noise, resolve_host, TCP_CONNECT_TIMEOUT}, stratum_core::{ - binary_sv2::Seq064K, - common_messages_sv2::{Protocol, SetupConnection}, - extensions_sv2::RequestExtensions, - handlers_sv2::HandleCommonMessagesFromServerAsync, - parsers_sv2::AnyMessage, + common_messages_sv2::Protocol, handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, }, task_manager::TaskManager, utils::{ @@ -370,21 +370,20 @@ impl Upstream { // Send RequestExtensions message if there are any required extensions if !self.required_extensions.is_empty() { - let require_extensions = RequestExtensions { + let require_extensions = RequestExtensionsOwned { request_id: 1, - requested_extensions: Seq064K::new(self.required_extensions.clone()) + requested_extensions: Seq064KOwned::new(self.required_extensions.clone()) .map_err(TproxyError::shutdown)?, }; info!( - "Sending RequestExtensions message to upstream: {}", + "Sending RequestExtensions message to upstream: {:?}", require_extensions ); - let sv2_frame: Sv2Frame = - AnyMessage::Extensions(require_extensions.into_static().into()) - .try_into() - .map_err(TproxyError::shutdown)?; + let sv2_frame: Sv2Frame = AnyMessageOwned::Extensions(require_extensions.into()) + .try_into() + .map_err(TproxyError::shutdown)?; self.upstream_io .upstream_sender @@ -551,7 +550,7 @@ impl Upstream { max_version: u16, address: &SocketAddr, is_work_selection_enabled: bool, - ) -> Result, TproxyErrorKind> { + ) -> Result { let endpoint_host = address.ip().to_string().try_into()?; let vendor = "SRI".try_into()?; let hardware_version = "Translator Proxy".try_into()?; @@ -563,7 +562,7 @@ impl Upstream { 0b100 }; - Ok(SetupConnection { + Ok(SetupConnectionOwned { protocol: Protocol::MiningProtocol, min_version, max_version, diff --git a/miner-apps/translator/src/lib/utils.rs b/miner-apps/translator/src/lib/utils.rs index df565fec2..2a82ddb79 100644 --- a/miner-apps/translator/src/lib/utils.rs +++ b/miner-apps/translator/src/lib/utils.rs @@ -2,11 +2,11 @@ use std::sync::{ atomic::{AtomicU8, Ordering}, Arc, }; +use stratum_apps::stratum_core::binary_sv2::U256Owned; use stratum_apps::{ key_utils::Secp256k1PublicKey, stratum_core::{ - binary_sv2::U256, bitcoin::{ block::{Header, Version}, hashes::Hash, @@ -57,11 +57,11 @@ pub const AGGREGATED_CHANNEL_ID: ChannelId = u32::MAX; /// * `Ok(false)` if the share is valid but doesn't meet the target /// * `Err(TproxyError)` if validation fails due to missing job or invalid data pub fn validate_sv1_share( - share: &client_to_server::Submit<'static>, + share: &client_to_server::Submit, target: Target, extranonce1: Vec, version_rolling_mask: Option, - job: Notify<'static>, + job: Notify, ) -> Result { let mut full_extranonce = vec![]; full_extranonce.extend_from_slice(extranonce1.as_slice()); @@ -75,7 +75,7 @@ pub fn validate_sv1_share( let mask = version_rolling_mask.unwrap_or(HexU32Be(0x1FFFE000_u32)).0; let version = (job.version.0 & !mask) | (share_version & mask); - let prev_hash: U256<'static> = Vec::::from(job.prev_hash.clone()) + let prev_hash: U256Owned = Vec::::from(job.prev_hash.clone()) .try_into() .map_err(TproxyErrorKind::BinarySv2)?; @@ -241,7 +241,7 @@ pub struct SubmitShareWithChannelId { /// The downstream connection ID that submitted this share pub downstream_id: DownstreamId, /// The actual SV1 share submission data - pub share: Submit<'static>, + pub share: Submit, /// The complete extranonce used for this share pub extranonce: Vec, /// The length of the extranonce2 field diff --git a/pool-apps/Cargo.lock b/pool-apps/Cargo.lock index 74b9938a0..6b8226835 100644 --- a/pool-apps/Cargo.lock +++ b/pool-apps/Cargo.lock @@ -272,8 +272,8 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", ] @@ -541,8 +541,8 @@ dependencies = [ [[package]] name = "channels_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -611,8 +611,8 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "codec_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -639,8 +639,8 @@ dependencies = [ [[package]] name = "common_messages_sv2" -version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "9.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -807,8 +807,8 @@ dependencies = [ [[package]] name = "derive_codec_sv2" -version = "1.1.3" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "2.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" [[package]] name = "digest" @@ -936,8 +936,8 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "extensions_sv2" -version = "0.2.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.3.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -997,8 +997,8 @@ dependencies = [ [[package]] name = "framing_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1132,8 +1132,8 @@ dependencies = [ [[package]] name = "handlers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -1533,8 +1533,8 @@ dependencies = [ [[package]] name = "job_declaration_sv2" -version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "10.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1653,8 +1653,8 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" -version = "11.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "12.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1694,7 +1694,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "1.4.2" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", "chacha20poly1305", @@ -1817,8 +1817,8 @@ dependencies = [ [[package]] name = "parsers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2477,8 +2477,8 @@ dependencies = [ [[package]] name = "stratum-core" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -2544,8 +2544,8 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "template_distribution_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] diff --git a/pool-apps/jd-server/src/lib/job_declarator/downstream/common_message_handler.rs b/pool-apps/jd-server/src/lib/job_declarator/downstream/common_message_handler.rs index 73d0365ad..e911a8032 100644 --- a/pool-apps/jd-server/src/lib/job_declarator/downstream/common_message_handler.rs +++ b/pool-apps/jd-server/src/lib/job_declarator/downstream/common_message_handler.rs @@ -6,19 +6,19 @@ use std::convert::TryInto; use stratum_apps::{ stratum_core::{ common_messages_sv2::{ - Protocol, SetupConnection, SetupConnectionError, SetupConnectionSuccess, + Protocol, SetupConnectionErrorOwned, SetupConnectionOwned, SetupConnectionSuccess, ERROR_CODE_SETUP_CONNECTION_MISSING_DECLARE_TX_DATA_FLAG, ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL, }, - handlers_sv2::HandleCommonMessagesFromClientAsync, - parsers_sv2::{AnyMessage, Tlv}, + handlers_sv2::HandleCommonMessagesFromClientOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::info; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromClientAsync for Downstream { +impl HandleCommonMessagesFromClientOwnedAsync for Downstream { type Error = JDSError; fn get_negotiated_extensions_with_client( @@ -33,7 +33,7 @@ impl HandleCommonMessagesFromClientAsync for Downstream { async fn handle_setup_connection( &mut self, client_id: Option, - msg: SetupConnection<'_>, + msg: SetupConnectionOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { info!( @@ -45,14 +45,14 @@ impl HandleCommonMessagesFromClientAsync for Downstream { if msg.protocol != Protocol::JobDeclarationProtocol { info!("Rejecting connection from {downstream_id}: SetupConnection asking for other protocols than mining protocol."); - let response = SetupConnectionError { + let response = SetupConnectionErrorOwned { flags: 0, error_code: ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL .to_string() .try_into() .expect("error code must be valid string"), }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(JDSError::shutdown)?; self.downstream_io @@ -77,14 +77,14 @@ impl HandleCommonMessagesFromClientAsync for Downstream { if !has_declare_tx_data { info!("Rejecting connection from {downstream_id}: SetupConnection missing DECLARE_TX_DATA flag."); - let response = SetupConnectionError { + let response = SetupConnectionErrorOwned { flags: 0, error_code: ERROR_CODE_SETUP_CONNECTION_MISSING_DECLARE_TX_DATA_FLAG .to_string() .try_into() .expect("error code must be valid string"), }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(JDSError::shutdown)?; self.downstream_io @@ -103,7 +103,7 @@ impl HandleCommonMessagesFromClientAsync for Downstream { used_version: 2, flags: 0, }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(JDSError::shutdown)?; self.downstream_io diff --git a/pool-apps/jd-server/src/lib/job_declarator/downstream/mod.rs b/pool-apps/jd-server/src/lib/job_declarator/downstream/mod.rs index 40cca2346..d23ba065d 100644 --- a/pool-apps/jd-server/src/lib/job_declarator/downstream/mod.rs +++ b/pool-apps/jd-server/src/lib/job_declarator/downstream/mod.rs @@ -26,9 +26,9 @@ use stratum_apps::{ stratum_core::{ common_messages_sv2::MESSAGE_TYPE_SETUP_CONNECTION, framing_sv2, - handlers_sv2::HandleCommonMessagesFromClientAsync, - job_declaration_sv2::DeclareMiningJob, - parsers_sv2::{parse_message_frame_with_tlvs, AnyMessage}, + handlers_sv2::HandleCommonMessagesFromClientOwnedAsync, + job_declaration_sv2::DeclareMiningJobOwned, + parsers_sv2::{parse_message_frame_with_tlvs, AnyMessageOwned}, }, task_manager::TaskManager, utils::{ @@ -43,7 +43,7 @@ mod common_message_handler; /// Data associated with a pending declare mining job. /// - Instant is the insertion timestamp /// - DeclareMiningJob is the declare mining job -pub type PendingDeclareMiningJob = (Instant, DeclareMiningJob<'static>); +pub type PendingDeclareMiningJob = (Instant, DeclareMiningJobOwned); /// Channel endpoints for a single downstream connection. #[derive(Clone)] @@ -319,7 +319,7 @@ impl Downstream { } }; - let message = AnyMessage::JobDeclaration(msg); + let message = AnyMessageOwned::JobDeclaration(msg); let std_frame: Sv2Frame = message .try_into() .map_err(|e| error::JDSError::disconnect(e, self.downstream_id))?; @@ -359,8 +359,8 @@ impl Downstream { ) .map_err(|e| error::JDSError::disconnect(e, self.downstream_id))?; - let jd_message = match any_message { - AnyMessage::JobDeclaration(msg) => msg, + let jd_message = match any_message.into_owned() { + AnyMessageOwned::JobDeclaration(msg) => msg, _ => { error!("Expected JobDeclaration message but got different type"); return Err(error::JDSError::disconnect( diff --git a/pool-apps/jd-server/src/lib/job_declarator/job_declaration_message_handler.rs b/pool-apps/jd-server/src/lib/job_declarator/job_declaration_message_handler.rs index f09f565fd..ab7ad8c70 100644 --- a/pool-apps/jd-server/src/lib/job_declarator/job_declaration_message_handler.rs +++ b/pool-apps/jd-server/src/lib/job_declarator/job_declaration_message_handler.rs @@ -7,22 +7,22 @@ use std::time::Instant; use stratum_apps::{ stratum_core::{ bitcoin::{consensus, hashes::Hash, Amount, TxOut, Wtxid}, - handlers_sv2::HandleJobDeclarationMessagesFromClientAsync, + handlers_sv2::HandleJobDeclarationMessagesFromClientOwnedAsync, job_declaration_sv2::{ - AllocateMiningJobToken, AllocateMiningJobTokenSuccess, DeclareMiningJob, - DeclareMiningJobError, DeclareMiningJobSuccess, ProvideMissingTransactions, - ProvideMissingTransactionsSuccess, PushSolution, - ERROR_CODE_DECLARE_MINING_JOB_INVALID_MINING_JOB_TOKEN, + AllocateMiningJobTokenOwned, AllocateMiningJobTokenSuccessOwned, + DeclareMiningJobErrorOwned, DeclareMiningJobOwned, DeclareMiningJobSuccessOwned, + ProvideMissingTransactionsOwned, ProvideMissingTransactionsSuccessOwned, + PushSolutionOwned, ERROR_CODE_DECLARE_MINING_JOB_INVALID_MINING_JOB_TOKEN, ERROR_CODE_DECLARE_MINING_JOB_MISSING_TXS, }, - parsers_sv2::{JobDeclaration, Tlv}, + parsers_sv2::{JobDeclarationOwned, Tlv}, }, utils::types::JdToken, }; use tracing::info; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { +impl HandleJobDeclarationMessagesFromClientOwnedAsync for JobDeclarator { type Error = JDSError; fn get_negotiated_extensions_with_client( @@ -44,10 +44,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { async fn handle_allocate_mining_job_token( &mut self, client_id: Option, - msg: AllocateMiningJobToken<'_>, + msg: AllocateMiningJobTokenOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); // Shutdown: client_id is always Some; None indicates a bug. let client_id = client_id.ok_or_else(|| JDSError::shutdown(error::JDSErrorKind::ClientNotFound(0)))?; @@ -64,7 +64,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { let serialized_coinbase_tx_outputs = consensus::serialize(&coinbase_tx_outputs); // response message - let allocate_mining_job_token_success = AllocateMiningJobTokenSuccess { + let allocate_mining_job_token_success = AllocateMiningJobTokenSuccessOwned { request_id: msg.request_id, mining_job_token: allocated_token .to_le_bytes() @@ -89,7 +89,9 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .clone(); client_sender .send(( - JobDeclaration::AllocateMiningJobTokenSuccess(allocate_mining_job_token_success), + JobDeclarationOwned::AllocateMiningJobTokenSuccess( + allocate_mining_job_token_success, + ), None, )) .await @@ -101,10 +103,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { async fn handle_declare_mining_job( &mut self, client_id: Option, - msg: DeclareMiningJob<'_>, + msg: DeclareMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); // Shutdown: client_id is always Some; None indicates a bug. let client_id = client_id.ok_or_else(|| JDSError::shutdown(error::JDSErrorKind::ClientNotFound(0)))?; @@ -126,7 +128,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { Ok(token_bytes) => u64::from_le_bytes(token_bytes), Err(_) => { // Send DeclareMiningJobError back to client - let error_message = DeclareMiningJobError { + let error_message = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: ERROR_CODE_DECLARE_MINING_JOB_INVALID_MINING_JOB_TOKEN .as_bytes() @@ -137,7 +139,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { }; client_sender - .send((JobDeclaration::DeclareMiningJobError(error_message), None)) + .send(( + JobDeclarationOwned::DeclareMiningJobError(error_message), + None, + )) .await .map_err(|e| error::JDSError::disconnect(e, client_id))?; @@ -148,7 +153,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { // was `DeclareMiningJob.mining_job_token` previously allocated for this client? if !self.token_manager.is_allocated(token, client_id) { // Send DeclareMiningJobError back to client - let error_message = DeclareMiningJobError { + let error_message = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: ERROR_CODE_DECLARE_MINING_JOB_INVALID_MINING_JOB_TOKEN .as_bytes() @@ -158,7 +163,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { error_details: Vec::new().try_into().unwrap(), }; client_sender - .send((JobDeclaration::DeclareMiningJobError(error_message), None)) + .send(( + JobDeclarationOwned::DeclareMiningJobError(error_message), + None, + )) .await .map_err(|e| error::JDSError::disconnect(e, client_id))?; @@ -175,7 +183,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { DeclareMiningJobResult::Success => { match self.token_manager.activate(token, client_id) { Some(activated_token) => { - let declare_mining_job_success = DeclareMiningJobSuccess { + let declare_mining_job_success = DeclareMiningJobSuccessOwned { request_id: msg.request_id, new_mining_job_token: activated_token .to_le_bytes() @@ -183,10 +191,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("must always be valid B0_255"), }; - JobDeclaration::DeclareMiningJobSuccess(declare_mining_job_success) + JobDeclarationOwned::DeclareMiningJobSuccess(declare_mining_job_success) } None => { - let declare_mining_job_error = DeclareMiningJobError { + let declare_mining_job_error = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: ERROR_CODE_DECLARE_MINING_JOB_INVALID_MINING_JOB_TOKEN .as_bytes() @@ -197,7 +205,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("empty array must be valid B0_64K"), }; - JobDeclaration::DeclareMiningJobError(declare_mining_job_error) + JobDeclarationOwned::DeclareMiningJobError(declare_mining_job_error) } } } @@ -206,7 +214,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { // make sure we clean up the allocated token self.token_manager.deallocate(token); - let declare_mining_job_error = DeclareMiningJobError { + let declare_mining_job_error = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: error .as_bytes() @@ -217,7 +225,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("empty array must be valid B0_64K"), }; - JobDeclaration::DeclareMiningJobError(declare_mining_job_error) + JobDeclarationOwned::DeclareMiningJobError(declare_mining_job_error) } // if missing transactions, add to pending declare mining jobs and return // ProvideMissingTransactions @@ -228,7 +236,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { })?; downstream .pending_declare_mining_jobs - .insert(msg.request_id, (Instant::now(), msg.as_static())); + .insert(msg.request_id, (Instant::now(), msg.clone())); // Convert missing Wtxids to u16 indices by finding their positions in // DeclareMiningJob.wtxid_list @@ -245,13 +253,13 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { }) .collect(); - let provide_missing_transactions = ProvideMissingTransactions { + let provide_missing_transactions = ProvideMissingTransactionsOwned { request_id: msg.request_id, unknown_tx_position_list: unknown_tx_position_list .try_into() .map_err(error::JDSError::shutdown)?, }; - JobDeclaration::ProvideMissingTransactions(provide_missing_transactions) + JobDeclarationOwned::ProvideMissingTransactions(provide_missing_transactions) } }; @@ -266,10 +274,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { async fn handle_provide_missing_transactions_success( &mut self, client_id: Option, - msg: ProvideMissingTransactionsSuccess<'_>, + msg: ProvideMissingTransactionsSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); // Shutdown: client_id is always Some; None indicates a bug. let client_id = client_id.ok_or_else(|| JDSError::shutdown(error::JDSErrorKind::ClientNotFound(0)))?; @@ -329,7 +337,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .activate(pending_declare_mining_job_token, client_id) { Some(activated_token) => { - let declare_mining_job_success = DeclareMiningJobSuccess { + let declare_mining_job_success = DeclareMiningJobSuccessOwned { request_id: msg.request_id, new_mining_job_token: activated_token .to_le_bytes() @@ -337,10 +345,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("must always be valid B0_255"), }; - JobDeclaration::DeclareMiningJobSuccess(declare_mining_job_success) + JobDeclarationOwned::DeclareMiningJobSuccess(declare_mining_job_success) } None => { - let declare_mining_job_error = DeclareMiningJobError { + let declare_mining_job_error = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: ERROR_CODE_DECLARE_MINING_JOB_INVALID_MINING_JOB_TOKEN .as_bytes() @@ -351,7 +359,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("empty array must be valid B0_64K"), }; - JobDeclaration::DeclareMiningJobError(declare_mining_job_error) + JobDeclarationOwned::DeclareMiningJobError(declare_mining_job_error) } } } @@ -361,7 +369,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { self.token_manager .deallocate(pending_declare_mining_job_token); - let declare_mining_job_error = DeclareMiningJobError { + let declare_mining_job_error = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: error_code .as_bytes() @@ -372,7 +380,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("empty array must be valid B0_64K"), }; - JobDeclaration::DeclareMiningJobError(declare_mining_job_error) + JobDeclarationOwned::DeclareMiningJobError(declare_mining_job_error) } // if we're still missing transactions, just reject this DeclareMiningJob DeclareMiningJobResult::MissingTransactions(_) => { @@ -380,7 +388,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { self.token_manager .deallocate(pending_declare_mining_job_token); - let declare_mining_job_error = DeclareMiningJobError { + let declare_mining_job_error = DeclareMiningJobErrorOwned { request_id: msg.request_id, error_code: ERROR_CODE_DECLARE_MINING_JOB_MISSING_TXS .as_bytes() @@ -391,7 +399,7 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { .try_into() .expect("empty array must be valid B0_64K"), }; - JobDeclaration::DeclareMiningJobError(declare_mining_job_error) + JobDeclarationOwned::DeclareMiningJobError(declare_mining_job_error) } }; @@ -406,10 +414,10 @@ impl HandleJobDeclarationMessagesFromClientAsync for JobDeclarator { async fn handle_push_solution( &mut self, client_id: Option, - msg: PushSolution<'_>, + msg: PushSolutionOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); // Shutdown: client_id is always Some; None indicates a bug. let client_id = diff --git a/pool-apps/jd-server/src/lib/job_declarator/job_validation/bitcoin_core_ipc.rs b/pool-apps/jd-server/src/lib/job_declarator/job_validation/bitcoin_core_ipc.rs index 6aaa09df9..f97e6fe00 100644 --- a/pool-apps/jd-server/src/lib/job_declarator/job_validation/bitcoin_core_ipc.rs +++ b/pool-apps/jd-server/src/lib/job_declarator/job_validation/bitcoin_core_ipc.rs @@ -32,7 +32,7 @@ use stratum_apps::{ BlockHash, CompactTarget, Transaction, TxMerkleNode, Txid, Wtxid, }, job_declaration_sv2::{ - DeclareMiningJob, ProvideMissingTransactionsSuccess, PushSolution, + DeclareMiningJobOwned, ProvideMissingTransactionsSuccessOwned, PushSolutionOwned, ERROR_CODE_DECLARE_MINING_JOB_INTERNAL_ERROR, ERROR_CODE_DECLARE_MINING_JOB_INVALID_COINBASE_TX, ERROR_CODE_DECLARE_MINING_JOB_INVALID_COINBASE_TX_INPUT, @@ -40,7 +40,7 @@ use stratum_apps::{ ERROR_CODE_DECLARE_MINING_JOB_STALE_CHAIN_TIP, }, mining_sv2::{ - SetCustomMiningJob, ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_COINBASE_PREFIX, + SetCustomMiningJobOwned, ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_COINBASE_PREFIX, ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_COINBASE_TX, ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_COINBASE_TX_INPUT_N_SEQUENCE, ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_COINBASE_TX_LOCKTIME, @@ -66,7 +66,7 @@ use stratum_apps::{ /// subsequent `SetCustomMiningJob` matches the original declaration. #[derive(Clone)] struct DeclaredCustomJob { - declare_mining_job: DeclareMiningJob<'static>, + declare_mining_job: DeclareMiningJobOwned, validation_context: ValidationContext, // committed at the time we receive DeclareMiningJob txid_list: Option>, // populated only on JdResponse::Success validated: bool, @@ -494,8 +494,8 @@ impl JobValidationEngine for BitcoinCoreIPCEngine { async fn handle_declare_mining_job( &self, downstream_id: DownstreamId, - declare_mining_job: DeclareMiningJob<'_>, - provide_missing_transactions_success: Option>, + declare_mining_job: DeclareMiningJobOwned, + provide_missing_transactions_success: Option, ) -> DeclareMiningJobResult { // Extract allocated token from the message let allocated_token: JdToken = match declare_mining_job.mining_job_token.try_as_array::<8>() @@ -509,7 +509,7 @@ impl JobValidationEngine for BitcoinCoreIPCEngine { }; // Create temporary DeclaredCustomJob for extracting coinbase (without prev_hash/nbits yet) - let declare_mining_job_static = declare_mining_job.clone().into_static(); + let declare_mining_job_static = declare_mining_job.clone(); // Extract and validate coinbase transaction let declared_coinbase_tx = { @@ -724,10 +724,10 @@ impl JobValidationEngine for BitcoinCoreIPCEngine { async fn handle_push_solution( &self, downstream_id: DownstreamId, - push_solution: PushSolution<'_>, + push_solution: PushSolutionOwned, ) { // Convert to static lifetime for channel transfer - let push_solution_static = push_solution.into_static(); + let push_solution_static = push_solution; // Send request to BitcoinCoreSv2JDP (fire-and-forget) let request = JdRequest::PushSolution { @@ -753,7 +753,7 @@ impl JobValidationEngine for BitcoinCoreIPCEngine { async fn handle_set_custom_mining_job( &self, downstream_id: DownstreamId, - set_custom_mining_job: SetCustomMiningJob<'_>, + set_custom_mining_job: SetCustomMiningJobOwned, allocated_token: JdToken, // Note: This is the corresponding DeclareMiningJob token ) -> SetCustomMiningJobResult { let declared_custom_job = match self diff --git a/pool-apps/jd-server/src/lib/job_declarator/job_validation/mod.rs b/pool-apps/jd-server/src/lib/job_declarator/job_validation/mod.rs index 0fdf234be..1a9b49833 100644 --- a/pool-apps/jd-server/src/lib/job_declarator/job_validation/mod.rs +++ b/pool-apps/jd-server/src/lib/job_declarator/job_validation/mod.rs @@ -3,8 +3,10 @@ use stratum_apps::{ stratum_core::{ bitcoin::Wtxid, - job_declaration_sv2::{DeclareMiningJob, ProvideMissingTransactionsSuccess, PushSolution}, - mining_sv2::SetCustomMiningJob, + job_declaration_sv2::{ + DeclareMiningJobOwned, ProvideMissingTransactionsSuccessOwned, PushSolutionOwned, + }, + mining_sv2::SetCustomMiningJobOwned, }, utils::types::{DownstreamId, JdToken}, }; @@ -17,12 +19,12 @@ pub mod bitcoin_core_ipc; /// - different ways to connect to the Bitcoin Node. /// /// Please note that while this is a trait with some similarities with -/// `handlers_sv2::job_declaration::HandleJobDeclarationMessagesFromClientAsync`, +/// `handlers_sv2::job_declaration::HandleJobDeclarationMessagesFromClientOwnedAsync`, /// this has a different purpose. /// /// More specifically, we diverge from -/// `handlers_sv2::job_declaration::HandleJobDeclarationMessagesFromClientAsync` in the following -/// ways: +/// `handlers_sv2::job_declaration::HandleJobDeclarationMessagesFromClientOwnedAsync` in the +/// following ways: /// - we do not handle the `AllocateMiningJobToken` message /// - we handle `SetCustomMiningJob` message #[async_trait::async_trait] @@ -31,15 +33,15 @@ pub trait JobValidationEngine: Send + Sync { async fn handle_declare_mining_job( &self, downstream_id: DownstreamId, - declare_mining_job: DeclareMiningJob<'_>, - provide_missing_transactions_success: Option>, + declare_mining_job: DeclareMiningJobOwned, + provide_missing_transactions_success: Option, ) -> DeclareMiningJobResult; /// Submits a mining solution to the backend. async fn handle_push_solution( &self, downstream_id: DownstreamId, - push_solution: PushSolution<'_>, + push_solution: PushSolutionOwned, ); /// Validates a `SetCustomMiningJob` (Mining Protocol) against the previously declared job @@ -47,7 +49,7 @@ pub trait JobValidationEngine: Send + Sync { async fn handle_set_custom_mining_job( &self, downstream_id: DownstreamId, - set_custom_mining_job: SetCustomMiningJob<'_>, + set_custom_mining_job: SetCustomMiningJobOwned, allocated_token: JdToken, ) -> SetCustomMiningJobResult; diff --git a/pool-apps/jd-server/src/lib/job_declarator/mod.rs b/pool-apps/jd-server/src/lib/job_declarator/mod.rs index 6a73424c2..82d1a03e3 100644 --- a/pool-apps/jd-server/src/lib/job_declarator/mod.rs +++ b/pool-apps/jd-server/src/lib/job_declarator/mod.rs @@ -29,12 +29,12 @@ use stratum_apps::{ key_utils::{Secp256k1PublicKey, Secp256k1SecretKey}, network_helpers::accept_noise_connection, stratum_core::{ - handlers_sv2::HandleJobDeclarationMessagesFromClientAsync, + handlers_sv2::HandleJobDeclarationMessagesFromClientOwnedAsync, mining_sv2::{ - SetCustomMiningJob, SetCustomMiningJobError, SetCustomMiningJobSuccess, + SetCustomMiningJobErrorOwned, SetCustomMiningJobOwned, SetCustomMiningJobSuccess, ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_MINING_JOB_TOKEN, }, - parsers_sv2::{JobDeclaration, Tlv}, + parsers_sv2::{JobDeclarationOwned, Tlv}, }, task_manager::TaskManager, utils::types::{DownstreamId, JdToken}, @@ -61,25 +61,25 @@ pub mod job_validation; pub mod token_management; /// Shared JDP payload exchanged between Job Declarator and downstreams. -type JobDeclarationMessage = (JobDeclaration<'static>, Option>); +type JobDeclarationMessage = (JobDeclarationOwned, Option>); /// Shared JDP payload sent from downstreams to Job Declarator, tagged with downstream id. -type DownstreamJobDeclarationMessage = (DownstreamId, JobDeclaration<'static>, Option>); +type DownstreamJobDeclarationMessage = (DownstreamId, JobDeclarationOwned, Option>); /// The response produced by [`JobDeclarator::handle_set_custom_mining_job`]. /// /// This is a Mining Protocol (MP) message, not a JDP message — it is returned to the /// caller (typically the Pool) rather than sent over the JDP TCP socket. #[derive(Debug)] -pub enum SetCustomMiningJobResponse<'a> { +pub enum SetCustomMiningJobResponse { Ok(SetCustomMiningJobSuccess), - Error(SetCustomMiningJobError<'a>), + Error(SetCustomMiningJobErrorOwned), } #[cfg_attr(not(test), hotpath::measure_all)] -impl SetCustomMiningJobResponse<'_> { +impl SetCustomMiningJobResponse { fn error(request_id: u32, channel_id: u32, error_code: &str) -> Self { - SetCustomMiningJobResponse::Error(SetCustomMiningJobError { + SetCustomMiningJobResponse::Error(SetCustomMiningJobErrorOwned { request_id, channel_id, error_code: error_code @@ -408,9 +408,9 @@ impl JobDeclarator { /// It is the caller's responsibility to set it. pub async fn handle_set_custom_mining_job( &mut self, - set_custom_mining_job: SetCustomMiningJob<'static>, + set_custom_mining_job: SetCustomMiningJobOwned, _tlv_fields: Option<&[Tlv]>, - ) -> JDSResult, error::JobDeclarator> { + ) -> JDSResult { let request_id = set_custom_mining_job.request_id; let channel_id = set_custom_mining_job.channel_id; diff --git a/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs b/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs index d8865f876..a2b1bf1ce 100644 --- a/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs +++ b/pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs @@ -1,4 +1,14 @@ use std::{convert::TryFrom, sync::atomic::Ordering}; +use stratum_apps::stratum_core::{ + mining_sv2::{ + CloseChannelOwned, OpenExtendedMiningChannelOwned, OpenExtendedMiningChannelSuccessOwned, + OpenMiningChannelErrorOwned, OpenStandardMiningChannelOwned, + OpenStandardMiningChannelSuccessOwned, SetCustomMiningJobErrorOwned, + SetCustomMiningJobOwned, SetNewPrevHashOwned, SetTargetOwned, SubmitSharesErrorOwned, + SubmitSharesExtendedOwned, UpdateChannelErrorOwned, UpdateChannelOwned, + }, + parsers_sv2::{MiningOwned, TemplateDistributionOwned}, +}; use stratum_apps::stratum_core::{ binary_sv2::Str0255, @@ -15,10 +25,10 @@ use stratum_apps::stratum_core::{ extensions_sv2::{ UserIdentity, EXTENSION_TYPE_WORKER_HASHRATE_TRACKING, TLV_FIELD_TYPE_USER_IDENTITY, }, - handlers_sv2::{HandleMiningMessagesFromClientAsync, SupportedChannelTypes}, + handlers_sv2::{HandleMiningMessagesFromClientOwnedAsync, SupportedChannelTypes}, mining_sv2::*, - parsers_sv2::{Mining, TemplateDistribution, Tlv, TlvField}, - template_distribution_sv2::SubmitSolution, + parsers_sv2::{Tlv, TlvField}, + template_distribution_sv2::SubmitSolutionOwned, }; use tracing::{error, info}; @@ -31,7 +41,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleMiningMessagesFromClientAsync for ChannelManager { +impl HandleMiningMessagesFromClientOwnedAsync for ChannelManager { type Error = PoolError; fn get_channel_type_for_client(&self, _client_id: Option) -> SupportedChannelTypes { @@ -67,10 +77,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_close_channel( &mut self, client_id: Option, - msg: CloseChannel<'_>, + msg: CloseChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received Close Channel: {msg}"); + info!("Received Close Channel: {msg:?}"); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); self.with_registered_downstream(downstream_id, |downstream| { @@ -93,20 +103,20 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_open_standard_mining_channel( &mut self, client_id: Option, - msg: OpenStandardMiningChannel<'_>, + msg: OpenStandardMiningChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - let request_id = msg.get_request_id_as_u32(); + let request_id = msg.request_id; let user_identity = msg.user_identity.as_utf8_or_hex(); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); - info!("Received OpenStandardMiningChannel: {}", msg); + info!("Received OpenStandardMiningChannel: {:?}", msg); let messages = self.with_registered_downstream(downstream_id, |downstream| { if downstream.requires_custom_work.load(Ordering::SeqCst) { error!("OpenStandardMiningChannel: Standard Channels are not supported for this connection"); - let open_standard_mining_channel_error = OpenMiningChannelError { + let open_standard_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: ERROR_CODE_OPEN_MINING_CHANNEL_STANDARD_CHANNELS_NOT_SUPPORTED_FOR_CUSTOM_WORK .to_string() @@ -115,7 +125,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_standard_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_standard_mining_channel_error), ) .into()]); } @@ -148,7 +158,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { "Invalid user_identity '{}': does not match any supported identity format", user_identity ); - let open_standard_mining_channel_error = OpenMiningChannelError { + let open_standard_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: ERROR_CODE_OPEN_MINING_CHANNEL_INVALID_USER_IDENTITY .to_string() @@ -157,7 +167,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_standard_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_standard_mining_channel_error), ) .into()]); } @@ -197,7 +207,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Err(e) => match e { StandardChannelError::OpenChannelInvalidNominalHashrate(code) => { error!("OpenMiningChannelError: {}", code); - let open_standard_mining_channel_error = OpenMiningChannelError { + let open_standard_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: code .to_string() @@ -206,7 +216,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_standard_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_standard_mining_channel_error), ) .into()]); } @@ -226,7 +236,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .map_err(PoolError::shutdown)?; let extranonce_prefix_size = standard_channel.get_extranonce_prefix().len(); - let open_standard_mining_channel_success = OpenStandardMiningChannelSuccess { + let open_standard_mining_channel_success = OpenStandardMiningChannelSuccessOwned { request_id: msg.request_id, channel_id, target: standard_channel.get_target().to_le_bytes().into(), @@ -237,14 +247,14 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("Extranonce_prefix must be valid"), group_channel_id, } - .into_static(); + ; let mut messages: Vec = Vec::new(); messages.push( ( downstream_id, - Mining::OpenStandardMiningChannelSuccess( + MiningOwned::OpenStandardMiningChannelSuccess( open_standard_mining_channel_success, ), ) @@ -263,19 +273,19 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .get_future_job(future_standard_job_id) .expect("future job must exist"); let future_standard_job_message = - future_standard_job.get_job_message().clone().into_static(); + future_standard_job.get_job_message().clone(); messages.push( ( downstream_id, - Mining::NewMiningJob(future_standard_job_message), + MiningOwned::NewMiningJob(future_standard_job_message), ) .into(), ); let prev_hash = last_set_new_prev_hash_tdp.prev_hash.clone(); let header_timestamp = last_set_new_prev_hash_tdp.header_timestamp; let n_bits = last_set_new_prev_hash_tdp.n_bits; - let set_new_prev_hash_mining = SetNewPrevHash { + let set_new_prev_hash_mining = SetNewPrevHashOwned { channel_id, job_id: future_standard_job_id, prev_hash, @@ -290,7 +300,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetNewPrevHash(set_new_prev_hash_mining), + MiningOwned::SetNewPrevHash(set_new_prev_hash_mining), ) .into(), ); @@ -330,14 +340,14 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_open_extended_mining_channel( &mut self, client_id: Option, - msg: OpenExtendedMiningChannel<'_>, + msg: OpenExtendedMiningChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - let request_id = msg.get_request_id_as_u32(); + let request_id = msg.request_id; let user_identity = msg.user_identity.as_utf8_or_hex(); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); - info!("Received OpenExtendedMiningChannel: {}", msg); + info!("Received OpenExtendedMiningChannel: {:?}", msg); let nominal_hash_rate = msg.nominal_hash_rate; let requested_max_target = Target::from_le_bytes(msg.max_target.to_array()); @@ -345,7 +355,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let messages = self.with_registered_downstream(downstream_id, |downstream| { if downstream.requires_standard_jobs.load(Ordering::SeqCst) { - let open_extended_mining_channel_error = OpenMiningChannelError { + let open_extended_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: ERROR_CODE_OPEN_MINING_CHANNEL_EXTENDED_CHANNELS_NOT_SUPPORTED_FOR_STANDARD_JOBS .to_string() @@ -354,7 +364,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_extended_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_extended_mining_channel_error), ) .into()]); } @@ -371,7 +381,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Ok(prefix) => prefix, Err(_) => { error!("OpenMiningChannelError: min-extranonce-size-too-large"); - let open_extended_mining_channel_error = OpenMiningChannelError { + let open_extended_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: ERROR_CODE_OPEN_MINING_CHANNEL_MIN_EXTRANONCE_SIZE_TOO_LARGE .to_string() @@ -380,7 +390,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_extended_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_extended_mining_channel_error), ) .into()]); } @@ -394,7 +404,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { "Invalid user_identity '{}': does not match any supported identity format", user_identity ); - let open_extended_mining_channel_error = OpenMiningChannelError { + let open_extended_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: ERROR_CODE_OPEN_MINING_CHANNEL_INVALID_USER_IDENTITY .to_string() @@ -403,7 +413,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_extended_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_extended_mining_channel_error), ) .into()]); } @@ -432,7 +442,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Err(e) => match e { ExtendedChannelError::OpenChannelInvalidNominalHashrate(code) => { error!("OpenMiningChannelError: {}", code); - let open_extended_mining_channel_error = OpenMiningChannelError { + let open_extended_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: code .to_string() @@ -441,13 +451,13 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_extended_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_extended_mining_channel_error), ) .into()]); } ExtendedChannelError::RequestedMinExtranonceSizeTooLarge(code) => { error!("OpenMiningChannelError: {}", code); - let open_extended_mining_channel_error = OpenMiningChannelError { + let open_extended_mining_channel_error = OpenMiningChannelErrorOwned { request_id, error_code: code .to_string() @@ -456,7 +466,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; return Ok(vec![( downstream_id, - Mining::OpenMiningChannelError(open_extended_mining_channel_error), + MiningOwned::OpenMiningChannelError(open_extended_mining_channel_error), ) .into()]); } @@ -472,7 +482,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .with(|channel| channel.get_group_channel_id()) .map_err(PoolError::shutdown)?; - let open_extended_mining_channel_success = OpenExtendedMiningChannelSuccess { + let open_extended_mining_channel_success = OpenExtendedMiningChannelSuccessOwned { request_id, channel_id, target: extended_channel.get_target().to_le_bytes().into(), @@ -484,13 +494,13 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { extranonce_size: extended_channel.get_rollable_extranonce_size(), group_channel_id, } - .into_static(); - info!("Sending OpenExtendedMiningChannel.Success (downstream_id: {downstream_id}): {open_extended_mining_channel_success}"); + ; + info!("Sending OpenExtendedMiningChannel.Success (downstream_id: {downstream_id}): {open_extended_mining_channel_success:?}"); messages.push( ( downstream_id, - Mining::OpenExtendedMiningChannelSuccess( + MiningOwned::OpenExtendedMiningChannelSuccess( open_extended_mining_channel_success, ), ) @@ -545,7 +555,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("future job must exist"); let future_extended_job_message = - future_extended_job.get_job_message().clone().into_static(); + future_extended_job.get_job_message().clone(); // send this future job as new job message // to be immediately activated with the subsequent SetNewPrevHash @@ -553,7 +563,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::NewExtendedMiningJob(future_extended_job_message), + MiningOwned::NewExtendedMiningJob(future_extended_job_message), ) .into(), ); @@ -562,7 +572,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let prev_hash = last_set_new_prev_hash_tdp.prev_hash.clone(); let header_timestamp = last_set_new_prev_hash_tdp.header_timestamp; let n_bits = last_set_new_prev_hash_tdp.n_bits; - let set_new_prev_hash_mining = SetNewPrevHash { + let set_new_prev_hash_mining = SetNewPrevHashOwned { channel_id, job_id: future_extended_job_id, prev_hash, @@ -577,7 +587,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::SetNewPrevHash(set_new_prev_hash_mining), + MiningOwned::SetNewPrevHash(set_new_prev_hash_mining), ) .into(), ); @@ -617,10 +627,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_submit_shares_standard( &mut self, client_id: Option, - msg: SubmitSharesStandard, + msg: SubmitSharesStandardOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received SubmitSharesStandard: {msg}"); + info!("Received SubmitSharesStandard: {msg:?}"); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); @@ -628,7 +638,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let vardiff_key = (downstream_id, channel_id).into(); let messages = self.with_registered_downstream(downstream_id, |downstream| { let messages = if !downstream.standard_channels.contains_key(&channel_id) { - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id, sequence_number: msg.sequence_number, error_code: ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID @@ -637,11 +647,11 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID); - vec![(downstream_id, Mining::SubmitSharesError(error)).into()] + vec![(downstream_id, MiningOwned::SubmitSharesError(error)).into()] } else if !self.vardiff.contains_key(&vardiff_key) { vec![( downstream_id, - Mining::CloseChannel(create_close_channel_msg( + MiningOwned::CloseChannel(create_close_channel_msg( channel_id, ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID, )), @@ -658,7 +668,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Ok(ShareValidationResult::Valid(share_hash)) => { let share_accounting = standard_channel.get_share_accounting(); if share_accounting.should_acknowledge() { - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting .get_last_share_sequence_number(), @@ -669,7 +679,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; info!("SubmitSharesStandard: {} ✅", success); messages.push( - (downstream_id, Mining::SubmitSharesSuccess(success)) + (downstream_id, MiningOwned::SubmitSharesSuccess(success)) .into(), ); } else { @@ -691,7 +701,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { // we can propagate the solution to the TP if let Some(template_id) = template_id { info!("SubmitSharesStandard: Propagating solution to the Template Provider."); - let solution = SubmitSolution { + let solution = SubmitSolutionOwned { template_id, version: msg.version, header_timestamp: msg.ntime, @@ -701,12 +711,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .map_err(PoolError::shutdown)?, }; messages.push( - TemplateDistribution::SubmitSolution(solution) + TemplateDistributionOwned::SubmitSolution(solution) .into(), ); } let share_accounting = standard_channel.get_share_accounting(); - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting .get_last_share_sequence_number(), @@ -716,13 +726,13 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .get_last_batch_work_sum(), }; messages.push( - (downstream_id, Mining::SubmitSharesSuccess(success)) + (downstream_id, MiningOwned::SubmitSharesSuccess(success)) .into(), ); } Err(ShareValidationError::Invalid(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -732,12 +742,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::Stale(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -746,12 +756,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::InvalidJobId(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -760,12 +770,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::DoesNotMeetTarget(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -774,12 +784,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::DuplicateShare(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -788,12 +798,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::VersionRollingNotAllowed(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -802,7 +812,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(e) => { @@ -820,7 +830,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { validation? } None => { - let submit_shares_error = SubmitSharesError { + let submit_shares_error = SubmitSharesErrorOwned { channel_id, sequence_number: msg.sequence_number, error_code: ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID @@ -831,7 +841,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID); vec![( downstream_id, - Mining::SubmitSharesError(submit_shares_error), + MiningOwned::SubmitSharesError(submit_shares_error), ) .into()] } @@ -856,10 +866,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_submit_shares_extended( &mut self, client_id: Option, - msg: SubmitSharesExtended<'_>, + msg: SubmitSharesExtendedOwned, tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received SubmitSharesExtended: {msg}"); + info!("Received SubmitSharesExtended: {msg:?}"); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); @@ -885,7 +895,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { let vardiff_key = (downstream_id, channel_id).into(); let messages = self.with_registered_downstream(downstream_id, |downstream| { let messages = if !downstream.extended_channels.contains_key(&channel_id) { - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id, sequence_number: msg.sequence_number, error_code: ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID @@ -894,11 +904,11 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID); - vec![(downstream_id, Mining::SubmitSharesError(error)).into()] + vec![(downstream_id, MiningOwned::SubmitSharesError(error)).into()] } else if !self.vardiff.contains_key(&vardiff_key) { vec![( downstream_id, - Mining::CloseChannel(create_close_channel_msg( + MiningOwned::CloseChannel(create_close_channel_msg( channel_id, ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID, )), @@ -919,7 +929,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { Ok(ShareValidationResult::Valid(share_hash)) => { let share_accounting = extended_channel.get_share_accounting(); if share_accounting.should_acknowledge() { - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting .get_last_share_sequence_number(), @@ -930,7 +940,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { }; info!("SubmitSharesExtended: {} ✅", success); messages.push( - (downstream_id, Mining::SubmitSharesSuccess(success)) + (downstream_id, MiningOwned::SubmitSharesSuccess(success)) .into(), ); } else { @@ -950,7 +960,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { info!("SubmitSharesExtended: 💰 Block Found!!! 💰{share_hash}"); if let Some(template_id) = template_id { info!("SubmitSharesExtended: Propagating solution to the Template Provider."); - let solution = SubmitSolution { + let solution = SubmitSolutionOwned { template_id, version: msg.version, header_timestamp: msg.ntime, @@ -960,12 +970,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .map_err(PoolError::shutdown)?, }; messages.push( - TemplateDistribution::SubmitSolution(solution) + TemplateDistributionOwned::SubmitSolution(solution) .into(), ); } let share_accounting = extended_channel.get_share_accounting(); - let success = SubmitSharesSuccess { + let success = SubmitSharesSuccessOwned { channel_id, last_sequence_number: share_accounting .get_last_share_sequence_number(), @@ -975,13 +985,13 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .get_last_batch_work_sum(), }; messages.push( - (downstream_id, Mining::SubmitSharesSuccess(success)) + (downstream_id, MiningOwned::SubmitSharesSuccess(success)) .into(), ); } Err(ShareValidationError::Invalid(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -990,12 +1000,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::Stale(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -1004,12 +1014,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::InvalidJobId(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -1018,12 +1028,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::DoesNotMeetTarget(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -1032,12 +1042,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::DuplicateShare(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -1046,12 +1056,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::BadExtranonceSize(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -1060,12 +1070,12 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(ShareValidationError::VersionRollingNotAllowed(code)) => { error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, code); - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id: msg.channel_id, sequence_number: msg.sequence_number, error_code: code @@ -1074,7 +1084,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; messages.push( - (downstream_id, Mining::SubmitSharesError(error)).into(), + (downstream_id, MiningOwned::SubmitSharesError(error)).into(), ); } Err(e) => { @@ -1092,7 +1102,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { validation? } None => { - let error = SubmitSharesError { + let error = SubmitSharesErrorOwned { channel_id, sequence_number: msg.sequence_number, error_code: ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID @@ -1101,7 +1111,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; error!("SubmitSharesError: downstream_id: {}, channel_id: {}, sequence_number: {}, error_code: {} ❌", downstream_id, channel_id, msg.sequence_number, ERROR_CODE_SUBMIT_SHARES_INVALID_CHANNEL_ID); - vec![(downstream_id, Mining::SubmitSharesError(error)).into()] + vec![(downstream_id, MiningOwned::SubmitSharesError(error)).into()] } } }; @@ -1124,10 +1134,10 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_update_channel( &mut self, client_id: Option, - msg: UpdateChannel<'_>, + msg: UpdateChannelOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); @@ -1149,7 +1159,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { match e { StandardChannelError::UpdateChannelInvalidNominalHashrate(code) => { error!("UpdateChannelError: {}", code); - let update_channel_error = UpdateChannelError { + let update_channel_error = UpdateChannelErrorOwned { channel_id, error_code: code .to_string() @@ -1159,7 +1169,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::UpdateChannelError(update_channel_error), + MiningOwned::UpdateChannelError(update_channel_error), ) .into(), ); @@ -1169,11 +1179,11 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { } } let new_target = standard_channel.get_target(); - let set_target = SetTarget { + let set_target = SetTargetOwned { channel_id, maximum_target: new_target.to_le_bytes().into(), }; - messages.push((downstream_id, Mining::SetTarget(set_target)).into()); + messages.push((downstream_id, MiningOwned::SetTarget(set_target)).into()); }) .is_none() && downstream @@ -1190,7 +1200,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { code, ) => { error!("UpdateChannelError: {}", code); - let update_channel_error = UpdateChannelError { + let update_channel_error = UpdateChannelErrorOwned { channel_id, error_code: code .to_string() @@ -1200,7 +1210,9 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::UpdateChannelError(update_channel_error), + MiningOwned::UpdateChannelError( + update_channel_error, + ), ) .into(), ); @@ -1210,16 +1222,16 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { } } let new_target = extended_channel.get_target(); - let set_target = SetTarget { + let set_target = SetTargetOwned { channel_id, maximum_target: new_target.to_le_bytes().into(), }; - messages.push((downstream_id, Mining::SetTarget(set_target)).into()); + messages.push((downstream_id, MiningOwned::SetTarget(set_target)).into()); }) .is_none() { error!("UpdateChannelError: invalid-channel-id"); - let update_channel_error = UpdateChannelError { + let update_channel_error = UpdateChannelErrorOwned { channel_id, error_code: ERROR_CODE_UPDATE_CHANNEL_INVALID_CHANNEL_ID .to_string() @@ -1229,7 +1241,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { messages.push( ( downstream_id, - Mining::UpdateChannelError(update_channel_error), + MiningOwned::UpdateChannelError(update_channel_error), ) .into(), ); @@ -1253,15 +1265,15 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { async fn handle_set_custom_mining_job( &mut self, client_id: Option, - msg: SetCustomMiningJob<'_>, + msg: SetCustomMiningJobOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); let downstream_id = client_id.expect("client_id must be present for downstream_id extraction"); let Some(ref mut job_declarator) = self.job_declarator else { - let error = SetCustomMiningJobError { + let error = SetCustomMiningJobErrorOwned { request_id: msg.request_id, channel_id: msg.channel_id, error_code: ERROR_CODE_SET_CUSTOM_MINING_JOB_JD_NOT_SUPPORTED @@ -1270,7 +1282,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .expect("error code must be valid string"), }; let message: RouteMessageTo = - (downstream_id, Mining::SetCustomMiningJobError(error)).into(); + (downstream_id, MiningOwned::SetCustomMiningJobError(error)).into(); message .forward(&self.channel_manager_io) .await @@ -1278,7 +1290,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { return Ok(()); }; - let msg_static = msg.clone().into_static(); + let msg_static = msg.clone(); // Step 1: Validate the custom job via JDS (token + job validation). let jds_response = job_declarator @@ -1287,11 +1299,8 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .map_err(|e| PoolError::shutdown(PoolErrorKind::Jds(e.into())))?; if let SetCustomMiningJobResponse::Error(jds_err) = jds_response { - let message: RouteMessageTo = ( - downstream_id, - Mining::SetCustomMiningJobError(jds_err.into_static()), - ) - .into(); + let message: RouteMessageTo = + (downstream_id, MiningOwned::SetCustomMiningJobError(jds_err)).into(); message .forward(&self.channel_manager_io) .await @@ -1309,18 +1318,22 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .on_set_custom_mining_job(msg_static.clone()) .map_err(|error| PoolError::disconnect(error, downstream_id))?; - let success = SetCustomMiningJobSuccess { + let success = SetCustomMiningJobSuccessOwned { channel_id: msg_static.channel_id, request_id: msg_static.request_id, job_id, }; - Ok((downstream_id, Mining::SetCustomMiningJobSuccess(success)).into()) + Ok(( + downstream_id, + MiningOwned::SetCustomMiningJobSuccess(success), + ) + .into()) }, ) { Some(message) => message, None => { error!("SetCustomMiningJobError: invalid-channel-id"); - let error = SetCustomMiningJobError { + let error = SetCustomMiningJobErrorOwned { request_id: msg_static.request_id, channel_id: msg_static.channel_id, error_code: ERROR_CODE_SET_CUSTOM_MINING_JOB_INVALID_CHANNEL_ID @@ -1328,7 +1341,7 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager { .try_into() .expect("error code must be valid string"), }; - Ok((downstream_id, Mining::SetCustomMiningJobError(error)).into()) + Ok((downstream_id, MiningOwned::SetCustomMiningJobError(error)).into()) } } })?; diff --git a/pool-apps/pool/src/lib/channel_manager/mod.rs b/pool-apps/pool/src/lib/channel_manager/mod.rs index 2c7cd6bd8..510b5e692 100644 --- a/pool-apps/pool/src/lib/channel_manager/mod.rs +++ b/pool-apps/pool/src/lib/channel_manager/mod.rs @@ -5,6 +5,10 @@ use std::{ Arc, }, }; +use stratum_apps::stratum_core::{ + mining_sv2::SetTargetOwned, + parsers_sv2::{MiningOwned, TemplateDistributionOwned}, +}; use async_channel::{unbounded, Receiver, Sender}; use core::sync::atomic::Ordering; @@ -23,11 +27,11 @@ use stratum_apps::{ Vardiff, VardiffState, }, handlers_sv2::{ - HandleMiningMessagesFromClientAsync, HandleTemplateDistributionMessagesFromServerAsync, + HandleMiningMessagesFromClientOwnedAsync, + HandleTemplateDistributionMessagesFromServerOwnedAsync, }, - mining_sv2::SetTarget, - parsers_sv2::{Mining, TemplateDistribution, Tlv}, - template_distribution_sv2::{NewTemplate, SetNewPrevHash}, + parsers_sv2::Tlv, + template_distribution_sv2::{NewTemplateOwned, SetNewPrevHashOwned}, }, sync::{SharedLock, SharedMap}, task_manager::TaskManager, @@ -64,10 +68,10 @@ pub const FULL_EXTRANONCE_SIZE: u8 = POOL_ALLOCATION_BYTES + CLIENT_SEARCH_SPACE #[derive(Clone)] pub struct ChannelManagerIo { - tp_sender: Sender>, - tp_receiver: Receiver>, + tp_sender: Sender, + tp_receiver: Receiver, downstream_sender: SharedMap>, - downstream_receiver: Receiver<(usize, Mining<'static>, Option>)>, + downstream_receiver: Receiver<(usize, MiningOwned, Option>)>, } impl ChannelManagerIo { @@ -100,9 +104,9 @@ pub struct ChannelManager { // Coinbase outputs. pub(crate) coinbase_outputs: Vec, // Last new prevhash. - pub(crate) last_new_prev_hash: SharedLock>>, + pub(crate) last_new_prev_hash: SharedLock>, // Last future template. - pub(crate) last_future_template: SharedLock>>, + pub(crate) last_future_template: SharedLock>, channel_manager_io: ChannelManagerIo, pool_tag_string: String, share_batch_size: usize, @@ -157,9 +161,9 @@ impl ChannelManager { #[allow(clippy::too_many_arguments)] pub async fn new( config: PoolConfig, - tp_sender: Sender>, - tp_receiver: Receiver>, - downstream_receiver: Receiver<(DownstreamId, Mining<'static>, Option>)>, + tp_sender: Sender, + tp_receiver: Receiver, + downstream_receiver: Receiver<(DownstreamId, MiningOwned, Option>)>, coinbase_outputs: Vec, job_declarator: Option, ) -> PoolResult { @@ -208,7 +212,7 @@ impl ChannelManager { fn bootstrap_group_channel( &self, channel_id: ChannelId, - ) -> PoolResult>, error::ChannelManager> { + ) -> PoolResult, error::ChannelManager> { let last_future_template = self .last_future_template .get() @@ -261,7 +265,7 @@ impl ChannelManager { listening_address: SocketAddr, task_manager: Arc, cancellation_token: CancellationToken, - channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, + channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, ) -> PoolResult<(), error::ChannelManager> { // todo: let start_downstream_server accept Arc, instead of clone. let this = Arc::new(self); @@ -511,7 +515,7 @@ impl ChannelManager { fn run_vardiff_on_extended_channel( downstream_id: DownstreamId, channel_id: ChannelId, - channel_state: &mut ExtendedChannel<'static>, + channel_state: &mut ExtendedChannel, vardiff_state: &mut VardiffState, updates: &mut Vec, ) { @@ -540,7 +544,7 @@ impl ChannelManager { updates.push( ( downstream_id, - Mining::SetTarget(SetTarget { + MiningOwned::SetTarget(SetTargetOwned { channel_id, maximum_target: updated_target.to_le_bytes().into(), }), @@ -559,7 +563,7 @@ impl ChannelManager { fn run_vardiff_on_standard_channel( downstream_id: DownstreamId, channel_id: ChannelId, - channel: &mut StandardChannel<'static>, + channel: &mut StandardChannel, vardiff_state: &mut VardiffState, updates: &mut Vec, ) { @@ -585,7 +589,7 @@ impl ChannelManager { updates.push( ( downstream_id, - Mining::SetTarget(SetTarget { + MiningOwned::SetTarget(SetTargetOwned { channel_id, maximum_target: updated_target.to_le_bytes().into(), }), @@ -696,7 +700,7 @@ impl ChannelManager { self.channel_manager_io .tp_sender - .send(TemplateDistribution::CoinbaseOutputConstraints(msg)) + .send(TemplateDistributionOwned::CoinbaseOutputConstraints(msg)) .await .map_err(|e| { error!(error = ?e, "Failed to send CoinbaseOutputConstraints message to TP"); @@ -740,26 +744,26 @@ impl ChannelManager { } #[derive(Debug, Clone)] -pub enum RouteMessageTo<'a> { +pub enum RouteMessageTo { /// Route to the template provider subsystem. - TemplateProvider(TemplateDistribution<'a>), + TemplateProvider(TemplateDistributionOwned), /// Route to a specific downstream client by ID, along with its mining message. - Downstream((DownstreamId, Mining<'a>)), + Downstream((DownstreamId, MiningOwned)), } -impl<'a> From> for RouteMessageTo<'a> { - fn from(value: TemplateDistribution<'a>) -> Self { +impl From for RouteMessageTo { + fn from(value: TemplateDistributionOwned) -> Self { Self::TemplateProvider(value) } } -impl<'a> From<(DownstreamId, Mining<'a>)> for RouteMessageTo<'a> { - fn from(value: (DownstreamId, Mining<'a>)) -> Self { +impl From<(DownstreamId, MiningOwned)> for RouteMessageTo { + fn from(value: (DownstreamId, MiningOwned)) -> Self { Self::Downstream(value) } } -impl RouteMessageTo<'_> { +impl RouteMessageTo { pub async fn forward(self, channel_manager_io: &ChannelManagerIo) -> Result<(), PoolErrorKind> { match self { RouteMessageTo::Downstream((downstream_id, message)) => { @@ -768,16 +772,13 @@ impl RouteMessageTo<'_> { .get_cloned(&downstream_id); if let Some(sender) = sender { - sender.send((message.into_static(), None)).await?; + sender.send((message, None)).await?; } else { debug!("Dropping message for downstream {downstream_id}: no longer connected"); } } RouteMessageTo::TemplateProvider(message) => { - channel_manager_io - .tp_sender - .send(message.into_static()) - .await?; + channel_manager_io.tp_sender.send(message).await?; } } Ok(()) diff --git a/pool-apps/pool/src/lib/channel_manager/template_distribution_message_handler.rs b/pool-apps/pool/src/lib/channel_manager/template_distribution_message_handler.rs index e551ba28e..d3f4f10d6 100644 --- a/pool-apps/pool/src/lib/channel_manager/template_distribution_message_handler.rs +++ b/pool-apps/pool/src/lib/channel_manager/template_distribution_message_handler.rs @@ -1,12 +1,16 @@ use std::sync::atomic::Ordering; +use stratum_apps::stratum_core::{ + parsers_sv2::MiningOwned, + template_distribution_sv2::{ + NewTemplateOwned, RequestTransactionDataErrorOwned, RequestTransactionDataSuccessOwned, + }, +}; use stratum_apps::stratum_core::{ - bitcoin::Amount, - channels_sv2::outputs::deserialize_outputs, - handlers_sv2::HandleTemplateDistributionMessagesFromServerAsync, - mining_sv2::SetNewPrevHash as SetNewPrevHashMp, - parsers_sv2::{Mining, Tlv}, - template_distribution_sv2::*, + bitcoin::Amount, channels_sv2::outputs::deserialize_outputs, + handlers_sv2::HandleTemplateDistributionMessagesFromServerOwnedAsync, + mining_sv2::SetNewPrevHashOwned as SetNewPrevHashMp, parsers_sv2::Tlv, + template_distribution_sv2::SetNewPrevHashOwned as SetNewPrevHashTdp, }; use tracing::{info, warn}; @@ -16,7 +20,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { +impl HandleTemplateDistributionMessagesFromServerOwnedAsync for ChannelManager { type Error = PoolError; fn get_negotiated_extensions_with_server( @@ -29,14 +33,14 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { async fn handle_new_template( &mut self, _server_id: Option, - msg: NewTemplate<'_>, + msg: NewTemplateOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); if msg.future_template { self.last_future_template - .set(Some(msg.clone().into_static())) + .set(Some(msg.clone())) .map_err(PoolError::shutdown)?; } @@ -71,7 +75,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { .with(|group_channel| { group_channel .on_new_template( - msg.clone().into_static(), + msg.clone(), downstream_coinbase_outputs.clone(), ) .map_err(PoolError::shutdown)?; @@ -98,7 +102,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { downstream_messages.push( ( downstream_id, - Mining::NewExtendedMiningJob(group_job.get_job_message().clone()), + MiningOwned::NewExtendedMiningJob(group_job.get_job_message().clone()), ) .into(), ); @@ -123,7 +127,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { } else { standard_channel .on_new_template( - msg.clone().into_static(), + msg.clone(), downstream_coinbase_outputs.clone(), ) .map_err(|e| { @@ -145,7 +149,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { downstream_messages.push( ( downstream_id, - Mining::NewMiningJob(standard_job.get_job_message().clone()), + MiningOwned::NewMiningJob(standard_job.get_job_message().clone()), ) .into(), ); @@ -182,33 +186,33 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { async fn handle_request_tx_data_error( &mut self, _server_id: Option, - msg: RequestTransactionDataError<'_>, + msg: RequestTransactionDataErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - warn!("Received: {}", msg); + warn!("Received: {:?}", msg); Ok(()) } async fn handle_request_tx_data_success( &mut self, _server_id: Option, - msg: RequestTransactionDataSuccess<'_>, + msg: RequestTransactionDataSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_set_new_prev_hash( &mut self, _server_id: Option, - msg: SetNewPrevHash<'_>, + msg: SetNewPrevHashTdp, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); self.last_new_prev_hash - .set(Some(msg.clone().into_static())) + .set(Some(msg.clone())) .map_err(PoolError::shutdown)?; let mut messages: Vec = vec![]; @@ -228,7 +232,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { // Call on_set_new_prev_hash on the group channel to update the channel // state. group_channel - .on_set_new_prev_hash(msg.clone().into_static()) + .on_set_new_prev_hash(msg.clone()) .map_err(|e| { tracing::error!("Error while adding new prev hash to group channel"); PoolError::shutdown(e) @@ -244,7 +248,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { downstream_messages.push( ( downstream_id, - Mining::SetNewPrevHash(SetNewPrevHashMp { + MiningOwned::SetNewPrevHash(SetNewPrevHashMp { channel_id: group_channel.get_group_channel_id(), job_id: active_job_id, prev_hash: msg.prev_hash.clone(), @@ -263,7 +267,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { // extended channel to update the channel state. downstream.extended_channels.try_for_each_mut(|channel_id, channel| { channel - .on_set_new_prev_hash(msg.clone().into_static()) + .on_set_new_prev_hash(msg.clone()) .map_err(|e| { tracing::error!("Error while adding new prev hash to extended channel: {channel_id:?} {e:?}"); PoolError::shutdown(e) @@ -276,7 +280,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { // Call on_set_new_prev_hash on the standard channel to update the channel // state. channel - .on_set_new_prev_hash(msg.clone().into_static()) + .on_set_new_prev_hash(msg.clone()) .map_err(|e| { tracing::error!("Error while adding new prev hash to standard channel: {channel_id:?} {e:?}"); PoolError::shutdown(e) @@ -292,7 +296,7 @@ impl HandleTemplateDistributionMessagesFromServerAsync for ChannelManager { downstream_messages.push( ( downstream_id, - Mining::SetNewPrevHash(SetNewPrevHashMp { + MiningOwned::SetNewPrevHash(SetNewPrevHashMp { channel_id, job_id: active_job_id, prev_hash: msg.prev_hash.clone(), diff --git a/pool-apps/pool/src/lib/config.rs b/pool-apps/pool/src/lib/config.rs index 5be1b3052..030e613b2 100644 --- a/pool-apps/pool/src/lib/config.rs +++ b/pool-apps/pool/src/lib/config.rs @@ -172,7 +172,7 @@ impl PoolConfig { pub fn get_txout(&self) -> TxOut { TxOut { value: Amount::from_sat(0), - script_pubkey: self.coinbase_reward_script.script_pubkey().to_owned(), + script_pubkey: self.coinbase_reward_script.script_pubkey(), } } diff --git a/pool-apps/pool/src/lib/downstream/common_message_handler.rs b/pool-apps/pool/src/lib/downstream/common_message_handler.rs index 9cb18c935..cb8c90e04 100644 --- a/pool-apps/pool/src/lib/downstream/common_message_handler.rs +++ b/pool-apps/pool/src/lib/downstream/common_message_handler.rs @@ -6,19 +6,19 @@ use std::{convert::TryInto, sync::atomic::Ordering}; use stratum_apps::{ stratum_core::{ common_messages_sv2::{ - has_requires_std_job, has_work_selection, Protocol, SetupConnection, - SetupConnectionError, SetupConnectionSuccess, + has_requires_std_job, has_work_selection, Protocol, SetupConnectionErrorOwned, + SetupConnectionOwned, SetupConnectionSuccess, ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL, }, - handlers_sv2::HandleCommonMessagesFromClientAsync, - parsers_sv2::{AnyMessage, Tlv}, + handlers_sv2::HandleCommonMessagesFromClientOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::info; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromClientAsync for Downstream { +impl HandleCommonMessagesFromClientOwnedAsync for Downstream { type Error = PoolError; fn get_negotiated_extensions_with_client( @@ -33,7 +33,7 @@ impl HandleCommonMessagesFromClientAsync for Downstream { async fn handle_setup_connection( &mut self, client_id: Option, - msg: SetupConnection<'_>, + msg: SetupConnectionOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { info!( @@ -45,14 +45,14 @@ impl HandleCommonMessagesFromClientAsync for Downstream { if msg.protocol != Protocol::MiningProtocol { info!("Rejecting connection from {downstream_id}: SetupConnection asking for other protocols than mining protocol."); - let response = SetupConnectionError { + let response = SetupConnectionErrorOwned { flags: 0, error_code: ERROR_CODE_SETUP_CONNECTION_UNSUPPORTED_PROTOCOL .to_string() .try_into() .expect("error code must be valid string"), }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(PoolError::shutdown)?; self.downstream_io @@ -91,7 +91,7 @@ impl HandleCommonMessagesFromClientAsync for Downstream { used_version: 2, flags: response_flags, }; - let frame: Sv2Frame = AnyMessage::Common(response.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Common(response.into()) .try_into() .map_err(PoolError::shutdown)?; self.downstream_io diff --git a/pool-apps/pool/src/lib/downstream/extensions_message_handler.rs b/pool-apps/pool/src/lib/downstream/extensions_message_handler.rs index 731d00f42..f45643652 100644 --- a/pool-apps/pool/src/lib/downstream/extensions_message_handler.rs +++ b/pool-apps/pool/src/lib/downstream/extensions_message_handler.rs @@ -5,17 +5,19 @@ use crate::{ use std::convert::TryInto; use stratum_apps::{ stratum_core::{ - binary_sv2::Seq064K, - extensions_sv2::{RequestExtensions, RequestExtensionsError, RequestExtensionsSuccess}, - handlers_sv2::HandleExtensionsFromClientAsync, - parsers_sv2::{AnyMessage, Tlv}, + binary_sv2::Seq064KOwned, + extensions_sv2::{ + RequestExtensionsErrorOwned, RequestExtensionsOwned, RequestExtensionsSuccessOwned, + }, + handlers_sv2::HandleExtensionsFromClientOwnedAsync, + parsers_sv2::{AnyMessageOwned, Tlv}, }, utils::types::Sv2Frame, }; use tracing::{error, info}; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleExtensionsFromClientAsync for Downstream { +impl HandleExtensionsFromClientOwnedAsync for Downstream { type Error = PoolError; fn get_negotiated_extensions_with_client( @@ -30,7 +32,7 @@ impl HandleExtensionsFromClientAsync for Downstream { async fn handle_request_extensions( &mut self, _client_id: Option, - msg: RequestExtensions<'_>, + msg: RequestExtensionsOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { let requested: Vec = msg.requested_extensions.clone().into_inner(); @@ -77,14 +79,15 @@ impl HandleExtensionsFromClientAsync for Downstream { self.downstream_id, requested, supported, unsupported, missing_required ); - let error = RequestExtensionsError { + let error = RequestExtensionsErrorOwned { request_id: msg.request_id, - unsupported_extensions: Seq064K::new(unsupported).map_err(PoolError::shutdown)?, - required_extensions: Seq064K::new(missing_required.clone()) + unsupported_extensions: Seq064KOwned::new(unsupported) + .map_err(PoolError::shutdown)?, + required_extensions: Seq064KOwned::new(missing_required.clone()) .map_err(PoolError::shutdown)?, }; - let frame: Sv2Frame = AnyMessage::Extensions(error.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Extensions(error.into()) .try_into() .map_err(PoolError::shutdown)?; self.downstream_io @@ -118,13 +121,13 @@ impl HandleExtensionsFromClientAsync for Downstream { .set(supported.clone()) .map_err(PoolError::shutdown)?; - let success = RequestExtensionsSuccess { + let success = RequestExtensionsSuccessOwned { request_id: msg.request_id, - supported_extensions: Seq064K::new(supported.clone()) + supported_extensions: Seq064KOwned::new(supported.clone()) .map_err(PoolError::shutdown)?, }; - let frame: Sv2Frame = AnyMessage::Extensions(success.into_static().into()) + let frame: Sv2Frame = AnyMessageOwned::Extensions(success.into()) .try_into() .map_err(PoolError::shutdown)?; self.downstream_io diff --git a/pool-apps/pool/src/lib/downstream/mod.rs b/pool-apps/pool/src/lib/downstream/mod.rs index 00dadd368..73723115b 100644 --- a/pool-apps/pool/src/lib/downstream/mod.rs +++ b/pool-apps/pool/src/lib/downstream/mod.rs @@ -2,6 +2,7 @@ use std::sync::{ atomic::{AtomicBool, AtomicU32}, Arc, }; +use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, MiningOwned}; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ @@ -14,8 +15,10 @@ use stratum_apps::{ }, common_messages_sv2::MESSAGE_TYPE_SETUP_CONNECTION, framing_sv2, - handlers_sv2::{HandleCommonMessagesFromClientAsync, HandleExtensionsFromClientAsync}, - parsers_sv2::{parse_message_frame_with_tlvs, AnyMessage, Mining, Tlv}, + handlers_sv2::{ + HandleCommonMessagesFromClientOwnedAsync, HandleExtensionsFromClientOwnedAsync, + }, + parsers_sv2::{parse_message_frame_with_tlvs, Tlv}, }, sync::{SharedLock, SharedMap}, task_manager::TaskManager, @@ -45,8 +48,8 @@ mod extensions_message_handler; /// - `downstream_receiver`: receives frames from the downstream. #[derive(Clone)] pub struct DownstreamIo { - channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, + channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, downstream_sender: Sender, downstream_receiver: Receiver, } @@ -62,9 +65,9 @@ impl DownstreamIo { /// Represents a downstream client connected to this node. #[derive(Clone)] pub struct Downstream { - pub group_channel: SharedLock>, - pub extended_channels: SharedMap>, - pub standard_channels: SharedMap>, + pub group_channel: SharedLock, + pub extended_channels: SharedMap, + pub standard_channels: SharedMap, pub channel_id_factory: Arc, /// Extensions that have been successfully negotiated with this client pub negotiated_extensions: SharedLock>, @@ -134,9 +137,9 @@ impl Downstream { pub fn new( downstream_id: DownstreamId, channel_id_factory: AtomicU32, - group_channel: GroupChannel<'static>, - channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, - channel_manager_receiver: Receiver<(Mining<'static>, Option>)>, + group_channel: GroupChannel, + channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, + channel_manager_receiver: Receiver<(MiningOwned, Option>)>, noise_stream: NoiseTcpStream, cancellation_token: CancellationToken, task_manager: Arc, @@ -308,7 +311,7 @@ impl Downstream { } }; - let message = AnyMessage::Mining(msg); + let message = AnyMessageOwned::Mining(msg); let std_frame: Sv2Frame = message.try_into().map_err(PoolError::shutdown)?; self.downstream_io @@ -352,8 +355,8 @@ impl Downstream { &negotiated_extensions, ) .map_err(|error| PoolError::disconnect(error, self.downstream_id))?; - let mining_message = match any_message { - AnyMessage::Mining(msg) => msg, + let mining_message = match any_message.into_owned() { + AnyMessageOwned::Mining(msg) => msg, _ => { error!("Expected Mining message but got different type"); return Err(PoolError::disconnect( diff --git a/pool-apps/pool/src/lib/error.rs b/pool-apps/pool/src/lib/error.rs index d5413752f..b8d25abb4 100644 --- a/pool-apps/pool/src/lib/error.rs +++ b/pool-apps/pool/src/lib/error.rs @@ -4,6 +4,7 @@ use std::{ marker::PhantomData, sync::{MutexGuard, PoisonError}, }; +use stratum_apps::stratum_core::parsers_sv2::MiningOwned; use stratum_apps::{ stratum_core::{ @@ -19,7 +20,7 @@ use stratum_apps::{ codec_sv2, framing_sv2, handlers_sv2::HandlerErrorType, noise_sv2, - parsers_sv2::{Mining, ParserError}, + parsers_sv2::ParserError, }, utils::types::{ CanDisconnect, CanShutdown, ChannelId, DownstreamId, ExtensionType, MessageType, @@ -143,7 +144,7 @@ pub enum PoolErrorKind { /// Custom error message. Custom(String), /// Error related to the SV2 protocol, including an error code and a `Mining` message. - Sv2ProtocolError((u32, Mining<'static>)), + Sv2ProtocolError((u32, MiningOwned)), /// Vardiff Error Vardiff(VardiffError), /// Parser Error @@ -367,8 +368,8 @@ impl From>> for PoolErrorKind { } } -impl From<(u32, Mining<'static>)> for PoolErrorKind { - fn from(e: (u32, Mining<'static>)) -> Self { +impl From<(u32, MiningOwned)> for PoolErrorKind { + fn from(e: (u32, MiningOwned)) -> Self { PoolErrorKind::Sv2ProtocolError(e) } } diff --git a/pool-apps/pool/src/lib/pool_runtime.rs b/pool-apps/pool/src/lib/pool_runtime.rs index 413c938ef..ae8509dc4 100644 --- a/pool-apps/pool/src/lib/pool_runtime.rs +++ b/pool-apps/pool/src/lib/pool_runtime.rs @@ -7,6 +7,7 @@ use std::{ sync::{atomic::Ordering, Arc}, thread::JoinHandle, }; +use stratum_apps::stratum_core::parsers_sv2::{MiningOwned, TemplateDistributionOwned}; use async_channel::{unbounded, Receiver, Sender}; @@ -16,7 +17,7 @@ use stratum_apps::{ bitcoin_core_sv2::CancellationToken, stratum_core::{ bitcoin::{consensus::Encodable, TxOut}, - parsers_sv2::{Mining, TemplateDistribution, Tlv}, + parsers_sv2::Tlv, }, task_manager::TaskManager, tp_type::TemplateProviderType, @@ -40,13 +41,12 @@ use crate::{ }; struct Io { - downstream_to_channel_manager_sender: Sender<(DownstreamId, Mining<'static>, Option>)>, - downstream_to_channel_manager_receiver: - Receiver<(DownstreamId, Mining<'static>, Option>)>, - channel_manager_to_tp_sender: Sender>, - channel_manager_to_tp_receiver: Receiver>, - tp_to_channel_manager_sender: Sender>, - tp_to_channel_manager_receiver: Receiver>, + downstream_to_channel_manager_sender: Sender<(DownstreamId, MiningOwned, Option>)>, + downstream_to_channel_manager_receiver: Receiver<(DownstreamId, MiningOwned, Option>)>, + channel_manager_to_tp_sender: Sender, + channel_manager_to_tp_receiver: Receiver, + tp_to_channel_manager_sender: Sender, + tp_to_channel_manager_receiver: Receiver, } struct BitcoinCoreSv2Handle { diff --git a/pool-apps/pool/src/lib/template_receiver/bitcoin_core.rs b/pool-apps/pool/src/lib/template_receiver/bitcoin_core.rs index 02229a9f1..7674cfa74 100644 --- a/pool-apps/pool/src/lib/template_receiver/bitcoin_core.rs +++ b/pool-apps/pool/src/lib/template_receiver/bitcoin_core.rs @@ -5,7 +5,7 @@ use stratum_apps::{ runtime_api::{template_distribution_protocol, BitcoinCoreVersion}, CancellationToken, }, - stratum_core::parsers_sv2::TemplateDistribution, + stratum_core::parsers_sv2::TemplateDistributionOwned, task_manager::TaskManager, }; @@ -15,8 +15,8 @@ pub struct BitcoinCoreSv2TDPConfig { pub unix_socket_path: PathBuf, pub fee_threshold: u64, pub min_interval: u8, - pub incoming_tdp_receiver: Receiver>, - pub outgoing_tdp_sender: Sender>, + pub incoming_tdp_receiver: Receiver, + pub outgoing_tdp_sender: Sender, pub cancellation_token: CancellationToken, } diff --git a/pool-apps/pool/src/lib/template_receiver/sv2_tp/common_message_handler.rs b/pool-apps/pool/src/lib/template_receiver/sv2_tp/common_message_handler.rs index bfa1fedf7..29e53f4c2 100644 --- a/pool-apps/pool/src/lib/template_receiver/sv2_tp/common_message_handler.rs +++ b/pool-apps/pool/src/lib/template_receiver/sv2_tp/common_message_handler.rs @@ -1,8 +1,9 @@ use stratum_apps::stratum_core::{ common_messages_sv2::{ - ChannelEndpointChanged, Reconnect, SetupConnectionError, SetupConnectionSuccess, + ChannelEndpointChangedOwned, ReconnectOwned, SetupConnectionErrorOwned, + SetupConnectionSuccessOwned, }, - handlers_sv2::HandleCommonMessagesFromServerAsync, + handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, parsers_sv2::Tlv, }; use tracing::{error, info}; @@ -13,7 +14,7 @@ use crate::{ }; #[cfg_attr(not(test), hotpath::measure_all)] -impl HandleCommonMessagesFromServerAsync for Sv2Tp { +impl HandleCommonMessagesFromServerOwnedAsync for Sv2Tp { type Error = PoolError; fn get_negotiated_extensions_with_server( @@ -26,7 +27,7 @@ impl HandleCommonMessagesFromServerAsync for Sv2Tp { async fn handle_setup_connection_success( &mut self, _server_id: Option, - msg: SetupConnectionSuccess, + msg: SetupConnectionSuccessOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { info!( @@ -39,7 +40,7 @@ impl HandleCommonMessagesFromServerAsync for Sv2Tp { async fn handle_channel_endpoint_changed( &mut self, _server_id: Option, - msg: ChannelEndpointChanged, + msg: ChannelEndpointChangedOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { info!( @@ -52,17 +53,17 @@ impl HandleCommonMessagesFromServerAsync for Sv2Tp { async fn handle_reconnect( &mut self, _server_id: Option, - msg: Reconnect<'_>, + msg: ReconnectOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { - info!("Received: {}", msg); + info!("Received: {:?}", msg); Ok(()) } async fn handle_setup_connection_error( &mut self, _server_id: Option, - msg: SetupConnectionError<'_>, + msg: SetupConnectionErrorOwned, _tlv_fields: Option<&[Tlv]>, ) -> Result<(), Self::Error> { error!( diff --git a/pool-apps/pool/src/lib/template_receiver/sv2_tp/mod.rs b/pool-apps/pool/src/lib/template_receiver/sv2_tp/mod.rs index ca1d8cac9..a2c10d3f5 100644 --- a/pool-apps/pool/src/lib/template_receiver/sv2_tp/mod.rs +++ b/pool-apps/pool/src/lib/template_receiver/sv2_tp/mod.rs @@ -1,4 +1,5 @@ use std::sync::Arc; +use stratum_apps::stratum_core::parsers_sv2::{AnyMessageOwned, TemplateDistributionOwned}; mod common_message_handler; use async_channel::{unbounded, Receiver, Sender}; use stratum_apps::{ @@ -7,9 +8,8 @@ use stratum_apps::{ key_utils::Secp256k1PublicKey, network_helpers::{self, connect_with_noise, resolve_host_port, TCP_CONNECT_TIMEOUT}, stratum_core::{ - framing_sv2, - handlers_sv2::HandleCommonMessagesFromServerAsync, - parsers_sv2::{AnyMessage, TemplateDistribution}, + framing_sv2, handlers_sv2::HandleCommonMessagesFromServerOwnedAsync, + parsers_sv2::TemplateDistribution, }, task_manager::TaskManager, utils::{ @@ -28,8 +28,8 @@ use crate::{ #[derive(Clone)] pub struct Sv2TpIo { - channel_manager_sender: Sender>, - channel_manager_receiver: Receiver>, + channel_manager_sender: Sender, + channel_manager_receiver: Receiver, tp_sender: Sender, tp_receiver: Receiver, } @@ -89,8 +89,8 @@ impl Sv2Tp { pub async fn new( tp_address: String, public_key: Option, - channel_manager_receiver: Receiver>, - channel_manager_sender: Sender>, + channel_manager_receiver: Receiver, + channel_manager_sender: Sender, cancellation_token: CancellationToken, task_manager: Arc, ) -> PoolResult { @@ -273,7 +273,7 @@ impl Sv2Tp { let message = TemplateDistribution::try_from((header.msg_type(), sv2_frame.payload())) .map_err(PoolError::shutdown)? - .into_static(); + .into_owned(); self.sv2_tp_io .channel_manager_sender @@ -305,7 +305,7 @@ impl Sv2Tp { .recv() .await .map_err(PoolError::shutdown)?; - let message = AnyMessage::TemplateDistribution(msg).into_static(); + let message = AnyMessageOwned::TemplateDistribution(msg); let frame: Sv2Frame = message.try_into().map_err(PoolError::shutdown)?; debug!("Forwarding message from channel manager to outbound_tx"); diff --git a/pool-apps/pool/src/lib/utils.rs b/pool-apps/pool/src/lib/utils.rs index 065f3cf16..9b8206820 100644 --- a/pool-apps/pool/src/lib/utils.rs +++ b/pool-apps/pool/src/lib/utils.rs @@ -1,10 +1,10 @@ use std::{convert::TryFrom, net::SocketAddr}; use stratum_apps::{ stratum_core::{ - binary_sv2::Str0255, - common_messages_sv2::{Protocol, SetupConnection}, - mining_sv2::CloseChannel, - parsers_sv2::{Mining, Tlv}, + binary_sv2::Str0255Owned, + common_messages_sv2::{Protocol, SetupConnectionOwned}, + mining_sv2::CloseChannelOwned, + parsers_sv2::{MiningOwned, Tlv}, }, utils::types::ChannelId, }; @@ -13,7 +13,7 @@ use crate::error::PoolErrorKind; pub use stratum_apps::payout::{PayoutMode, PayoutModeError}; -pub(crate) type DownstreamMessage = (Mining<'static>, Option>); +pub(crate) type DownstreamMessage = (MiningOwned, Option>); /// Constructs a `SetupConnection` message for the mining protocol. #[allow(clippy::result_large_err)] @@ -21,14 +21,14 @@ pub fn get_setup_connection_message( min_version: u16, max_version: u16, address: &SocketAddr, -) -> Result, PoolErrorKind> { +) -> Result { let endpoint_host = address.ip().to_string().try_into()?; let vendor = "".try_into()?; let hardware_version = "".try_into()?; let firmware = "".try_into()?; let device_id = "".try_into()?; let flags = 0b0000_0000_0000_0000_0000_0000_0000_0110; - Ok(SetupConnection { + Ok(SetupConnectionOwned { protocol: Protocol::MiningProtocol, min_version, max_version, @@ -46,13 +46,13 @@ pub fn get_setup_connection_message( #[allow(clippy::result_large_err)] pub fn get_setup_connection_message_tp( address: SocketAddr, -) -> Result, PoolErrorKind> { +) -> Result { let endpoint_host = address.ip().to_string().try_into()?; let vendor = "".try_into()?; let hardware_version = "".try_into()?; let firmware = "".try_into()?; let device_id = "".try_into()?; - Ok(SetupConnection { + Ok(SetupConnectionOwned { protocol: Protocol::TemplateDistributionProtocol, min_version: 2, max_version: 2, @@ -70,9 +70,9 @@ pub fn get_setup_connection_message_tp( /// /// The `msg` is converted into a [`Str0255`] reason code. /// If conversion fails, this function will panic. -pub(crate) fn create_close_channel_msg(channel_id: ChannelId, msg: &str) -> CloseChannel<'_> { - CloseChannel { +pub(crate) fn create_close_channel_msg(channel_id: ChannelId, msg: &str) -> CloseChannelOwned { + CloseChannelOwned { channel_id, - reason_code: Str0255::try_from(msg).expect("Could not convert message."), + reason_code: Str0255Owned::try_from(msg).expect("Could not convert message."), } } diff --git a/stratum-apps/Cargo.lock b/stratum-apps/Cargo.lock index e52a10f5e..7d848d12f 100644 --- a/stratum-apps/Cargo.lock +++ b/stratum-apps/Cargo.lock @@ -773,8 +773,8 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "binary_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "buffer_sv2", "derive_codec_sv2", @@ -940,7 +940,7 @@ dependencies = [ [[package]] name = "buffer_sv2" version = "3.0.1" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", ] @@ -1070,8 +1070,8 @@ dependencies = [ [[package]] name = "channels_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -1116,8 +1116,8 @@ dependencies = [ [[package]] name = "codec_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1139,8 +1139,8 @@ dependencies = [ [[package]] name = "common_messages_sv2" -version = "8.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "9.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1340,8 +1340,8 @@ dependencies = [ [[package]] name = "derive_codec_sv2" -version = "1.1.3" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "2.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" [[package]] name = "digest" @@ -1481,8 +1481,8 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "extensions_sv2" -version = "0.2.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.3.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -1539,8 +1539,8 @@ dependencies = [ [[package]] name = "framing_sv2" -version = "7.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "8.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "buffer_sv2", @@ -1710,8 +1710,8 @@ dependencies = [ [[package]] name = "handlers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -2139,8 +2139,8 @@ dependencies = [ [[package]] name = "job_declaration_sv2" -version = "9.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "10.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -2327,8 +2327,8 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining_sv2" -version = "11.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "12.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] @@ -2368,7 +2368,7 @@ dependencies = [ [[package]] name = "noise_sv2" version = "1.4.2" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "aes-gcm", "chacha20poly1305", @@ -2491,8 +2491,8 @@ dependencies = [ [[package]] name = "parsers_sv2" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "common_messages_sv2", @@ -3441,8 +3441,8 @@ dependencies = [ [[package]] name = "stratum-core" -version = "0.5.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.6.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -3464,8 +3464,8 @@ dependencies = [ [[package]] name = "stratum_translation" -version = "0.4.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "0.5.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -3505,8 +3505,8 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sv1_api" -version = "5.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "6.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", "bitcoin", @@ -3561,8 +3561,8 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "template_distribution_sv2" -version = "6.0.0" -source = "git+https://github.com/stratum-mining/stratum?branch=main#3519557cd154d471d3efeff72473735f9f4ea58c" +version = "7.0.0" +source = "git+https://github.com/Shourya742/stratum?branch=2026-07-13-split-inner#db2d873ce01b5f82cc971df4bf03d0ab78a5cf8c" dependencies = [ "binary_sv2", ] diff --git a/stratum-apps/Cargo.toml b/stratum-apps/Cargo.toml index 4fe348a50..e469001d4 100644 --- a/stratum-apps/Cargo.toml +++ b/stratum-apps/Cargo.toml @@ -16,7 +16,8 @@ keywords = ["stratum", "mining", "bitcoin", "protocol", "sv2"] # fetching from github enables synchronizing development workflows across sv2-apps and stratum repos # it MUST be changed before stratum-apps is published to crates.io # with the proper version of stratum-core being fetched from crates.io as well -stratum-core = { git = "https://github.com/stratum-mining/stratum", branch = "main", optional = true } +stratum-core = { git = "https://github.com/Shourya742/stratum", branch = "2026-07-13-split-inner", optional = true } + bitcoin-core-sv2 = { package = "bitcoin_core_sv2", version = "0.5.0", path = "../bitcoin-core-sv2", optional = true } # External dependencies needed by the modules diff --git a/stratum-apps/src/coinbase_output_constraints.rs b/stratum-apps/src/coinbase_output_constraints.rs index 35068413c..7c6f53de9 100644 --- a/stratum-apps/src/coinbase_output_constraints.rs +++ b/stratum-apps/src/coinbase_output_constraints.rs @@ -5,7 +5,7 @@ use stratum_core::{ transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut, Version}, witness::Witness, }, - template_distribution_sv2::CoinbaseOutputConstraints, + template_distribution_sv2::CoinbaseOutputConstraintsOwned, }; /// Offset added to the calculated max size to account for the additional space required by @@ -39,7 +39,7 @@ const OFFSET_MAX_SIGOPS: u16 = 4; /// CoinbaseOutputConstraints with exact size and sigops values based on the provided outputs pub fn coinbase_output_constraints_message( coinbase_outputs: Vec, -) -> CoinbaseOutputConstraints { +) -> CoinbaseOutputConstraintsOwned { // calculate the max coinbase output size for CoinbaseOutputConstraints let max_size: u32 = coinbase_outputs.iter().map(|o| o.size() as u32).sum(); tracing::debug!( @@ -65,7 +65,7 @@ pub fn coinbase_output_constraints_message( let max_sigops = dummy_coinbase.total_sigop_cost(|_| None) as u16; tracing::debug!(max_sigops, "Calculated max sigops for coinbase"); - CoinbaseOutputConstraints { + CoinbaseOutputConstraintsOwned { coinbase_output_max_additional_size: max_size, coinbase_output_max_additional_sigops: max_sigops, } @@ -93,10 +93,10 @@ pub fn coinbase_output_constraints_message( /// - **Sigops**: +4 to accommodate Pay-to-Public-Key-Hash (p2pkh) addresses pub fn coinbase_output_constraints_message_with_offset( coinbase_outputs: Vec, -) -> CoinbaseOutputConstraints { +) -> CoinbaseOutputConstraintsOwned { let constraints = coinbase_output_constraints_message(coinbase_outputs); - CoinbaseOutputConstraints { + CoinbaseOutputConstraintsOwned { coinbase_output_max_additional_size: constraints.coinbase_output_max_additional_size + OFFSET_ADDITIONAL_SIZE, coinbase_output_max_additional_sigops: constraints.coinbase_output_max_additional_sigops diff --git a/stratum-apps/src/network_helpers/mod.rs b/stratum-apps/src/network_helpers/mod.rs index eb7b6a382..402b4f2a2 100644 --- a/stratum-apps/src/network_helpers/mod.rs +++ b/stratum-apps/src/network_helpers/mod.rs @@ -122,7 +122,7 @@ pub async fn connect_with_noise( authority_pub_key: Option, ) -> Result, Error> where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { let initiator = match authority_pub_key { Some(key) => Initiator::from_raw_k(key.into_bytes()).map_err(|_| Error::InvalidKey)?, @@ -151,7 +151,7 @@ pub async fn accept_noise_connection( cert_validity: u64, ) -> Result, Error> where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { let responder = Responder::from_authority_kp( &pub_key.into_bytes(), diff --git a/stratum-apps/src/network_helpers/noise_connection.rs b/stratum-apps/src/network_helpers/noise_connection.rs index d7a0768e5..bd2ad52f7 100644 --- a/stratum-apps/src/network_helpers/noise_connection.rs +++ b/stratum-apps/src/network_helpers/noise_connection.rs @@ -42,7 +42,7 @@ impl Connection { Error, > where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { let (sender_incoming, receiver_incoming) = unbounded(); let (sender_outgoing, receiver_outgoing) = unbounded(); @@ -69,7 +69,7 @@ impl Connection { conn_state: Arc>, ) -> task::JoinHandle<()> where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { let sender_incoming = conn_state.sender_incoming.clone(); @@ -104,7 +104,7 @@ impl Connection { conn_state: Arc>, ) -> task::JoinHandle<()> where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { let receiver_outgoing = conn_state.receiver_outgoing.clone(); diff --git a/stratum-apps/src/network_helpers/noise_stream.rs b/stratum-apps/src/network_helpers/noise_stream.rs index b929876f7..c329d53f1 100644 --- a/stratum-apps/src/network_helpers/noise_stream.rs +++ b/stratum-apps/src/network_helpers/noise_stream.rs @@ -38,7 +38,9 @@ use tracing::{debug, error}; /// If `read_frame()` or `write_frame()` is canceled mid-way, /// internal state may be left in an inconsistent state, which can lead to /// protocol errors or dropped frames. -pub struct NoiseTcpStream + GetSize + Send + 'static> { +pub struct NoiseTcpStream< + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, +> { reader: NoiseTcpReadHalf, writer: NoiseTcpWriteHalf, } @@ -47,7 +49,9 @@ pub struct NoiseTcpStream + GetSize + /// /// It buffers incoming encrypted bytes, attempts to decode full Noise frames, /// and exposes a method to retrieve structured messages of type `Message`. -pub struct NoiseTcpReadHalf + GetSize + Send + 'static> { +pub struct NoiseTcpReadHalf< + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, +> { reader: OwnedReadHalf, decoder: StandardNoiseDecoder, state: State, @@ -59,7 +63,9 @@ pub struct NoiseTcpReadHalf + GetSize /// /// It accepts structured messages, encodes them via the Noise protocol, /// and writes the result to the socket. -pub struct NoiseTcpWriteHalf + GetSize + Send + 'static> { +pub struct NoiseTcpWriteHalf< + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, +> { writer: OwnedWriteHalf, encoder: NoiseEncoder, state: State, @@ -67,7 +73,7 @@ pub struct NoiseTcpWriteHalf + GetSize impl NoiseTcpStream where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { /// Constructs a new `NoiseTcpStream` over the given TCP stream, /// performing the Noise handshake in the given `role`. @@ -181,7 +187,7 @@ where impl NoiseTcpWriteHalf where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { /// Encrypts and writes a full message frame to the socket. /// @@ -227,7 +233,7 @@ where impl NoiseTcpReadHalf where - Message: Serialize + Deserialize<'static> + GetSize + Send + 'static, + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, { /// Reads and decodes a complete frame from the socket. /// @@ -317,7 +323,9 @@ where } } -async fn send_message + GetSize + Send + 'static>( +async fn send_message< + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, +>( writer: &mut OwnedWriteHalf, msg: StandardEitherFrame, state: &mut State, @@ -331,7 +339,9 @@ async fn send_message + GetSize + Send Ok(()) } -async fn receive_message + GetSize + Send + 'static>( +async fn receive_message< + Message: Serialize + for<'decoder> Deserialize<'decoder> + GetSize + Send + 'static, +>( reader: &mut OwnedReadHalf, state: &mut State, decoder: &mut StandardNoiseDecoder, diff --git a/stratum-apps/src/utils/types.rs b/stratum-apps/src/utils/types.rs index ddcec4cb8..5676181de 100644 --- a/stratum-apps/src/utils/types.rs +++ b/stratum-apps/src/utils/types.rs @@ -1,4 +1,4 @@ -use stratum_core::{codec_sv2::StandardSv2Frame, parsers_sv2::AnyMessage}; +use stratum_core::{codec_sv2::StandardSv2Frame, parsers_sv2::AnyMessageOwned}; pub const GRACEFUL_SHUTDOWN_TIMEOUT_SECONDS: u64 = 5; @@ -15,7 +15,7 @@ pub type ExtensionType = u16; pub type MessageType = u8; pub type JdToken = u64; -pub type Message = AnyMessage<'static>; +pub type Message = AnyMessageOwned; pub type Sv2Frame = StandardSv2Frame; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]