2019-03-12 18:26:07 -06:00
|
|
|
use serde_json::{json, Value};
|
|
|
|
use std::{error, fmt};
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum RpcRequest {
|
|
|
|
ConfirmTransaction,
|
2019-04-25 08:52:53 -06:00
|
|
|
DeregisterNode,
|
|
|
|
FullnodeExit,
|
2019-03-12 18:26:07 -06:00
|
|
|
GetAccountInfo,
|
|
|
|
GetBalance,
|
2019-04-25 08:52:53 -06:00
|
|
|
GetClusterNodes,
|
2019-08-21 18:16:40 -07:00
|
|
|
GetGenesisBlockhash,
|
2019-04-25 08:52:53 -06:00
|
|
|
GetNumBlocksSinceSignatureConfirmation,
|
2019-07-11 12:38:52 -06:00
|
|
|
GetProgramAccounts,
|
2019-03-12 18:26:07 -06:00
|
|
|
GetRecentBlockhash,
|
|
|
|
GetSignatureStatus,
|
2019-06-12 16:43:05 -07:00
|
|
|
GetSlot,
|
2019-04-25 08:52:53 -06:00
|
|
|
GetSlotLeader,
|
2019-07-10 13:33:29 -07:00
|
|
|
GetStorageTurn,
|
|
|
|
GetStorageTurnRate,
|
2019-07-09 16:48:40 -07:00
|
|
|
GetSlotsPerSegment,
|
2019-05-03 16:27:53 -07:00
|
|
|
GetStoragePubkeysForSlot,
|
2019-03-12 18:26:07 -06:00
|
|
|
GetTransactionCount,
|
2019-08-08 11:13:06 -06:00
|
|
|
GetVersion,
|
2019-08-16 17:02:19 -06:00
|
|
|
GetVoteAccounts,
|
2019-04-25 08:52:53 -06:00
|
|
|
RegisterNode,
|
2019-03-12 18:26:07 -06:00
|
|
|
RequestAirdrop,
|
|
|
|
SendTransaction,
|
|
|
|
SignVote,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RpcRequest {
|
2019-03-16 21:51:41 -07:00
|
|
|
pub(crate) fn build_request_json(&self, id: u64, params: Option<Value>) -> Value {
|
2019-03-12 18:26:07 -06:00
|
|
|
let jsonrpc = "2.0";
|
|
|
|
let method = match self {
|
|
|
|
RpcRequest::ConfirmTransaction => "confirmTransaction",
|
2019-04-25 08:52:53 -06:00
|
|
|
RpcRequest::DeregisterNode => "deregisterNode",
|
|
|
|
RpcRequest::FullnodeExit => "fullnodeExit",
|
2019-03-12 18:26:07 -06:00
|
|
|
RpcRequest::GetAccountInfo => "getAccountInfo",
|
|
|
|
RpcRequest::GetBalance => "getBalance",
|
2019-04-25 08:52:53 -06:00
|
|
|
RpcRequest::GetClusterNodes => "getClusterNodes",
|
2019-08-21 18:16:40 -07:00
|
|
|
RpcRequest::GetGenesisBlockhash => "getGenesisBlockhash",
|
2019-04-25 08:52:53 -06:00
|
|
|
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
|
|
|
"getNumBlocksSinceSignatureConfirmation"
|
|
|
|
}
|
2019-07-11 12:38:52 -06:00
|
|
|
RpcRequest::GetProgramAccounts => "getProgramAccounts",
|
2019-03-12 18:26:07 -06:00
|
|
|
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
|
|
|
RpcRequest::GetSignatureStatus => "getSignatureStatus",
|
2019-06-12 16:43:05 -07:00
|
|
|
RpcRequest::GetSlot => "getSlot",
|
2019-04-25 08:52:53 -06:00
|
|
|
RpcRequest::GetSlotLeader => "getSlotLeader",
|
2019-07-10 13:33:29 -07:00
|
|
|
RpcRequest::GetStorageTurn => "getStorageTurn",
|
|
|
|
RpcRequest::GetStorageTurnRate => "getStorageTurnRate",
|
2019-07-09 16:48:40 -07:00
|
|
|
RpcRequest::GetSlotsPerSegment => "getSlotsPerSegment",
|
2019-05-03 16:27:53 -07:00
|
|
|
RpcRequest::GetStoragePubkeysForSlot => "getStoragePubkeysForSlot",
|
2019-03-12 18:26:07 -06:00
|
|
|
RpcRequest::GetTransactionCount => "getTransactionCount",
|
2019-08-08 11:13:06 -06:00
|
|
|
RpcRequest::GetVersion => "getVersion",
|
2019-08-16 17:02:19 -06:00
|
|
|
RpcRequest::GetVoteAccounts => "getVoteAccounts",
|
2019-04-25 08:52:53 -06:00
|
|
|
RpcRequest::RegisterNode => "registerNode",
|
2019-03-12 18:26:07 -06:00
|
|
|
RpcRequest::RequestAirdrop => "requestAirdrop",
|
|
|
|
RpcRequest::SendTransaction => "sendTransaction",
|
|
|
|
RpcRequest::SignVote => "signVote",
|
|
|
|
};
|
|
|
|
let mut request = json!({
|
|
|
|
"jsonrpc": jsonrpc,
|
|
|
|
"id": id,
|
|
|
|
"method": method,
|
|
|
|
});
|
|
|
|
if let Some(param_string) = params {
|
|
|
|
request["params"] = param_string;
|
|
|
|
}
|
|
|
|
request
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
pub enum RpcError {
|
|
|
|
RpcRequestError(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for RpcError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "invalid")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl error::Error for RpcError {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
"invalid"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cause(&self) -> Option<&dyn error::Error> {
|
|
|
|
// Generic error, underlying cause isn't tracked.
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_build_request_json() {
|
|
|
|
let test_request = RpcRequest::GetAccountInfo;
|
|
|
|
let addr = json!(["deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx"]);
|
|
|
|
let request = test_request.build_request_json(1, Some(addr.clone()));
|
|
|
|
assert_eq!(request["method"], "getAccountInfo");
|
|
|
|
assert_eq!(request["params"], addr,);
|
|
|
|
|
|
|
|
let test_request = RpcRequest::GetBalance;
|
|
|
|
let request = test_request.build_request_json(1, Some(addr));
|
|
|
|
assert_eq!(request["method"], "getBalance");
|
|
|
|
|
|
|
|
let test_request = RpcRequest::GetRecentBlockhash;
|
|
|
|
let request = test_request.build_request_json(1, None);
|
|
|
|
assert_eq!(request["method"], "getRecentBlockhash");
|
|
|
|
|
2019-06-12 16:43:05 -07:00
|
|
|
let test_request = RpcRequest::GetSlot;
|
|
|
|
let request = test_request.build_request_json(1, None);
|
|
|
|
assert_eq!(request["method"], "getSlot");
|
|
|
|
|
2019-03-12 18:26:07 -06:00
|
|
|
let test_request = RpcRequest::GetTransactionCount;
|
|
|
|
let request = test_request.build_request_json(1, None);
|
|
|
|
assert_eq!(request["method"], "getTransactionCount");
|
|
|
|
|
|
|
|
let test_request = RpcRequest::RequestAirdrop;
|
|
|
|
let request = test_request.build_request_json(1, None);
|
|
|
|
assert_eq!(request["method"], "requestAirdrop");
|
|
|
|
|
|
|
|
let test_request = RpcRequest::SendTransaction;
|
|
|
|
let request = test_request.build_request_json(1, None);
|
|
|
|
assert_eq!(request["method"], "sendTransaction");
|
|
|
|
}
|
|
|
|
}
|