Skip to content
27 changes: 26 additions & 1 deletion common/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion protocols/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ members = [
"v2/sv2-ffi",
"v2/roles-logic-sv2",
"v2/channels-sv2",
"v2/parsers-sv2",
"v2/parsers-sv2",
"v2/handlers-sv2",
]

[profile.dev]
Expand Down
21 changes: 21 additions & 0 deletions protocols/v2/handlers-sv2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "handlers_sv2"
version = "0.1.0"
authors = ["The Stratum V2 Developers"]
edition = "2018"
readme = "README.md"
description = "Sv2 Message handlers"
documentation = "https://docs.rs/handlers_sv2"
license = "MIT OR Apache-2.0"
repository = "https://github.com/stratum-mining/stratum"
homepage = "https://stratumprotocol.org"
keywords = ["stratum", "mining", "bitcoin", "protocol"]

[dependencies]
trait-variant = "0.1.2"
parsers_sv2 = { path = "../parsers-sv2", version = "^0.1.0"}
binary_sv2 = { path = "../binary-sv2", version = "^3.0.0" }
common_messages_sv2 = { path = "../subprotocols/common-messages", version = "^5.0.0" }
mining_sv2 = { path = "../subprotocols/mining", version = "^4.0.0" }
template_distribution_sv2 = { path = "../subprotocols/template-distribution", version = "^3.0.0" }
job_declaration_sv2 = { path = "../subprotocols/job-declaration", version = "^4.0.0" }
156 changes: 156 additions & 0 deletions protocols/v2/handlers-sv2/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
use crate::error::HandlerError as Error;
use common_messages_sv2::{
ChannelEndpointChanged, Reconnect, SetupConnectionError, SetupConnectionSuccess, *,
};
use core::convert::TryInto;
use parsers_sv2::CommonMessages;

pub trait HandleCommonMessagesFromServerSync {
fn handle_common_message(&mut self, message_type: u8, payload: &mut [u8]) -> Result<(), Error> {
let parsed: CommonMessages<'_> = (message_type, payload).try_into()?;
self.dispatch_common_message(parsed)
}

fn dispatch_common_message(&mut self, message: CommonMessages<'_>) -> Result<(), Error> {
match message {
CommonMessages::SetupConnectionSuccess(msg) => {
self.handle_setup_connection_success(msg)
}
CommonMessages::SetupConnectionError(msg) => self.handle_setup_connection_error(msg),
CommonMessages::ChannelEndpointChanged(msg) => {
self.handle_channel_endpoint_changed(msg)
}
CommonMessages::Reconnect(msg) => self.handle_reconnect(msg),

CommonMessages::SetupConnection(_) => {
Err(Error::UnexpectedMessage(MESSAGE_TYPE_SETUP_CONNECTION))
}
}
}

fn handle_setup_connection_success(&mut self, msg: SetupConnectionSuccess)
-> Result<(), Error>;

fn handle_setup_connection_error(&mut self, msg: SetupConnectionError) -> Result<(), Error>;

fn handle_channel_endpoint_changed(&mut self, msg: ChannelEndpointChanged)
-> Result<(), Error>;

fn handle_reconnect(&mut self, msg: Reconnect) -> Result<(), Error>;
}

