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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
pub mod error;
pub mod params;
pub mod traits;
use crate::params::{ClientParams, PoolParams};
use crate::traits::StratumPackets;
pub use error::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub type Result<T> = std::result::Result<T, Error>;

//There is definitely a better way to do this where request and response are generalized, and then
//when used in the pool we set params = PoolParams, and response sets ClientParams.
//@todo P1 Priority small, can be done later.

//Request Base Object
#[derive(Serialize, Deserialize)]
pub struct PoolRequest<SP: StratumPackets> {
    pub id: String,
    //TODO might remove this.
    // jsonrpc: String,
    pub method: StratumMethod,
    pub params: PoolParams<SP>,
}

#[derive(Serialize, Deserialize)]
pub struct PoolResponse<SP: StratumPackets> {
    pub id: String, //@todo
    pub method: StratumMethod,
    pub result: PoolParams<SP>,
    pub error: Option<Vec<String>>,
}

#[derive(Serialize, Deserialize)]
pub struct ClientRequest<SP: StratumPackets> {
    pub id: String,
    pub method: StratumMethod,
    pub params: ClientParams<SP>,
}

#[derive(Serialize, Deserialize)]
pub struct ClientResponse<SP: StratumPackets> {
    pub id: u32,
    pub method: StratumMethod,
    //@todo lets see if there is a simple way of deserializing this based on the stratum method
    //above. https://github.com/serde-rs/json/issues/181
    pub result: PoolParams<SP>,
    pub error: Option<Vec<String>>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct StratumError {
    //@todo I hate the fact that the error codes are negative - if there isn't a vlaid reason
    //That this is the case, then move this back to u32, and let's just use positive numbers.
    pub code: i32,
    pub message: String,
}

#[derive(Debug)]
pub enum StratumMethod {
    //Sending and receiving
    Authorize,
    Capabilities,
    ExtraNonceSubscribe,
    GetTransactions,
    Submit,
    Subscribe,
    SuggestDifficulty,
    SuggestTarget,
    //Strictly receiving
    GetVersion,
    Reconnect,
    ShowMessage,
    Notify,
    SetDifficulty,
    SetExtraNonce,
    SetGoal,

    //Future methods potentially not implemented yet.
    Unknown(String),
}

impl Serialize for StratumMethod {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(match *self {
            StratumMethod::Authorize => "authorize",
            StratumMethod::Capabilities => "capabilities",
            StratumMethod::ExtraNonceSubscribe => "extranonce.subscribe",
            StratumMethod::GetTransactions => "get_transactions",
            StratumMethod::Submit => "submit",
            StratumMethod::Subscribe => "subscribe",
            StratumMethod::SuggestDifficulty => "suggest_difficulty",
            StratumMethod::SuggestTarget => "suggest_target",
            StratumMethod::GetVersion => "get_version",
            StratumMethod::Reconnect => "reconnect",
            StratumMethod::ShowMessage => "show_message",
            StratumMethod::Notify => "notify",
            StratumMethod::SetDifficulty => "set_difficulty",
            StratumMethod::SetExtraNonce => "set_extranonce",
            StratumMethod::SetGoal => "set_goal",
            StratumMethod::Unknown(ref s) => s,
        })
    }
}

impl<'de> Deserialize<'de> for StratumMethod {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(match s.as_str() {
            "authorize" => StratumMethod::Authorize,
            "capabilities" => StratumMethod::Capabilities,
            "extranonce.subscribe" => StratumMethod::ExtraNonceSubscribe,
            "get_transactions" => StratumMethod::GetTransactions,
            "submit" => StratumMethod::Submit,
            "subscribe" => StratumMethod::Subscribe,
            "suggest_difficulty" => StratumMethod::SuggestDifficulty,
            "suggest_target" => StratumMethod::SuggestTarget,
            "get_version" => StratumMethod::GetVersion,
            "reconnect" => StratumMethod::Reconnect,
            "show_message" => StratumMethod::ShowMessage,
            "notify" => StratumMethod::Notify,
            "set_difficulty" => StratumMethod::SetDifficulty,
            "set_extranonce" => StratumMethod::SetExtraNonce,
            "set_goal" => StratumMethod::SetGoal,
            _ => StratumMethod::Unknown(s),
        })
    }
}