2019-11-06 13:15:00 -08:00
|
|
|
use crate::{
|
2020-03-12 23:20:49 -07:00
|
|
|
client_error::Result,
|
2020-01-14 23:25:45 -08:00
|
|
|
generic_rpc_client_request::GenericRpcClientRequest,
|
2019-11-06 13:15:00 -08:00
|
|
|
rpc_request::RpcRequest,
|
2020-03-26 13:29:30 -07:00
|
|
|
rpc_response::{Response, RpcResponseContext},
|
2019-11-06 13:15:00 -08:00
|
|
|
};
|
2019-03-16 21:51:41 -07:00
|
|
|
use serde_json::{Number, Value};
|
2019-11-06 13:15:00 -08:00
|
|
|
use solana_sdk::{
|
2020-02-28 12:27:01 -08:00
|
|
|
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
2019-12-09 19:35:34 -08:00
|
|
|
instruction::InstructionError,
|
2019-11-06 13:15:00 -08:00
|
|
|
transaction::{self, TransactionError},
|
|
|
|
};
|
2020-03-26 13:29:30 -07:00
|
|
|
use solana_transaction_status::TransactionStatus;
|
2019-12-27 12:35:49 -08:00
|
|
|
use std::{collections::HashMap, sync::RwLock};
|
2019-03-12 17:26:07 -07:00
|
|
|
|
|
|
|
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
|
|
|
|
pub const SIGNATURE: &str =
|
|
|
|
"43yNSFC6fYTuPgTNFFhF4axw7AfWxB2BPdurme8yrsWEYwm8299xh8n6TAHjGymiSub1XtyxTNyd9GBfY2hxoBw8";
|
|
|
|
|
2019-12-27 12:35:49 -08:00
|
|
|
pub type Mocks = HashMap<RpcRequest, Value>;
|
2019-03-16 21:51:41 -07:00
|
|
|
pub struct MockRpcClientRequest {
|
2019-12-27 12:35:49 -08:00
|
|
|
mocks: RwLock<Mocks>,
|
2019-03-16 21:51:41 -07:00
|
|
|
url: String,
|
2019-03-12 17:26:07 -07:00
|
|
|
}
|
|
|
|
|
2019-03-16 21:51:41 -07:00
|
|
|
impl MockRpcClientRequest {
|
2019-03-15 22:42:36 -07:00
|
|
|
pub fn new(url: String) -> Self {
|
2019-12-27 12:35:49 -08:00
|
|
|
Self::new_with_mocks(url, Mocks::default())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_with_mocks(url: String, mocks: Mocks) -> Self {
|
|
|
|
Self {
|
|
|
|
url,
|
|
|
|
mocks: RwLock::new(mocks),
|
|
|
|
}
|
2019-03-12 17:26:07 -07:00
|
|
|
}
|
2019-03-16 21:51:41 -07:00
|
|
|
}
|
2019-03-12 17:26:07 -07:00
|
|
|
|
2019-03-16 21:51:41 -07:00
|
|
|
impl GenericRpcClientRequest for MockRpcClientRequest {
|
|
|
|
fn send(
|
2019-03-12 17:26:07 -07:00
|
|
|
&self,
|
|
|
|
request: &RpcRequest,
|
2020-04-04 23:31:24 -07:00
|
|
|
_params: serde_json::Value,
|
2019-03-16 21:51:41 -07:00
|
|
|
_retries: usize,
|
2020-03-12 23:20:49 -07:00
|
|
|
) -> Result<serde_json::Value> {
|
2019-12-27 12:35:49 -08:00
|
|
|
if let Some(value) = self.mocks.write().unwrap().remove(request) {
|
|
|
|
return Ok(value);
|
|
|
|
}
|
2019-03-15 22:42:36 -07:00
|
|
|
if self.url == "fails" {
|
2019-03-12 17:26:07 -07:00
|
|
|
return Ok(Value::Null);
|
|
|
|
}
|
|
|
|
let val = match request {
|
2020-02-11 21:48:04 -08:00
|
|
|
RpcRequest::GetBalance => serde_json::to_value(Response {
|
|
|
|
context: RpcResponseContext { slot: 1 },
|
|
|
|
value: Value::Number(Number::from(50)),
|
|
|
|
})?,
|
2019-11-12 11:49:41 -08:00
|
|
|
RpcRequest::GetRecentBlockhash => serde_json::to_value(Response {
|
|
|
|
context: RpcResponseContext { slot: 1 },
|
|
|
|
value: (
|
|
|
|
Value::String(PUBKEY.to_string()),
|
|
|
|
serde_json::to_value(FeeCalculator::default()).unwrap(),
|
|
|
|
),
|
|
|
|
})?,
|
2020-03-06 16:01:31 -08:00
|
|
|
RpcRequest::GetFeeCalculatorForBlockhash => {
|
|
|
|
let value = if self.url == "blockhash_expired" {
|
|
|
|
Value::Null
|
|
|
|
} else {
|
|
|
|
serde_json::to_value(Some(FeeCalculator::default())).unwrap()
|
|
|
|
};
|
|
|
|
serde_json::to_value(Response {
|
|
|
|
context: RpcResponseContext { slot: 1 },
|
|
|
|
value,
|
|
|
|
})?
|
|
|
|
}
|
2020-02-28 12:27:01 -08:00
|
|
|
RpcRequest::GetFeeRateGovernor => serde_json::to_value(Response {
|
|
|
|
context: RpcResponseContext { slot: 1 },
|
|
|
|
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
|
|
|
|
})?,
|
2020-04-01 11:30:58 -07:00
|
|
|
RpcRequest::GetSignatureStatuses => {
|
2020-03-23 10:25:39 -07:00
|
|
|
let status: transaction::Result<()> = if self.url == "account_in_use" {
|
|
|
|
Err(TransactionError::AccountInUse)
|
2019-12-09 19:35:34 -08:00
|
|
|
} else if self.url == "instruction_error" {
|
2020-03-23 10:25:39 -07:00
|
|
|
Err(TransactionError::InstructionError(
|
2019-12-09 19:35:34 -08:00
|
|
|
0,
|
|
|
|
InstructionError::UninitializedAccount,
|
2020-03-23 10:25:39 -07:00
|
|
|
))
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
};
|
|
|
|
let status = if self.url == "sig_not_found" {
|
2019-04-05 19:56:17 -07:00
|
|
|
None
|
2019-03-12 17:26:07 -07:00
|
|
|
} else {
|
2020-04-04 16:13:26 -07:00
|
|
|
let err = status.clone().err();
|
2020-03-26 18:21:01 -07:00
|
|
|
Some(TransactionStatus {
|
|
|
|
status,
|
|
|
|
slot: 1,
|
|
|
|
confirmations: Some(0),
|
2020-04-04 16:13:26 -07:00
|
|
|
err,
|
2020-03-26 18:21:01 -07:00
|
|
|
})
|
2019-03-12 17:26:07 -07:00
|
|
|
};
|
2020-03-26 18:21:01 -07:00
|
|
|
serde_json::to_value(Response {
|
|
|
|
context: RpcResponseContext { slot: 1 },
|
|
|
|
value: vec![status],
|
|
|
|
})?
|
2019-03-12 17:26:07 -07:00
|
|
|
}
|
|
|
|
RpcRequest::GetTransactionCount => Value::Number(Number::from(1234)),
|
2019-06-12 16:43:05 -07:00
|
|
|
RpcRequest::GetSlot => Value::Number(Number::from(0)),
|
2019-03-12 17:26:07 -07:00
|
|
|
RpcRequest::SendTransaction => Value::String(SIGNATURE.to_string()),
|
2019-09-30 12:44:49 -07:00
|
|
|
RpcRequest::GetMinimumBalanceForRentExemption => Value::Number(Number::from(1234)),
|
2019-03-12 17:26:07 -07:00
|
|
|
_ => Value::Null,
|
|
|
|
};
|
|
|
|
Ok(val)
|
|
|
|
}
|
|
|
|
}
|