diff --git a/protocols/v2/roles-logic-sv2/src/handlers/common.rs b/protocols/v2/roles-logic-sv2/src/handlers/common.rs index c2fb4ceb6..a520b8ca7 100644 --- a/protocols/v2/roles-logic-sv2/src/handlers/common.rs +++ b/protocols/v2/roles-logic-sv2/src/handlers/common.rs @@ -1,3 +1,36 @@ +//! # Common Handlers +//! +//! This module defines traits and implementations for handling common Stratum V2 messages exchanged +//! between upstream and downstream nodes. +//! +//! ## Core Traits +//! +//! - `ParseUpstreamCommonMessages`: Implemented by downstream nodes to handle common messages +//! received from upstream nodes, such as setup connection results or channel endpoint changes. +//! - `ParseDownstreamCommonMessages`: Implemented by upstream nodes to process setup connection +//! messages received from downstream nodes. +//! +//! ## Message Handling +//! +//! Handlers in this module are responsible for: +//! - Parsing and deserializing common messages. +//! - Dispatching deserialized messages to appropriate handler functions based on message type, such +//! as `SetupConnection` or `ChannelEndpointChanged`. +//! - Ensuring robust error handling for unexpected or malformed messages. +//! +//! ## Return Type +//! +//! Functions return `Result`, where `SendTo` specifies the next action for the +//! message: whether to forward it, respond to it, or ignore it. +//! +//! ## Structure +//! +//! This module includes: +//! - Traits for upstream and downstream message parsing and handling. +//! - Functions to process common message types while maintaining clear separation of concerns. +//! - Error handling mechanisms to address edge cases and ensure reliable communication within +//! Stratum V2 networks. + use super::SendTo_; use crate::{ common_properties::CommonDownstreamData, @@ -41,6 +74,7 @@ where routing_logic, ) } + /// Takes a message and it calls the appropriate handler function /// /// Arguments: @@ -86,19 +120,43 @@ where } } - /// Called by `Self::handle_message_common` when the `SetupConnectionSuccess` message is - /// received from the upstream node. + /// Handles a `SetupConnectionSuccess` message. + /// + /// This method processes a `SetupConnectionSuccess` message and handles it + /// by delegating to the appropriate handler. + /// + /// # Arguments + /// - `message`: The `SetupConnectionSuccess` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_setup_connection_success( &mut self, m: SetupConnectionSuccess, ) -> Result; - /// Called by `Self::handle_message_common` when the `SetupConnectionError` message is received - /// from the upstream node. + /// Handles a `SetupConnectionError` message. + /// + /// This method processes a `SetupConnectionError` message and handles it + /// by delegating to the appropriate handler. + /// + /// # Arguments + /// - `message`: The `SetupConnectionError` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_setup_connection_error(&mut self, m: SetupConnectionError) -> Result; - /// Called by `Self::handle_message_common` when the `ChannelEndpointChanged` message is - /// received from the upstream node. + /// Handles a `ChannelEndpointChanged` message. + /// + /// This method processes a `ChannelEndpointChanged` message and handles it + /// by delegating to the appropriate handler. + /// + /// # Arguments + /// - `message`: The `ChannelEndpointChanged` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_channel_endpoint_changed( &mut self, m: ChannelEndpointChanged, @@ -129,6 +187,7 @@ where Err(e) => Err(e), } } + /// It takes a message type and a payload, and if the message is a serialized setup connection /// message, it calls the `on_setup_connection` function on the routing logic, and then calls /// the `handle_setup_connection` function on the router @@ -150,8 +209,8 @@ where } /// It takes a message do setup connection message, it calls - /// the `on_setup_connection` function on the routing logic, and then calls the - /// `handle_setup_connection` function on the router + /// the `on_setup_connection` function on the routing logic, and then calls + /// the `handle_setup_connection` function on the router fn handle_message_common_deserilized( self_: Arc>, message: Result, Error>, @@ -192,8 +251,17 @@ where } } - /// Called by `Self::handle_message_common` when a setup connection message is received from the - /// downstream node. + /// Handles a `SetupConnection` message. + /// + /// This method processes a `SetupConnection` message and handles it + /// by delegating to the appropriate handler in the routing logic. + /// + /// # Arguments + /// - `message`: The `SetupConnection` message. + /// - `result`: The result of the `on_setup_connection` call, if available. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_setup_connection( &mut self, m: SetupConnection, diff --git a/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs b/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs index 61044fa15..f0453fd8d 100644 --- a/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs +++ b/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs @@ -1,3 +1,44 @@ +//! # Job Declaration Handlers +//! +//! This module defines traits and functions for handling job declaration messages within the +//! Stratum V2 protocol. The job declaration process is integral to managing mining tasks and +//! transactions between server and client components. +//! +//! ## Core Traits +//! +//! - `ParseServerJobDeclarationMessages`: This trait is implemented by downstream nodes to process +//! job declaration messages received from upstream nodes. The trait includes methods for handling +//! job-related events such as mining job token allocation, job declaration successes or errors, +//! and transaction identification or provisioning. +//! - `ParseClientJobDeclarationMessages`: This trait is implemented by upstream nodes to manage job +//! declaration messages received from downstream nodes. It facilitates the handling of job +//! declarations, mining job token allocation, and transaction solutions submitted by downstream +//! nodes. +//! +//! ## Message Handling +//! +//! The handlers are responsible for the following tasks: +//! - Parsing and deserializing job declaration messages into appropriate types. +//! - Dispatching the deserialized messages to specific handler functions based on their type, such +//! as handling job token allocation, job declaration success or error responses, and transaction +//! data management. +//! +//! ## Return Type +//! +//! The functions return a `Result`. The `SendTo` type determines the next action for +//! the message: whether the message should be relayed, responded to, or ignored. If an error occurs +//! during processing, the `Error` type is returned. +//! +//! ## Structure +//! +//! This module contains: +//! - Traits for processing job declaration messages, covering both server-side and client-side +//! handling. +//! - Functions designed to parse, deserialize, and process messages related to job declarations, +//! with robust error handling. +//! - Error handling mechanisms to address unexpected messages and ensure safe processing, +//! particularly in the context of shared state. + use crate::{parsers::JobDeclaration, utils::Mutex}; use std::sync::Arc; pub type SendTo = SendTo_, ()>; @@ -7,12 +48,25 @@ use core::convert::TryInto; use job_declaration_sv2::*; use tracing::{debug, error, info, trace}; -/// A trait implemented by a downstream to handle SV2 job declaration messages. +/// A trait for parsing and handling SV2 job declaration messages sent by a server. +/// +/// This trait is designed to be implemented by downstream components that need to handle +/// various job declaration messages from an upstream SV2 server, such as job allocation, +/// declaration success, and error messages. pub trait ParseServerJobDeclarationMessages where Self: Sized, { - /// Used to parse job declaration message and route to the message's respected handler function + /// Routes an incoming job declaration message to the appropriate handler function. + /// + /// # Parameters + /// - `self_`: An `Arc>` instance to ensure thread-safe access to the implementor. + /// - `message_type`: The type identifier of the incoming message. + /// - `payload`: A mutable slice containing the message payload. + /// + /// # Returns + /// - `Ok(SendTo)`: Indicates the message was successfully handled. + /// - `Err(Error)`: Indicates an error occurred during message parsing or handling. fn handle_message_job_declaration( self_: Arc>, message_type: u8, @@ -21,6 +75,16 @@ where Self::handle_message_job_declaration_deserialized(self_, (message_type, payload).try_into()) } + /// Routes a deserialized job declaration message to the appropriate handler function. + /// + /// # Parameters + /// - `self_`: An `Arc>` instance to ensure thread-safe access to the implementor. + /// - `message`: A `Result` containing either the parsed message or an + /// error. + /// + /// # Returns + /// - `Ok(SendTo)`: Indicates the message was successfully handled. + /// - `Err(Error)`: Indicates an error occurred during message parsing or handling. fn handle_message_job_declaration_deserialized( self_: Arc>, message: Result, Error>, @@ -81,44 +145,95 @@ where Err(e) => Err(e), } } - /// When upstream send AllocateMiningJobTokenSuccess self should use the received token to - /// negotiate the next job + + /// Handles an `AllocateMiningJobTokenSuccess` message. /// - /// "[`job_declaration_sv2::AllocateMiningJobToken`]" + /// This method processes a message indicating a successful job token allocation. + /// + /// # Arguments + /// - `message`: The `AllocateMiningJobTokenSuccess` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_allocate_mining_job_token_success( &mut self, message: AllocateMiningJobTokenSuccess, ) -> Result; - // When upstream send DeclareMiningJobSuccess if the token is different from the one negotiated - // self must use the new token to refer to the committed job + /// Handles a `DeclareMiningJobSuccess` message. + /// + /// This method processes a message indicating a successful mining job declaration. + /// + /// # Arguments + /// - `message`: The `DeclareMiningJobSuccess` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_declare_mining_job_success( &mut self, message: DeclareMiningJobSuccess, ) -> Result; - // TODO: comment + /// Handles a `DeclareMiningJobError` message. + /// + /// This method processes a message indicating an error in the mining job declaration process. + /// + /// # Arguments + /// - `message`: The `DeclareMiningJobError` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_declare_mining_job_error( &mut self, message: DeclareMiningJobError, ) -> Result; - // TODO: comment + /// Handles an `IdentifyTransactions` message. + /// + /// This method processes a message that provides transaction identification data. + /// + /// # Arguments + /// - `message`: The `IdentifyTransactions` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_identify_transactions( &mut self, message: IdentifyTransactions, ) -> Result; - // TODO: comment + /// Handles a `ProvideMissingTransactions` message. + /// + /// This method processes a message that supplies missing transaction data. + /// + /// # Arguments + /// - `message`: The `ProvideMissingTransactions` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_provide_missing_transactions( &mut self, message: ProvideMissingTransactions, ) -> Result; } + +/// The `ParseClientJobDeclarationMessages` trait is responsible for handling job declaration +/// messages sent by clients to upstream nodes. The methods process messages like job declarations, +/// solutions, and transaction success indicators, ensuring proper routing and handling. pub trait ParseClientJobDeclarationMessages where Self: Sized, { + /// Routes an incoming job declaration message to the appropriate handler function. + /// + /// # Parameters + /// - `self_`: An `Arc>` instance to ensure thread-safe access to the implementor. + /// - `message_type`: The type identifier of the incoming message. + /// - `payload`: A mutable slice containing the message payload. + /// + /// # Returns + /// - `Ok(SendTo)`: Indicates the message was successfully handled. + /// - `Err(Error)`: Indicates an error occurred during message parsing or handling. fn handle_message_job_declaration( self_: Arc>, message_type: u8, @@ -127,6 +242,16 @@ where Self::handle_message_job_declaration_deserialized(self_, (message_type, payload).try_into()) } + /// Routes a deserialized job declaration message to the appropriate handler function. + /// + /// # Parameters + /// - `self_`: An `Arc>` instance to ensure thread-safe access to the implementor. + /// - `message`: A `Result` containing either the parsed message or an + /// error. + /// + /// # Returns + /// - `Ok(SendTo)`: Indicates the message was successfully handled. + /// - `Err(Error)`: Indicates an error occurred during message parsing or handling. fn handle_message_job_declaration_deserialized( self_: Arc>, message: Result, Error>, @@ -176,27 +301,72 @@ where .safe_lock(|x| x.handle_submit_solution(message)) .map_err(|e| crate::Error::PoisonLock(e.to_string()))? } - Ok(_) => todo!(), Err(e) => Err(e), } } + /// Handles an `AllocateMiningJobToken` message. + /// + /// This method processes a message that allocates a mining job token. + /// + /// # Arguments + /// - `message`: The `AllocateMiningJobToken` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_allocate_mining_job_token( &mut self, message: AllocateMiningJobToken, ) -> Result; + /// Handles a `DeclareMiningJob` message. + /// + /// This method processes a message that declares a new mining job. + /// + /// # Arguments + /// - `message`: The `DeclareMiningJob` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_declare_mining_job(&mut self, message: DeclareMiningJob) -> Result; + /// Handles an `IdentifyTransactionsSuccess` message. + /// + /// This method processes a message that confirms the identification of transactions. + /// + /// # Arguments + /// - `message`: The `IdentifyTransactionsSuccess` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_identify_transactions_success( &mut self, message: IdentifyTransactionsSuccess, ) -> Result; + /// Handles a `ProvideMissingTransactionsSuccess` message. + /// + /// This method processes a message that confirms the receipt of missing transactions. + /// + /// # Arguments + /// - `message`: The `ProvideMissingTransactionsSuccess` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_provide_missing_transactions_success( &mut self, message: ProvideMissingTransactionsSuccess, ) -> Result; + + /// Handles a `SubmitSolution` message. + /// + /// This method processes a message that submits a solution for the mining job. + /// + /// # Arguments + /// - `message`: The `SubmitSolutionJd` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_submit_solution(&mut self, message: SubmitSolutionJd) -> Result; } diff --git a/protocols/v2/roles-logic-sv2/src/handlers/mining.rs b/protocols/v2/roles-logic-sv2/src/handlers/mining.rs index b5ec45e16..918a32405 100644 --- a/protocols/v2/roles-logic-sv2/src/handlers/mining.rs +++ b/protocols/v2/roles-logic-sv2/src/handlers/mining.rs @@ -1,3 +1,41 @@ +//! # Mining Handlers +//! +//! This module defines traits and functions for handling mining-related messages within the Stratum +//! V2 protocol. +//! +//! ## Core Traits +//! +//! - `ParseUpstreamMiningMessages`: Implemented by downstream nodes to process mining messages +//! received from upstream nodes. This trait provides methods for handling mining events like new +//! mining jobs, share submissions, extranonce prefix updates, and channel status updates. +//! - `ParseDownstreamMiningMessages`: Implemented by upstream nodes to manage mining messages +//! received from downstream nodes. This trait includes methods for managing tasks such as +//! submitting shares, opening mining channels, and handling mining job responses. +//! +//! ## Message Handling +//! +//! Handlers in this module are responsible for: +//! - Parsing and deserializing mining-related messages into the appropriate types. +//! - Dispatching the deserialized messages to specific handler functions based on message type, +//! such as handling new mining jobs, share submissions, and extranonce updates. +//! - Ensuring the integrity and validity of received messages, while interacting with downstream +//! mining systems to ensure proper communication and task execution. +//! +//! ## Return Type +//! +//! Functions return `Result, Error>`, where `SendTo` specifies the next action +//! for the message: whether it should be sent to the downstream node, an error response should be +//! generated, or the message should be ignored. +//! +//! ## Structure +//! +//! This module includes: +//! - Traits for processing mining-related messages for both upstream and downstream communication. +//! - Functions to parse, deserialize, and process messages related to mining, ensuring robust error +//! handling for unexpected conditions. +//! - Support for managing mining channels, extranonce prefixes, and share submissions, while +//! handling edge cases and ensuring the correctness of the mining process. + use crate::{common_properties::RequestIdMapper, errors::Error, parsers::Mining}; use core::convert::TryInto; use mining_sv2::{ @@ -24,16 +62,20 @@ use tracing::{debug, error, info, trace}; pub type SendTo = SendTo_, Remote>; +/// Represents supported channel types in a mining connection. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum SupportedChannelTypes { Standard, Extended, Group, - // Non header only connection can support both group and extended channels. + /// Represents a connection that supports both group and extended channels. GroupAndExtended, } -/// Connection-wide downtream's messages parser implemented by an upstream. +/// Trait for parsing downstream mining messages in a Stratum V2 connection. +/// +/// This trait defines methods for parsing and routing downstream messages +/// related to mining operations. pub trait ParseDownstreamMiningMessages< Up: IsMiningUpstream + D, Selector: DownstreamMiningSelector + D, @@ -41,10 +83,19 @@ pub trait ParseDownstreamMiningMessages< > where Self: IsMiningDownstream + Sized + D, { + /// Returns the type of channel supported by the downstream connection. fn get_channel_type(&self) -> SupportedChannelTypes; - /// Used to parse and route SV2 mining messages from the downstream based on `message_type` and - /// `payload` + /// Handles a mining message from the downstream, given its type and payload. + /// + /// # Arguments + /// - `self_mutex`: The `Arc>` representing the downstream entity. + /// - `message_type`: The type of the mining message. + /// - `payload`: The raw payload of the message. + /// - `routing_logic`: The logic for routing the message to the appropriate upstream entity. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_message_mining( self_mutex: Arc>, message_type: u8, @@ -64,7 +115,15 @@ pub trait ParseDownstreamMiningMessages< } } - /// Used to route SV2 mining messages from the downstream + /// Deserializes and processes a mining message from the downstream. + /// + /// # Arguments + /// - `self_mutex`: The `Arc>` representing the downstream entity. + /// - `message`: The mining message to be processed. + /// - `routing_logic`: The logic for routing the message to the appropriate upstream entity. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_message_mining_deserialized( self_mutex: Arc>, message: Result, Error>, @@ -265,9 +324,20 @@ pub trait ParseDownstreamMiningMessages< } } + /// Checks if work selection is enabled for the downstream connection. + /// + /// # Returns + /// - `bool`: `true` if work selection is enabled, `false` otherwise. fn is_work_selection_enabled(&self) -> bool; - /// returns None if the user is authorized and Open + /// Checks if the downstream user is authorized. + /// + /// # Arguments + /// - `_self_mutex`: The `Arc>` representing the downstream entity. + /// - `_user_identity`: The user's identity to be checked. + /// + /// # Returns + /// - `Result`: `true` if the user is authorized, `false` otherwise. fn is_downstream_authorized( _self_mutex: Arc>, _user_identity: &binary_sv2::Str0255, @@ -275,32 +345,94 @@ pub trait ParseDownstreamMiningMessages< Ok(true) } + /// Handles an `OpenStandardMiningChannel` message. + /// + /// This method processes an `OpenStandardMiningChannel` message and initiates the + /// appropriate response. + /// + /// # Arguments + /// - `m`: The `OpenStandardMiningChannel` message. + /// - `up`: An optional upstream entity to which the message is forwarded. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_open_standard_mining_channel( &mut self, m: OpenStandardMiningChannel, up: Option>>, ) -> Result, Error>; + /// Handles an `OpenExtendedMiningChannel` message. + /// + /// This method processes an `OpenExtendedMiningChannel` message and initiates the + /// appropriate response. + /// + /// # Arguments + /// - `m`: The `OpenExtendedMiningChannel` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_open_extended_mining_channel( &mut self, m: OpenExtendedMiningChannel, ) -> Result, Error>; + /// Handles an `UpdateChannel` message. + /// + /// This method processes an `UpdateChannel` message and updates the channel settings. + /// + /// # Arguments + /// - `m`: The `UpdateChannel` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_update_channel(&mut self, m: UpdateChannel) -> Result, Error>; + /// Handles a `SubmitSharesStandard` message. + /// + /// This method processes a `SubmitSharesStandard` message and validates the submitted shares. + /// + /// # Arguments + /// - `m`: The `SubmitSharesStandard` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_submit_shares_standard( &mut self, m: SubmitSharesStandard, ) -> Result, Error>; + /// Handles a `SubmitSharesExtended` message. + /// + /// This method processes a `SubmitSharesExtended` message and validates the submitted shares. + /// + /// # Arguments + /// - `m`: The `SubmitSharesExtended` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_submit_shares_extended( &mut self, m: SubmitSharesExtended, ) -> Result, Error>; + /// Handles a `SetCustomMiningJob` message. + /// + /// This method processes a `SetCustomMiningJob` message and applies the custom mining job + /// settings. + /// + /// # Arguments + /// - `m`: The `SetCustomMiningJob` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_set_custom_mining_job(&mut self, m: SetCustomMiningJob) -> Result, Error>; } -/// Connection-wide upstream's messages parser implemented by a downstream. + +/// A trait defining the parser for upstream mining messages used by a downstream. +/// +/// This trait provides the functionality to handle and route various types of mining messages +/// from the upstream based on the message type and payload. pub trait ParseUpstreamMiningMessages< Down: IsMiningDownstream + D, Selector: DownstreamMiningSelector + D, @@ -308,16 +440,35 @@ pub trait ParseUpstreamMiningMessages< > where Self: IsMiningUpstream + Sized + D, { + /// Retrieves the type of the channel supported by this upstream parser. + /// + /// # Returns + /// - `SupportedChannelTypes`: The supported channel type for this upstream. fn get_channel_type(&self) -> SupportedChannelTypes; + /// Retrieves an optional RequestIdMapper, used to manage request IDs across connections. + /// + /// # Returns + /// - `Option>>`: An optional RequestIdMapper for request ID + /// modification. fn get_request_id_mapper(&mut self) -> Option>> { None } - /// Used to parse and route SV2 mining messages from the upstream based on `message_type` and - /// `payload` The implementor of DownstreamMining needs to pass a RequestIdMapper if needing - /// to change the req id. Proxies likely would want to update a downstream req id to a new - /// one as req id must be connection-wide unique + /// Parses and routes SV2 mining messages from the upstream based on the message type and + /// payload. The implementor of DownstreamMining needs to pass a RequestIdMapper if changing + /// the request ID. Proxies typically need this to ensure the request ID is unique across + /// the connection. + /// + /// # Arguments + /// - `self_mutex`: The `Arc>` representing the downstream entity. + /// - `message_type`: The type of the incoming message. + /// - `payload`: The payload containing the message data. + /// - `routing_logic`: The logic to handle the routing of the message based on the type. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message, either sending a + /// response or an error. fn handle_message_mining( self_mutex: Arc>, message_type: u8, @@ -334,6 +485,17 @@ pub trait ParseUpstreamMiningMessages< } } + /// Handles the deserialized mining message from the upstream, processing it according to the + /// routing logic. + /// + /// # Arguments + /// - `self_mutex`: The `Arc>` representing the downstream entity. + /// - `message`: The deserialized mining message, wrapped in a Result for error handling. + /// - `routing_logic`: The logic used to route the message based on the type. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message, either sending a + /// response or an error. fn handle_message_mining_deserialized( self_mutex: Arc>, message: Result, @@ -673,64 +835,181 @@ pub trait ParseUpstreamMiningMessages< } } + /// Determines whether work selection is enabled for this upstream. + /// + /// # Returns + /// - `bool`: A boolean indicating if work selection is enabled. fn is_work_selection_enabled(&self) -> bool; + /// Handles a successful response for opening a standard mining channel. + /// + /// # Arguments + /// - `m`: The `OpenStandardMiningChannelSuccess` message. + /// - `remote`: An optional reference to the downstream, wrapped in an `Arc`. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_open_standard_mining_channel_success( &mut self, m: OpenStandardMiningChannelSuccess, remote: Option>>, ) -> Result, Error>; + /// Handles a successful response for opening an extended mining channel. + /// + /// # Arguments + /// - `m`: The `OpenExtendedMiningChannelSuccess` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_open_extended_mining_channel_success( &mut self, m: OpenExtendedMiningChannelSuccess, ) -> Result, Error>; + /// Handles an error when opening a mining channel. + /// + /// # Arguments + /// - `m`: The `OpenMiningChannelError` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the error. fn handle_open_mining_channel_error( &mut self, m: OpenMiningChannelError, ) -> Result, Error>; + /// Handles an error when updating a mining channel. + /// + /// # Arguments + /// - `m`: The `UpdateChannelError` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the error. fn handle_update_channel_error(&mut self, m: UpdateChannelError) -> Result, Error>; + /// Handles a request to close a mining channel. + /// + /// # Arguments + /// - `m`: The `CloseChannel` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_close_channel(&mut self, m: CloseChannel) -> Result, Error>; + /// Handles a request to set the extranonce prefix for mining. + /// + /// # Arguments + /// - `m`: The `SetExtranoncePrefix` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_set_extranonce_prefix( &mut self, m: SetExtranoncePrefix, ) -> Result, Error>; + /// Handles a successful submission of shares. + /// + /// # Arguments + /// - `m`: The `SubmitSharesSuccess` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_submit_shares_success( &mut self, m: SubmitSharesSuccess, ) -> Result, Error>; + /// Handles an error when submitting shares. + /// + /// # Arguments + /// - `m`: The `SubmitSharesError` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the error. fn handle_submit_shares_error(&mut self, m: SubmitSharesError) -> Result, Error>; + /// Handles a new mining job. + /// + /// # Arguments + /// - `m`: The `NewMiningJob` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_new_mining_job(&mut self, m: NewMiningJob) -> Result, Error>; + /// Handles a new extended mining job. + /// + /// # Arguments + /// - `m`: The `NewExtendedMiningJob` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_new_extended_mining_job( &mut self, m: NewExtendedMiningJob, ) -> Result, Error>; + /// Handles a request to set the new previous hash. + /// + /// # Arguments + /// - `m`: The `SetNewPrevHash` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_set_new_prev_hash(&mut self, m: SetNewPrevHash) -> Result, Error>; + /// Handles a successful response for setting a custom mining job. + /// + /// # Arguments + /// - `m`: The `SetCustomMiningJobSuccess` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_set_custom_mining_job_success( &mut self, m: SetCustomMiningJobSuccess, ) -> Result, Error>; + /// Handles an error when setting a custom mining job. + /// + /// # Arguments + /// - `m`: The `SetCustomMiningJobError` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the error. fn handle_set_custom_mining_job_error( &mut self, m: SetCustomMiningJobError, ) -> Result, Error>; + /// Handles a request to set the target for mining. + /// + /// # Arguments + /// - `m`: The `SetTarget` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_set_target(&mut self, m: SetTarget) -> Result, Error>; + /// Handles a request to reconnect the mining connection. + /// + /// # Arguments + /// - `m`: The `Reconnect` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_reconnect(&mut self, m: Reconnect) -> Result, Error>; + /// Handles a request to set the group channel for mining. + /// + /// # Arguments + /// - `_m`: The `SetGroupChannel` message. + /// + /// # Returns + /// - `Result, Error>`: The result of processing the message. fn handle_set_group_channel(&mut self, _m: SetGroupChannel) -> Result, Error> { Ok(SendTo::None(None)) } diff --git a/protocols/v2/roles-logic-sv2/src/handlers/mod.rs b/protocols/v2/roles-logic-sv2/src/handlers/mod.rs index b7d39ab4e..b717eb34a 100644 --- a/protocols/v2/roles-logic-sv2/src/handlers/mod.rs +++ b/protocols/v2/roles-logic-sv2/src/handlers/mod.rs @@ -1,76 +1,65 @@ -//! Handlers are divided per (sub)protocol and per Downstream/Upstream. -//! Each (sup)protocol defines a handler for both the Upstream node and the Downstream node -//! Handlers are a trait called `Parse[Downstream/Upstream][(sub)protocol]` -//! (eg. `ParseDownstreamCommonMessages`). +//! # Handlers Overview //! -//! When implemented, the handler makes the `handle_message_[(sub)protoco](..)` (e.g. -//! `handle_message_common(..)`) function available. +//! This module centralizes the logic for processing and routing Stratum V2 protocol messages, +//! defining traits and utilities to handle messages for both Downstream and Upstream roles. //! -//! The trait requires the implementer to define one function for each message type that a role -//! defined by the (sub)protocol and the Upstream/Downstream state could receive. +//! ## Purpose //! -//! This function will always take a mutable ref to `self`, a message payload + message type, and -//! the routing logic. -//! Using `parsers` in `crate::parser`, the payload and message type are parsed in an actual SV2 -//! message. -//! Routing logic is used in order to select the correct Downstream/Upstream to which the message -//! must be relayed/sent. -//! Routing logic is used to update the request id when needed. -//! After that, the specific function for the message type (implemented by the implementer) is -//! called with the SV2 message and the remote that must receive the message. +//! - Standardize the handling of protocol-specific messages. +//! - Enable efficient routing, transformation, and relaying of messages between nodes. +//! - Support modularity and scalability across Stratum V2 subprotocols. //! -//! A `Result` is returned and it is the duty of the implementer to send the -//! message. +//! ## Structure +//! +//! The module is organized by subprotocol and role, with handler traits for: +//! - `ParseDownstream[Protocol]`: Handles messages from Downstream nodes. +//! - `ParseUpstream[Protocol]`: Handles messages from Upstream nodes. +//! +//! Supported subprotocols include: +//! - `common`: Shared messages across protocols. +//! - `job_declaration`: Job-related messages. +//! - `mining`: Mining-specific messages. +//! - `template_distribution`: Template distribution messages. +//! +//! ## Return Values +//! +//! Handlers return `Result`, where: +//! - `SendTo_` specifies the action (relay, respond, or no action). +//! - `Error` indicates processing issues. pub mod common; pub mod job_declaration; pub mod mining; pub mod template_distribution; + use crate::utils::Mutex; use std::sync::Arc; #[derive(Debug)] -/// Message is a serializable entity that rapresent the meanings of communication between Remote(s) -/// SendTo_ is used to add context to Message, it say what we need to do with that Message. +/// Represents a serializable entity used for communication between Remotes. +/// The `SendTo_` enum adds context to the message, specifying the intended action. pub enum SendTo_ { - /// Used by proxies when Message must be relayed downstream or upstream and we want to specify - /// to which particular downstream or upstream we want to relay the message. - /// - /// When the message that we need to relay is the same message that we received should be used - /// RelaySameMessageToRemote in order to save an allocation. + /// Relay a new message to a specific remote. RelayNewMessageToRemote(Arc>, Message), - /// Used by proxies when Message must be relayed downstream or upstream and we want to specify - /// to which particular downstream or upstream we want to relay the message. - /// - /// Is used when we need to relay the same message the we received in order to save an - /// allocation. + /// Relay the same received message to a specific remote to avoid extra allocations. RelaySameMessageToRemote(Arc>), - /// Used by proxies when Message must be relayed downstream or upstream and we do not want to - /// specify specify to which particular downstream or upstream we want to relay the - /// message. + /// Relay a new message without specifying a specific remote. /// - /// This is used in proxies that do and Sv1 to Sv2 translation. The upstream is connected via - /// an extended channel that means that + /// This is common in proxies that translate between SV1 and SV2 protocols, where messages are + /// often broadcasted via extended channels. RelayNewMessage(Message), - /// Used proxies clients and servers to directly respond to a received message. + /// Directly respond to a received message. Respond(Message), + /// Relay multiple messages to various destinations. Multiple(Vec>), - /// Used by proxies, clients, and servers, when Message do not have to be used in any of the - /// above way. If Message is still needed to be used in a non conventional way we use - /// SendTo::None(Some(message)) If we just want to discard it we can use SendTo::None(None) + /// Indicates that no immediate action is required for the message. /// - /// SendTo::None(Some(m)) could be used for example when we do not need to send the message, - /// but we still need it for successive handling/transformation. - /// One of these cases are proxies that are connected to upstream via an extended channel (like - /// the Sv1 <-> Sv2 translator). This because extended channel messages are always general - /// for all the downstream, where standard channel message can be specific for a particular - /// downstream. Another case is when 2 roles are implemented in the same software, like a - /// pool that is both TP client and a Mining server, messages received by the TP client - /// must be sent to the Mining Server than transformed in Mining messages and sent to the - /// downstream. + /// This variant allows for cases where the message is still needed for later processing + /// (e.g., transformations or when two roles are implemented in the same software). None(Option), } impl SendTo_ { + /// Extracts the message, if available. pub fn into_message(self) -> Option { match self { Self::RelayNewMessageToRemote(_, m) => Some(m), @@ -81,6 +70,8 @@ impl SendTo_ { Self::None(m) => m, } } + + /// Extracts the remote, if available. pub fn into_remote(self) -> Option>> { match self { Self::RelayNewMessageToRemote(r, _) => Some(r), diff --git a/protocols/v2/roles-logic-sv2/src/handlers/template_distribution.rs b/protocols/v2/roles-logic-sv2/src/handlers/template_distribution.rs index fd321d0f7..a0a5b94ec 100644 --- a/protocols/v2/roles-logic-sv2/src/handlers/template_distribution.rs +++ b/protocols/v2/roles-logic-sv2/src/handlers/template_distribution.rs @@ -1,3 +1,40 @@ +//! # Template Distribution Handlers +//! +//! This module defines traits and functions for handling template distribution messages within the +//! Stratum V2 protocol. +//! +//! ## Core Traits +//! +//! - `ParseServerTemplateDistributionMessages`: Implemented by downstream nodes to process template +//! distribution messages received from upstream nodes. This trait includes methods for handling +//! template-related events like new templates, previous hash updates, and transaction data +//! requests. +//! - `ParseClientTemplateDistributionMessages`: Implemented by upstream nodes to manage template +//! distribution messages received from downstream nodes. This trait handles coinbase output size, +//! transaction data requests, and solution submissions. +//! +//! ## Message Handling +//! +//! Handlers are responsible for: +//! - Parsing and deserializing template distribution messages into appropriate types. +//! - Dispatching the deserialized messages to specific handler functions based on message type, +//! such as handling new templates, transaction data requests, and coinbase output data. +//! +//! ## Return Type +//! +//! Functions return `Result`, where `SendTo` determines the next action for the +//! message: whether it should be relayed, responded to, or ignored. +//! +//! ## Structure +//! +//! This module includes: +//! - Traits for processing template distribution messages, including server-side and client-side +//! handling. +//! - Functions to parse, deserialize, and process messages related to template distribution, +//! ensuring robust error handling. +//! - Error handling mechanisms to address unexpected messages and ensure safe processing, +//! especially in the context of shared state. + use super::SendTo_; use crate::{errors::Error, parsers::TemplateDistribution, utils::Mutex}; use template_distribution_sv2::{ @@ -11,10 +48,28 @@ use core::convert::TryInto; use std::sync::Arc; use tracing::{debug, error, info, trace}; +/// Trait for handling template distribution messages received from upstream nodes (server side). +/// Includes functions to handle messages such as new templates, previous hash updates, and +/// transaction data requests. pub trait ParseServerTemplateDistributionMessages where Self: Sized, { + /// Handles incoming template distribution messages. + /// + /// This function is responsible for parsing and dispatching the appropriate handler based on + /// the message type. It first deserializes the payload and then routes it to the + /// corresponding handler function. + /// + /// # Arguments + /// - `self_`: An `Arc>` representing the instance of the object implementing this + /// trait. + /// - `message_type`: The type of the incoming message. + /// - `payload`: The raw payload data of the message. + /// + /// # Returns + /// - `Result`: The result of processing the message, where `SendTo` indicates + /// the next step in message handling. fn handle_message_template_distribution( self_: Arc>, message_type: u8, @@ -25,6 +80,19 @@ where (message_type, payload).try_into(), ) } + + /// Handles deserialized template distribution messages. + /// + /// This function takes the deserialized message and processes it according to the specific + /// message type, invoking the appropriate handler function. + /// + /// # Arguments + /// - `self_`: An `Arc>` representing the instance of the object implementing this + /// trait. + /// - `message`: The deserialized `TemplateDistribution` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_message_template_distribution_desrialized( self_: Arc>, message: Result, Error>, @@ -80,22 +148,82 @@ where Err(e) => Err(e), } } + + /// Handles a `NewTemplate` message. + /// + /// This method processes the `NewTemplate` message, which contains information about a newly + /// generated template. + /// + /// # Arguments + /// - `m`: The `NewTemplate` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_new_template(&mut self, m: NewTemplate) -> Result; + + /// Handles a `SetNewPrevHash` message. + /// + /// This method processes the `SetNewPrevHash` message, which updates the previous hash for a + /// template. + /// + /// # Arguments + /// - `m`: The `SetNewPrevHash` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_set_new_prev_hash(&mut self, m: SetNewPrevHash) -> Result; + + /// Handles a `RequestTransactionDataSuccess` message. + /// + /// This method processes the success response for a requested transaction data message. + /// + /// # Arguments + /// - `m`: The `RequestTransactionDataSuccess` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_request_tx_data_success( &mut self, m: RequestTransactionDataSuccess, ) -> Result; + + /// Handles a `RequestTransactionDataError` message. + /// + /// This method processes an error response for a requested transaction data message. + /// + /// # Arguments + /// - `m`: The `RequestTransactionDataError` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_request_tx_data_error( &mut self, m: RequestTransactionDataError, ) -> Result; } +/// Trait for handling template distribution messages received from downstream nodes (client side). +/// Includes functions to handle messages such as coinbase output data size, transaction data +/// requests, and solution submissions. pub trait ParseClientTemplateDistributionMessages where Self: Sized, { + /// Handles incoming template distribution messages. + /// + /// This function is responsible for parsing and dispatching the appropriate handler based on + /// the message type. It first deserializes the payload and then routes it to the + /// corresponding handler function. + /// + /// # Arguments + /// - `self_`: An `Arc>` representing the instance of the object implementing this + /// trait. + /// - `message_type`: The type of the incoming message. + /// - `payload`: The raw payload data of the message. + /// + /// # Returns + /// - `Result`: The result of processing the message, where `SendTo` indicates + /// the next step in message handling. fn handle_message_template_distribution( self_: Arc>, message_type: u8, @@ -107,6 +235,18 @@ where ) } + /// Handles deserialized template distribution messages. + /// + /// This function takes the deserialized message and processes it according to the specific + /// message type, invoking the appropriate handler function. + /// + /// # Arguments + /// - `self_`: An `Arc>` representing the instance of the object implementing this + /// trait. + /// - `message`: The deserialized `TemplateDistribution` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_message_template_distribution_desrialized( self_: Arc>, message: Result, Error>, @@ -137,8 +277,38 @@ where Err(e) => Err(e), } } + + /// Handles a `CoinbaseOutputDataSize` message. + /// + /// This method processes a message that includes the coinbase output data size. + /// + /// # Arguments + /// - `m`: The `CoinbaseOutputDataSize` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_coinbase_out_data_size(&mut self, m: CoinbaseOutputDataSize) -> Result; + + /// Handles a `RequestTransactionData` message. + /// + /// This method processes a message requesting transaction data. + /// + /// # Arguments + /// - `m`: The `RequestTransactionData` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_request_tx_data(&mut self, m: RequestTransactionData) -> Result; + + /// Handles a `SubmitSolution` message. + /// + /// This method processes a solution submission message. + /// + /// # Arguments + /// - `m`: The `SubmitSolution` message. + /// + /// # Returns + /// - `Result`: The result of processing the message. fn handle_request_submit_solution(&mut self, m: SubmitSolution) -> Result; }