2021-03-26 20:26:06 -07:00
|
|
|
use {
|
|
|
|
crate::{nonce_utils, rpc_client::RpcClient},
|
|
|
|
clap::ArgMatches,
|
|
|
|
solana_clap_utils::{
|
|
|
|
input_parsers::{pubkey_of, value_of},
|
|
|
|
nonce::*,
|
|
|
|
offline::*,
|
|
|
|
},
|
|
|
|
solana_sdk::{
|
|
|
|
commitment_config::CommitmentConfig, fee_calculator::FeeCalculator, hash::Hash,
|
|
|
|
pubkey::Pubkey,
|
|
|
|
},
|
2020-09-22 15:06:14 -07:00
|
|
|
};
|
2020-03-11 11:14:15 -07:00
|
|
|
|
2022-05-22 18:00:42 -07:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2020-03-11 11:14:15 -07:00
|
|
|
pub enum Source {
|
|
|
|
Cluster,
|
|
|
|
NonceAccount(Pubkey),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Source {
|
2021-10-26 09:06:41 -07:00
|
|
|
#[deprecated(since = "1.9.0", note = "Please use `get_blockhash` instead")]
|
2020-03-11 11:14:15 -07:00
|
|
|
pub fn get_blockhash_and_fee_calculator(
|
|
|
|
&self,
|
|
|
|
rpc_client: &RpcClient,
|
2020-06-17 11:18:48 -07:00
|
|
|
commitment: CommitmentConfig,
|
2020-03-11 11:14:15 -07:00
|
|
|
) -> Result<(Hash, FeeCalculator), Box<dyn std::error::Error>> {
|
|
|
|
match self {
|
|
|
|
Self::Cluster => {
|
2021-08-13 09:08:20 -07:00
|
|
|
#[allow(deprecated)]
|
2020-06-17 11:18:48 -07:00
|
|
|
let res = rpc_client
|
|
|
|
.get_recent_blockhash_with_commitment(commitment)?
|
|
|
|
.value;
|
|
|
|
Ok((res.0, res.1))
|
2020-03-11 11:14:15 -07:00
|
|
|
}
|
|
|
|
Self::NonceAccount(ref pubkey) => {
|
2021-10-05 22:24:48 -07:00
|
|
|
#[allow(clippy::redundant_closure)]
|
2020-09-21 12:55:44 -07:00
|
|
|
let data = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
|
|
|
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
2022-06-03 07:36:27 -07:00
|
|
|
Ok((data.blockhash(), data.fee_calculator))
|
2020-03-11 11:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-13 09:08:20 -07:00
|
|
|
#[deprecated(
|
2021-10-26 09:06:41 -07:00
|
|
|
since = "1.9.0",
|
2021-08-13 09:08:20 -07:00
|
|
|
note = "Please do not use, will no longer be available in the future"
|
|
|
|
)]
|
2020-03-11 11:14:15 -07:00
|
|
|
pub fn get_fee_calculator(
|
|
|
|
&self,
|
|
|
|
rpc_client: &RpcClient,
|
|
|
|
blockhash: &Hash,
|
2020-06-17 11:18:48 -07:00
|
|
|
commitment: CommitmentConfig,
|
2020-03-11 11:14:15 -07:00
|
|
|
) -> Result<Option<FeeCalculator>, Box<dyn std::error::Error>> {
|
|
|
|
match self {
|
|
|
|
Self::Cluster => {
|
2021-08-13 09:08:20 -07:00
|
|
|
#[allow(deprecated)]
|
2020-06-17 11:18:48 -07:00
|
|
|
let res = rpc_client
|
|
|
|
.get_fee_calculator_for_blockhash_with_commitment(blockhash, commitment)?
|
|
|
|
.value;
|
2020-03-11 11:14:15 -07:00
|
|
|
Ok(res)
|
|
|
|
}
|
|
|
|
Self::NonceAccount(ref pubkey) => {
|
2020-09-21 12:55:44 -07:00
|
|
|
let res = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)?;
|
|
|
|
let res = nonce_utils::data_from_account(&res)?;
|
2020-06-08 17:38:14 -07:00
|
|
|
Ok(Some(res)
|
2022-06-03 07:36:27 -07:00
|
|
|
.filter(|d| d.blockhash() == *blockhash)
|
2020-06-08 17:38:14 -07:00
|
|
|
.map(|d| d.fee_calculator))
|
2020-03-11 11:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-13 09:08:20 -07:00
|
|
|
|
|
|
|
pub fn get_blockhash(
|
|
|
|
&self,
|
|
|
|
rpc_client: &RpcClient,
|
|
|
|
commitment: CommitmentConfig,
|
|
|
|
) -> Result<Hash, Box<dyn std::error::Error>> {
|
|
|
|
match self {
|
|
|
|
Self::Cluster => {
|
|
|
|
let (blockhash, _) = rpc_client.get_latest_blockhash_with_commitment(commitment)?;
|
|
|
|
Ok(blockhash)
|
|
|
|
}
|
|
|
|
Self::NonceAccount(ref pubkey) => {
|
2021-10-05 22:24:48 -07:00
|
|
|
#[allow(clippy::redundant_closure)]
|
2021-08-13 09:08:20 -07:00
|
|
|
let data = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
|
|
|
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
2022-06-03 07:36:27 -07:00
|
|
|
Ok(data.blockhash())
|
2021-08-13 09:08:20 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_blockhash_valid(
|
|
|
|
&self,
|
|
|
|
rpc_client: &RpcClient,
|
|
|
|
blockhash: &Hash,
|
|
|
|
commitment: CommitmentConfig,
|
|
|
|
) -> Result<bool, Box<dyn std::error::Error>> {
|
|
|
|
Ok(match self {
|
|
|
|
Self::Cluster => rpc_client.is_blockhash_valid(blockhash, commitment)?,
|
|
|
|
Self::NonceAccount(ref pubkey) => {
|
2021-10-05 22:24:48 -07:00
|
|
|
#[allow(clippy::redundant_closure)]
|
2021-08-13 09:08:20 -07:00
|
|
|
let _ = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
|
|
|
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
|
|
|
true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2020-03-11 11:14:15 -07:00
|
|
|
}
|
|
|
|
|
2022-05-22 18:00:42 -07:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2020-03-11 11:14:15 -07:00
|
|
|
pub enum BlockhashQuery {
|
|
|
|
None(Hash),
|
|
|
|
FeeCalculator(Source, Hash),
|
|
|
|
All(Source),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BlockhashQuery {
|
|
|
|
pub fn new(blockhash: Option<Hash>, sign_only: bool, nonce_account: Option<Pubkey>) -> Self {
|
|
|
|
let source = nonce_account
|
|
|
|
.map(Source::NonceAccount)
|
|
|
|
.unwrap_or(Source::Cluster);
|
|
|
|
match blockhash {
|
|
|
|
Some(hash) if sign_only => Self::None(hash),
|
|
|
|
Some(hash) if !sign_only => Self::FeeCalculator(source, hash),
|
|
|
|
None if !sign_only => Self::All(source),
|
|
|
|
_ => panic!("Cannot resolve blockhash"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_from_matches(matches: &ArgMatches<'_>) -> Self {
|
|
|
|
let blockhash = value_of(matches, BLOCKHASH_ARG.name);
|
|
|
|
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
|
2020-09-21 14:12:51 -07:00
|
|
|
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
|
2020-03-11 11:14:15 -07:00
|
|
|
BlockhashQuery::new(blockhash, sign_only, nonce_account)
|
|
|
|
}
|
|
|
|
|
2021-10-26 09:06:41 -07:00
|
|
|
#[deprecated(since = "1.9.0", note = "Please use `get_blockhash` instead")]
|
2020-03-11 11:14:15 -07:00
|
|
|
pub fn get_blockhash_and_fee_calculator(
|
|
|
|
&self,
|
|
|
|
rpc_client: &RpcClient,
|
2020-06-17 11:18:48 -07:00
|
|
|
commitment: CommitmentConfig,
|
2020-03-11 11:14:15 -07:00
|
|
|
) -> Result<(Hash, FeeCalculator), Box<dyn std::error::Error>> {
|
|
|
|
match self {
|
|
|
|
BlockhashQuery::None(hash) => Ok((*hash, FeeCalculator::default())),
|
|
|
|
BlockhashQuery::FeeCalculator(source, hash) => {
|
2021-08-13 09:08:20 -07:00
|
|
|
#[allow(deprecated)]
|
2020-03-11 11:14:15 -07:00
|
|
|
let fee_calculator = source
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_fee_calculator(rpc_client, hash, commitment)?
|
2020-03-11 11:14:15 -07:00
|
|
|
.ok_or(format!("Hash has expired {:?}", hash))?;
|
|
|
|
Ok((*hash, fee_calculator))
|
|
|
|
}
|
2021-08-13 09:08:20 -07:00
|
|
|
BlockhashQuery::All(source) =>
|
|
|
|
{
|
|
|
|
#[allow(deprecated)]
|
2020-06-17 11:18:48 -07:00
|
|
|
source.get_blockhash_and_fee_calculator(rpc_client, commitment)
|
|
|
|
}
|
2020-03-11 11:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
2021-08-13 09:08:20 -07:00
|
|
|
|
|
|
|
pub fn get_blockhash(
|
|
|
|
&self,
|
|
|
|
rpc_client: &RpcClient,
|
|
|
|
commitment: CommitmentConfig,
|
|
|
|
) -> Result<Hash, Box<dyn std::error::Error>> {
|
|
|
|
match self {
|
|
|
|
BlockhashQuery::None(hash) => Ok(*hash),
|
|
|
|
BlockhashQuery::FeeCalculator(source, hash) => {
|
|
|
|
if !source.is_blockhash_valid(rpc_client, hash, commitment)? {
|
|
|
|
return Err(format!("Hash has expired {:?}", hash).into());
|
|
|
|
}
|
|
|
|
Ok(*hash)
|
|
|
|
}
|
|
|
|
BlockhashQuery::All(source) => source.get_blockhash(rpc_client, commitment),
|
|
|
|
}
|
|
|
|
}
|
2020-03-11 11:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for BlockhashQuery {
|
|
|
|
fn default() -> Self {
|
|
|
|
BlockhashQuery::All(Source::Cluster)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
super::*,
|
|
|
|
crate::{
|
|
|
|
blockhash_query,
|
|
|
|
rpc_request::RpcRequest,
|
|
|
|
rpc_response::{Response, RpcFeeCalculator, RpcFees, RpcResponseContext},
|
|
|
|
},
|
|
|
|
clap::App,
|
|
|
|
serde_json::{self, json},
|
|
|
|
solana_account_decoder::{UiAccount, UiAccountEncoding},
|
2022-06-03 07:36:27 -07:00
|
|
|
solana_sdk::{
|
|
|
|
account::Account,
|
|
|
|
hash::hash,
|
|
|
|
nonce::{self, state::DurableNonce},
|
|
|
|
system_program,
|
|
|
|
},
|
2021-12-03 09:00:31 -08:00
|
|
|
std::collections::HashMap,
|
2020-03-11 11:14:15 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_blockhash_query_new_ok() {
|
|
|
|
let blockhash = hash(&[1u8]);
|
|
|
|
let nonce_pubkey = Pubkey::new(&[1u8; 32]);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new(Some(blockhash), true, None),
|
|
|
|
BlockhashQuery::None(blockhash),
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new(Some(blockhash), false, None),
|
|
|
|
BlockhashQuery::FeeCalculator(blockhash_query::Source::Cluster, blockhash),
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new(None, false, None),
|
|
|
|
BlockhashQuery::All(blockhash_query::Source::Cluster)
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new(Some(blockhash), true, Some(nonce_pubkey)),
|
|
|
|
BlockhashQuery::None(blockhash),
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new(Some(blockhash), false, Some(nonce_pubkey)),
|
|
|
|
BlockhashQuery::FeeCalculator(
|
|
|
|
blockhash_query::Source::NonceAccount(nonce_pubkey),
|
|
|
|
blockhash
|
|
|
|
),
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new(None, false, Some(nonce_pubkey)),
|
|
|
|
BlockhashQuery::All(blockhash_query::Source::NonceAccount(nonce_pubkey)),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_blockhash_query_new_no_nonce_fail() {
|
|
|
|
BlockhashQuery::new(None, true, None);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_blockhash_query_new_nonce_fail() {
|
|
|
|
let nonce_pubkey = Pubkey::new(&[1u8; 32]);
|
|
|
|
BlockhashQuery::new(None, true, Some(nonce_pubkey));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_blockhash_query_new_from_matches_ok() {
|
2020-09-28 19:59:37 -07:00
|
|
|
let test_commands = App::new("blockhash_query_test")
|
|
|
|
.nonce_args(false)
|
2020-10-07 12:18:25 -07:00
|
|
|
.offline_args();
|
2020-03-11 11:14:15 -07:00
|
|
|
let blockhash = hash(&[1u8]);
|
|
|
|
let blockhash_string = blockhash.to_string();
|
|
|
|
|
|
|
|
let matches = test_commands.clone().get_matches_from(vec![
|
|
|
|
"blockhash_query_test",
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
"--sign-only",
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new_from_matches(&matches),
|
|
|
|
BlockhashQuery::None(blockhash),
|
|
|
|
);
|
|
|
|
|
|
|
|
let matches = test_commands.clone().get_matches_from(vec![
|
|
|
|
"blockhash_query_test",
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new_from_matches(&matches),
|
|
|
|
BlockhashQuery::FeeCalculator(blockhash_query::Source::Cluster, blockhash),
|
|
|
|
);
|
|
|
|
|
|
|
|
let matches = test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["blockhash_query_test"]);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new_from_matches(&matches),
|
|
|
|
BlockhashQuery::All(blockhash_query::Source::Cluster),
|
|
|
|
);
|
|
|
|
|
|
|
|
let nonce_pubkey = Pubkey::new(&[1u8; 32]);
|
|
|
|
let nonce_string = nonce_pubkey.to_string();
|
|
|
|
let matches = test_commands.clone().get_matches_from(vec![
|
|
|
|
"blockhash_query_test",
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
"--sign-only",
|
|
|
|
"--nonce",
|
|
|
|
&nonce_string,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new_from_matches(&matches),
|
|
|
|
BlockhashQuery::None(blockhash),
|
|
|
|
);
|
|
|
|
|
|
|
|
let matches = test_commands.clone().get_matches_from(vec![
|
|
|
|
"blockhash_query_test",
|
|
|
|
"--blockhash",
|
|
|
|
&blockhash_string,
|
|
|
|
"--nonce",
|
|
|
|
&nonce_string,
|
|
|
|
]);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::new_from_matches(&matches),
|
|
|
|
BlockhashQuery::FeeCalculator(
|
|
|
|
blockhash_query::Source::NonceAccount(nonce_pubkey),
|
|
|
|
blockhash
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_blockhash_query_new_from_matches_without_nonce_fail() {
|
|
|
|
let test_commands = App::new("blockhash_query_test")
|
|
|
|
.arg(blockhash_arg())
|
|
|
|
// We can really only hit this case if the arg requirements
|
|
|
|
// are broken, so unset the requires() to recreate that condition
|
|
|
|
.arg(sign_only_arg().requires(""));
|
|
|
|
|
|
|
|
let matches = test_commands
|
|
|
|
.clone()
|
|
|
|
.get_matches_from(vec!["blockhash_query_test", "--sign-only"]);
|
|
|
|
BlockhashQuery::new_from_matches(&matches);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_blockhash_query_new_from_matches_with_nonce_fail() {
|
|
|
|
let test_commands = App::new("blockhash_query_test")
|
|
|
|
.arg(blockhash_arg())
|
|
|
|
// We can really only hit this case if the arg requirements
|
|
|
|
// are broken, so unset the requires() to recreate that condition
|
|
|
|
.arg(sign_only_arg().requires(""));
|
|
|
|
let nonce_pubkey = Pubkey::new(&[1u8; 32]);
|
|
|
|
let nonce_string = nonce_pubkey.to_string();
|
|
|
|
|
|
|
|
let matches = test_commands.clone().get_matches_from(vec![
|
|
|
|
"blockhash_query_test",
|
|
|
|
"--sign-only",
|
|
|
|
"--nonce",
|
|
|
|
&nonce_string,
|
|
|
|
]);
|
|
|
|
BlockhashQuery::new_from_matches(&matches);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-08-13 09:08:20 -07:00
|
|
|
#[allow(deprecated)]
|
2020-03-11 11:14:15 -07:00
|
|
|
fn test_blockhash_query_get_blockhash_fee_calc() {
|
|
|
|
let test_blockhash = hash(&[0u8]);
|
|
|
|
let rpc_blockhash = hash(&[1u8]);
|
|
|
|
let rpc_fee_calc = FeeCalculator::new(42);
|
|
|
|
let get_recent_blockhash_response = json!(Response {
|
2022-05-11 21:17:21 -07:00
|
|
|
context: RpcResponseContext {
|
|
|
|
slot: 1,
|
|
|
|
api_version: None
|
|
|
|
},
|
2021-08-11 00:04:00 -07:00
|
|
|
value: json!(RpcFees {
|
|
|
|
blockhash: rpc_blockhash.to_string(),
|
2022-05-16 12:30:37 -07:00
|
|
|
fee_calculator: rpc_fee_calc,
|
2021-08-11 00:04:00 -07:00
|
|
|
last_valid_slot: 42,
|
|
|
|
last_valid_block_height: 42,
|
|
|
|
}),
|
2020-03-11 11:14:15 -07:00
|
|
|
});
|
|
|
|
let get_fee_calculator_for_blockhash_response = json!(Response {
|
2022-05-11 21:17:21 -07:00
|
|
|
context: RpcResponseContext {
|
|
|
|
slot: 1,
|
|
|
|
api_version: None
|
|
|
|
},
|
2020-03-11 11:14:15 -07:00
|
|
|
value: json!(RpcFeeCalculator {
|
2022-05-16 12:30:37 -07:00
|
|
|
fee_calculator: rpc_fee_calc
|
2020-03-11 11:14:15 -07:00
|
|
|
}),
|
|
|
|
});
|
|
|
|
let mut mocks = HashMap::new();
|
2021-08-11 00:04:00 -07:00
|
|
|
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response.clone());
|
2020-03-11 11:14:15 -07:00
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::default()
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.unwrap(),
|
2022-05-16 12:30:37 -07:00
|
|
|
(rpc_blockhash, rpc_fee_calc),
|
2020-03-11 11:14:15 -07:00
|
|
|
);
|
|
|
|
let mut mocks = HashMap::new();
|
2021-08-11 00:04:00 -07:00
|
|
|
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response.clone());
|
2020-03-11 11:14:15 -07:00
|
|
|
mocks.insert(
|
|
|
|
RpcRequest::GetFeeCalculatorForBlockhash,
|
2020-05-15 09:35:43 -07:00
|
|
|
get_fee_calculator_for_blockhash_response,
|
2020-03-11 11:14:15 -07:00
|
|
|
);
|
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::FeeCalculator(Source::Cluster, test_blockhash)
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.unwrap(),
|
2020-05-15 09:35:43 -07:00
|
|
|
(test_blockhash, rpc_fee_calc),
|
2020-03-11 11:14:15 -07:00
|
|
|
);
|
|
|
|
let mut mocks = HashMap::new();
|
2021-08-11 00:04:00 -07:00
|
|
|
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response);
|
2020-03-11 11:14:15 -07:00
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::None(test_blockhash)
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.unwrap(),
|
|
|
|
(test_blockhash, FeeCalculator::default()),
|
|
|
|
);
|
|
|
|
let rpc_client = RpcClient::new_mock("fails".to_string());
|
|
|
|
assert!(BlockhashQuery::default()
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.is_err());
|
|
|
|
|
2022-06-03 07:36:27 -07:00
|
|
|
let durable_nonce =
|
|
|
|
DurableNonce::from_blockhash(&Hash::new(&[2u8; 32]), /*separate_domains:*/ true);
|
|
|
|
let nonce_blockhash = *durable_nonce.as_hash();
|
2020-03-11 11:14:15 -07:00
|
|
|
let nonce_fee_calc = FeeCalculator::new(4242);
|
|
|
|
let data = nonce::state::Data {
|
|
|
|
authority: Pubkey::new(&[3u8; 32]),
|
2022-06-03 07:36:27 -07:00
|
|
|
durable_nonce,
|
2022-05-16 12:30:37 -07:00
|
|
|
fee_calculator: nonce_fee_calc,
|
2020-03-11 11:14:15 -07:00
|
|
|
};
|
|
|
|
let nonce_account = Account::new_data_with_space(
|
|
|
|
42,
|
2022-06-09 08:28:37 -07:00
|
|
|
&nonce::state::Versions::new(
|
|
|
|
nonce::State::Initialized(data),
|
|
|
|
true, // separate_domains
|
|
|
|
),
|
2020-03-11 11:14:15 -07:00
|
|
|
nonce::State::size(),
|
|
|
|
&system_program::id(),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
let nonce_pubkey = Pubkey::new(&[4u8; 32]);
|
2020-08-09 00:50:45 -07:00
|
|
|
let rpc_nonce_account = UiAccount::encode(
|
|
|
|
&nonce_pubkey,
|
2021-05-25 16:44:18 -07:00
|
|
|
&nonce_account,
|
2020-08-15 22:06:39 -07:00
|
|
|
UiAccountEncoding::Base64,
|
2020-08-09 00:50:45 -07:00
|
|
|
None,
|
2020-08-10 15:35:29 -07:00
|
|
|
None,
|
2020-08-09 00:50:45 -07:00
|
|
|
);
|
2020-03-11 11:14:15 -07:00
|
|
|
let get_account_response = json!(Response {
|
2022-05-11 21:17:21 -07:00
|
|
|
context: RpcResponseContext {
|
|
|
|
slot: 1,
|
|
|
|
api_version: None
|
|
|
|
},
|
2020-05-15 09:35:43 -07:00
|
|
|
value: json!(Some(rpc_nonce_account)),
|
2020-03-11 11:14:15 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
let mut mocks = HashMap::new();
|
|
|
|
mocks.insert(RpcRequest::GetAccountInfo, get_account_response.clone());
|
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::All(Source::NonceAccount(nonce_pubkey))
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.unwrap(),
|
2022-05-16 12:30:37 -07:00
|
|
|
(nonce_blockhash, nonce_fee_calc),
|
2020-03-11 11:14:15 -07:00
|
|
|
);
|
|
|
|
let mut mocks = HashMap::new();
|
|
|
|
mocks.insert(RpcRequest::GetAccountInfo, get_account_response.clone());
|
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::FeeCalculator(Source::NonceAccount(nonce_pubkey), nonce_blockhash)
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.unwrap(),
|
2020-05-15 09:35:43 -07:00
|
|
|
(nonce_blockhash, nonce_fee_calc),
|
2020-03-11 11:14:15 -07:00
|
|
|
);
|
|
|
|
let mut mocks = HashMap::new();
|
|
|
|
mocks.insert(RpcRequest::GetAccountInfo, get_account_response.clone());
|
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert!(
|
|
|
|
BlockhashQuery::FeeCalculator(Source::NonceAccount(nonce_pubkey), test_blockhash)
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.is_err()
|
|
|
|
);
|
|
|
|
let mut mocks = HashMap::new();
|
2020-05-15 09:35:43 -07:00
|
|
|
mocks.insert(RpcRequest::GetAccountInfo, get_account_response);
|
2020-03-11 11:14:15 -07:00
|
|
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
|
|
|
assert_eq!(
|
|
|
|
BlockhashQuery::None(nonce_blockhash)
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.unwrap(),
|
|
|
|
(nonce_blockhash, FeeCalculator::default()),
|
|
|
|
);
|
|
|
|
|
|
|
|
let rpc_client = RpcClient::new_mock("fails".to_string());
|
|
|
|
assert!(BlockhashQuery::All(Source::NonceAccount(nonce_pubkey))
|
2020-06-17 11:18:48 -07:00
|
|
|
.get_blockhash_and_fee_calculator(&rpc_client, CommitmentConfig::default())
|
2020-03-11 11:14:15 -07:00
|
|
|
.is_err());
|
|
|
|
}
|
|
|
|
}
|