1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
//! 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`).
//!
//! When implemented, the handler makes the `handle_message_[(sub)protoco](..)` (e.g.
//! `handle_message_common(..)`) function available.
//!
//! 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.
//!
//! 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.
//!
//! A `Result<SendTo_, Error>` is returned and it is the duty of the implementer to send the
//! message.
//!
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.
pub enum SendTo_<Message, Remote> {
/// 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.
RelayNewMessageToRemote(Arc<Mutex<Remote>>, 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.
RelaySameMessageToRemote(Arc<Mutex<Remote>>),
/// 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.
///
/// This is used in proxies that do and Sv1 to Sv2 translation. The upstream is connected via
/// an extended channel that means that
RelayNewMessage(Message),
/// Used proxies clients and servers to directly respond to a received message.
Respond(Message),
Multiple(Vec<SendTo_<Message, Remote>>),
/// 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)
///
/// 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.
///
None(Option<Message>),
}
impl<SubProtocol, Remote> SendTo_<SubProtocol, Remote> {
pub fn into_message(self) -> Option<SubProtocol> {
match self {
Self::RelayNewMessageToRemote(_, m) => Some(m),
Self::RelaySameMessageToRemote(_) => None,
Self::RelayNewMessage(m) => Some(m),
Self::Respond(m) => Some(m),
Self::Multiple(_) => None,
Self::None(m) => m,
}
}
pub fn into_remote(self) -> Option<Arc<Mutex<Remote>>> {
match self {
Self::RelayNewMessageToRemote(r, _) => Some(r),
Self::RelaySameMessageToRemote(r) => Some(r),
Self::RelayNewMessage(_) => None,
Self::Respond(_) => None,
Self::Multiple(_) => None,
Self::None(_) => None,
}
}
}