#[trait_variant::make(Send)]
pub trait HandleCommonMessagesFromServerAsync {
async fn handle_common_message(
&mut self,
message_type: u8,
payload: &mut [u8],
) -> Result<(), Error> {
let parsed: Result<CommonMessages<'_>, _> = (message_type, payload).try_into();
async move {
let parsed = parsed?;
self.dispatch_common_message(parsed).await
}
}

async fn dispatch_common_message(&mut self, message: CommonMessages<'_>) -> Result<(), Error> {
async move {
match message {
CommonMessages::SetupConnectionSuccess(msg) => {
self.handle_setup_connection_success(msg).await
}
CommonMessages::SetupConnectionError(msg) => {
self.handle_setup_connection_error(msg).await
}
CommonMessages::ChannelEndpointChanged(msg) => {
self.handle_channel_endpoint_changed(msg).await
}
CommonMessages::Reconnect(msg) => self.handle_reconnect(msg).await,

CommonMessages::SetupConnection(_) => {
Err(Error::UnexpectedMessage(MESSAGE_TYPE_SETUP_CONNECTION))
}
}
}
}

async fn handle_setup_connection_success(
&mut self,
msg: SetupConnectionSuccess,
) -> Result<(), Error>;

async fn handle_setup_connection_error(
&mut self,
msg: SetupConnectionError,
) -> Result<(), Error>;

async fn handle_channel_endpoint_changed(
&mut self,
msg: ChannelEndpointChanged,
) -> Result<(), Error>;

async fn handle_reconnect(&mut self, msg: Reconnect) -> Result<(), Error>;
}

pub trait HandleCommonMessagesFromClientSync {
fn handle_common_message(&mut self, message_type: u8, payload: &mut [u8]) -> Result<(), Error> {
let parsed: CommonMessages<'_> = (message_type, payload).try_into()?;
self.dispatch_common_message(parsed)
}

fn dispatch_common_message(&mut self, message: CommonMessages<'_>) -> Result<(), Error> {
match message {
CommonMessages::SetupConnectionSuccess(_) => Err(Error::UnexpectedMessage(
MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS,
)),
CommonMessages::SetupConnectionError(_) => Err(Error::UnexpectedMessage(
MESSAGE_TYPE_SETUP_CONNECTION_ERROR,
)),
CommonMessages::ChannelEndpointChanged(_) => Err(Error::UnexpectedMessage(
MESSAGE_TYPE_CHANNEL_ENDPOINT_CHANGED,
)),
CommonMessages::Reconnect(_) => Err(Error::UnexpectedMessage(MESSAGE_TYPE_RECONNECT)),

CommonMessages::SetupConnection(msg) => self.handle_setup_connection(msg),
}
}

fn handle_setup_connection(&mut self, msg: SetupConnection) -> Result<(), Error>;
}

#[trait_variant::make(Send)]
pub trait HandleCommonMessagesFromClientAsync {
async fn handle_common_message(
&mut self,
message_type: u8,
payload: &mut [u8],
) -> Result<(), Error> {
let parsed: Result<CommonMessages<'_>, _> = (message_type, payload).try_into();
async move {
let parsed = parsed?;
self.dispatch_common_message(parsed).await
}
}

async fn dispatch_common_message(&mut self, message: CommonMessages<'_>) -> Result<(), Error> {
async move {
match message {
CommonMessages::SetupConnectionSuccess(_) => Err(Error::UnexpectedMessage(
MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS,
)),
CommonMessages::SetupConnectionError(_) => Err(Error::UnexpectedMessage(
MESSAGE_TYPE_SETUP_CONNECTION_ERROR,
)),
CommonMessages::ChannelEndpointChanged(_) => Err(Error::UnexpectedMessage(
MESSAGE_TYPE_CHANNEL_ENDPOINT_CHANGED,
)),
CommonMessages::Reconnect(_) => {
Err(Error::UnexpectedMessage(MESSAGE_TYPE_RECONNECT))
}
CommonMessages::SetupConnection(msg) => self.handle_setup_connection(msg).await,
}
}
}

async fn handle_setup_connection(&mut self, msg: SetupConnection) -> Result<(), Error>;
}
14 changes: 14 additions & 0 deletions protocols/v2/handlers-sv2/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use parsers_sv2::ParserError;

#[derive(Debug)]
pub enum HandlerError {
UnexpectedMessage(u8),
ParserError(ParserError),
External(Box<dyn std::error::Error + Send + Sync>),
}

impl From<ParserError> for HandlerError {
fn from(value: ParserError) -> HandlerError {
HandlerError::ParserError(value)
}
}
Loading