Extend GetBlockHash RPC API to include the fee scehdule for using the returned blockhash (#4222)

This commit is contained in:
Michael Vines 2019-05-13 12:49:37 -07:00 committed by GitHub
parent 23c696706b
commit a2e3a92b01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 126 additions and 98 deletions

View File

@ -371,7 +371,7 @@ fn swapper<T>(
}
account_group = (account_group + 1) % account_groups as usize;
let blockhash = client
let (blockhash, _fee_calculator) = client
.get_recent_blockhash()
.expect("Failed to get blockhash");
let to_swap_txs: Vec<_> = to_swap
@ -499,7 +499,7 @@ fn trader<T>(
}
account_group = (account_group + 1) % account_groups as usize;
let blockhash = client
let (blockhash, _fee_calculator) = client
.get_recent_blockhash()
.expect("Failed to get blockhash");
@ -663,7 +663,8 @@ pub fn fund_keys(client: &Client, source: &Keypair, dests: &[Arc<Keypair>], lamp
to_fund_txs.len(),
);
let blockhash = client.get_recent_blockhash().expect("blockhash");
let (blockhash, _fee_calculator) =
client.get_recent_blockhash().expect("blockhash");
to_fund_txs.par_iter_mut().for_each(|(k, tx)| {
tx.sign(&[*k], blockhash);
});
@ -738,7 +739,7 @@ pub fn create_token_accounts(client: &Client, signers: &[Arc<Keypair>], accounts
let mut retries = 0;
while !to_create_txs.is_empty() {
let blockhash = client
let (blockhash, _fee_calculator) = client
.get_recent_blockhash()
.expect("Failed to get blockhash");
to_create_txs.par_iter_mut().for_each(|(k, tx)| {
@ -854,7 +855,7 @@ pub fn airdrop_lamports(client: &Client, drone_addr: &SocketAddr, id: &Keypair,
let mut tries = 0;
loop {
let blockhash = client
let (blockhash, _fee_calculator) = client
.get_recent_blockhash()
.expect("Failed to get blockhash");
match request_airdrop_transaction(&drone_addr, &id.pubkey(), amount_to_drop, blockhash) {

View File

@ -140,7 +140,7 @@ where
// this seems to be faster than trying to determine the balance of individual
// accounts
let len = tx_count as usize;
if let Ok(new_blockhash) = client.get_new_blockhash(&blockhash) {
if let Ok((new_blockhash, _fee_calculator)) = client.get_new_blockhash(&blockhash) {
blockhash = new_blockhash;
} else {
if blockhash_time.elapsed().as_secs() > 30 {
@ -404,7 +404,7 @@ pub fn fund_keys<T: Client>(client: &T, source: &Keypair, dests: &[Keypair], lam
to_fund_txs.len(),
);
let blockhash = client.get_recent_blockhash().unwrap();
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
// re-sign retained to_fund_txes with updated blockhash
to_fund_txs.par_iter_mut().for_each(|(k, tx)| {
@ -454,7 +454,7 @@ pub fn airdrop_lamports<T: Client>(
id.pubkey(),
);
let blockhash = client.get_recent_blockhash().unwrap();
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
match request_airdrop_transaction(&drone_addr, &id.pubkey(), airdrop_amount, blockhash) {
Ok(transaction) => {
let signature = client.async_send_transaction(transaction).unwrap();

View File

@ -167,13 +167,16 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
---
### getRecentBlockhash
Returns a recent block hash from the ledger
Returns a recent block hash from the ledger, and a fee schedule that can be used
to compute the cost of submitting a transaction using it.
##### Parameters:
None
##### Results:
An array consisting of
* `string` - a Hash as base-58 encoded string
* `FeeCalculator object` - the fee schedule for this block hash
##### Example:
```bash
@ -181,7 +184,7 @@ None
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getRecentBlockhash"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":"GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC","id":1}
{"jsonrpc":"2.0","result":["GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC",{"lamportsPerSignature": 0}],"id":1}
```
---

View File

@ -2,6 +2,7 @@ use crate::client_error::ClientError;
use crate::generic_rpc_client_request::GenericRpcClientRequest;
use crate::rpc_request::RpcRequest;
use serde_json::{Number, Value};
use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::transaction::{self, TransactionError};
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
@ -44,7 +45,10 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
let n = if self.url == "airdrop" { 0 } else { 50 };
Value::Number(Number::from(n))
}
RpcRequest::GetRecentBlockhash => Value::String(PUBKEY.to_string()),
RpcRequest::GetRecentBlockhash => Value::Array(vec![
Value::String(PUBKEY.to_string()),
serde_json::to_value(FeeCalculator::default()).unwrap(),
]),
RpcRequest::GetSignatureStatus => {
let response: Option<transaction::Result<()>> = if self.url == "account_in_use" {
Some(Err(TransactionError::AccountInUse))

View File

@ -7,6 +7,7 @@ use bincode::serialize;
use log::*;
use serde_json::{json, Value};
use solana_sdk::account::Account;
use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{KeypairUtil, Signature};
@ -186,7 +187,7 @@ impl RpcClient {
send_retries -= 1;
// Re-sign any failed transactions with a new blockhash and retry
let blockhash =
let (blockhash, _fee_calculator) =
self.get_new_blockhash(&transactions_signatures[0].0.message().recent_blockhash)?;
transactions = transactions_signatures
.into_iter()
@ -203,7 +204,8 @@ impl RpcClient {
tx: &mut Transaction,
signer_keys: &[&T],
) -> Result<(), ClientError> {
let blockhash = self.get_new_blockhash(&tx.message().recent_blockhash)?;
let (blockhash, _fee_calculator) =
self.get_new_blockhash(&tx.message().recent_blockhash)?;
tx.sign(signer_keys, blockhash);
Ok(())
}
@ -234,9 +236,11 @@ impl RpcClient {
trace!("Response account {:?} {:?}", pubkey, account);
Ok(account)
})
.map_err(|error| {
debug!("Response account {}: None (error: {:?})", pubkey, error);
io::Error::new(io::ErrorKind::Other, "AccountNotFound")
.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("AccountNotFound: pubkey={}: {}", pubkey, err),
)
})
}
@ -264,13 +268,15 @@ impl RpcClient {
)
})?;
serde_json::from_value(response).map_err(|error| {
debug!("ParseError: get_transaction_count: {}", error);
io::Error::new(io::ErrorKind::Other, "GetTransactionCount parse failure")
serde_json::from_value(response).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetTransactionCount parse failure: {}", err),
)
})
}
pub fn get_recent_blockhash(&self) -> io::Result<Hash> {
pub fn get_recent_blockhash(&self) -> io::Result<(Hash, FeeCalculator)> {
let response = self
.client
.send(&RpcRequest::GetRecentBlockhash, None, 0)
@ -281,21 +287,29 @@ impl RpcClient {
)
})?;
response
.as_str()
.ok_or_else(|| {
io::Error::new(io::ErrorKind::Other, "GetRecentBlockhash parse failure")
})?
.parse()
.map_err(|_| io::Error::new(io::ErrorKind::Other, "GetRecentBlockhash parse failure"))
let (blockhash, fee_calculator) =
serde_json::from_value::<(String, FeeCalculator)>(response).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetRecentBlockhash parse failure: {:?}", err),
)
})?;
let blockhash = blockhash.parse().map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetRecentBlockhash parse failure: {:?}", err),
)
})?;
Ok((blockhash, fee_calculator))
}
pub fn get_new_blockhash(&self, blockhash: &Hash) -> io::Result<Hash> {
pub fn get_new_blockhash(&self, blockhash: &Hash) -> io::Result<(Hash, FeeCalculator)> {
let mut num_retries = 10;
while num_retries > 0 {
if let Ok(new_blockhash) = self.get_recent_blockhash() {
if let Ok((new_blockhash, fee_calculator)) = self.get_recent_blockhash() {
if new_blockhash != *blockhash {
return Ok(new_blockhash);
return Ok((new_blockhash, fee_calculator));
}
}
debug!("Got same blockhash ({:?}), will retry...", blockhash);
@ -454,24 +468,22 @@ impl RpcClient {
Some(params.clone()),
1,
)
.map_err(|error| {
debug!(
"Response get_num_blocks_since_signature_confirmation: {:?}",
error
);
.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
"GetNumBlocksSinceSignatureConfirmation request failure",
format!(
"GetNumBlocksSinceSignatureConfirmation request failure: {}",
err
),
)
})?;
serde_json::from_value(response).map_err(|error| {
debug!(
"ParseError: get_num_blocks_since_signature_confirmation: {}",
error
);
serde_json::from_value(response).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
"GetNumBlocksSinceSignatureConfirmation parse failure",
format!(
"GetNumBlocksSinceSignatureConfirmation parse failure: {}",
err
),
)
})
}
@ -578,7 +590,7 @@ mod tests {
// Send erroneous parameter
let blockhash = rpc_client.retry_make_rpc_request(
&RpcRequest::GetRecentBlockhash,
Some(json!("paramter")),
Some(json!("parameter")),
0,
);
assert_eq!(blockhash.is_err(), true);
@ -646,13 +658,12 @@ mod tests {
let vec = bs58::decode(PUBKEY).into_vec().unwrap();
let expected_blockhash = Hash::new(&vec);
let blockhash = dbg!(rpc_client.get_recent_blockhash()).expect("blockhash ok");
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash().expect("blockhash ok");
assert_eq!(blockhash, expected_blockhash);
let rpc_client = RpcClient::new_mock("fails".to_string());
let blockhash = dbg!(rpc_client.get_recent_blockhash());
assert!(blockhash.is_err());
assert!(rpc_client.get_recent_blockhash().is_err());
}
#[test]

View File

@ -7,6 +7,7 @@ use crate::rpc_client::RpcClient;
use bincode::{serialize_into, serialized_size};
use log::*;
use solana_sdk::client::{AsyncClient, Client, SyncClient};
use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::hash::Hash;
use solana_sdk::instruction::Instruction;
use solana_sdk::message::Message;
@ -107,7 +108,8 @@ impl ThinClient {
return Ok(transaction.signatures[0]);
}
info!("{} tries failed transfer to {}", x, self.transactions_addr);
transaction.sign(keypairs, self.rpc_client.get_recent_blockhash()?);
let (blockhash, _fee_calculator) = self.rpc_client.get_recent_blockhash()?;
transaction.sign(keypairs, blockhash);
}
Err(io::Error::new(
io::ErrorKind::Other,
@ -159,7 +161,7 @@ impl Client for ThinClient {
impl SyncClient for ThinClient {
fn send_message(&self, keypairs: &[&Keypair], message: Message) -> TransportResult<Signature> {
let blockhash = self.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = self.get_recent_blockhash()?;
let mut transaction = Transaction::new(&keypairs, message, blockhash);
let signature = self.send_and_confirm_transaction(keypairs, &mut transaction, 5, 0)?;
Ok(signature)
@ -210,9 +212,8 @@ impl SyncClient for ThinClient {
Ok(status)
}
fn get_recent_blockhash(&self) -> TransportResult<Hash> {
let recent_blockhash = self.rpc_client.get_recent_blockhash()?;
Ok(recent_blockhash)
fn get_recent_blockhash(&self) -> TransportResult<(Hash, FeeCalculator)> {
Ok(self.rpc_client.get_recent_blockhash()?)
}
fn get_transaction_count(&self) -> TransportResult<u64> {
@ -235,9 +236,8 @@ impl SyncClient for ThinClient {
Ok(self.rpc_client.poll_for_signature(signature)?)
}
fn get_new_blockhash(&self, blockhash: &Hash) -> TransportResult<Hash> {
let new_blockhash = self.rpc_client.get_new_blockhash(blockhash)?;
Ok(new_blockhash)
fn get_new_blockhash(&self, blockhash: &Hash) -> TransportResult<(Hash, FeeCalculator)> {
Ok(self.rpc_client.get_new_blockhash(blockhash)?)
}
}

View File

@ -39,11 +39,12 @@ pub fn spend_and_verify_all_nodes(
.poll_get_balance(&funding_keypair.pubkey())
.expect("balance in source");
assert!(bal > 0);
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
let mut transaction = system_transaction::transfer(
&funding_keypair,
&random_keypair.pubkey(),
1,
client.get_recent_blockhash().unwrap(),
blockhash,
0,
);
let confs = VOTE_THRESHOLD_DEPTH + 1;
@ -65,11 +66,12 @@ pub fn send_many_transactions(node: &ContactInfo, funding_keypair: &Keypair, num
.poll_get_balance(&funding_keypair.pubkey())
.expect("balance in source");
assert!(bal > 0);
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
let mut transaction = system_transaction::transfer(
&funding_keypair,
&random_keypair.pubkey(),
1,
client.get_recent_blockhash().unwrap(),
blockhash,
0,
);
client
@ -187,11 +189,12 @@ pub fn kill_entry_and_spend_and_verify_rest(
}
let random_keypair = Keypair::new();
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
let mut transaction = system_transaction::transfer(
&funding_keypair,
&random_keypair.pubkey(),
1,
client.get_recent_blockhash().unwrap(),
blockhash,
0,
);

View File

@ -338,7 +338,7 @@ impl LocalCluster {
lamports: u64,
) -> u64 {
trace!("getting leader blockhash");
let blockhash = client.get_recent_blockhash().unwrap();
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
let mut tx = system_transaction::create_user_account(
&source_keypair,
dest_pubkey,
@ -378,10 +378,11 @@ impl LocalCluster {
0,
amount,
);
let (blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
let mut transaction = Transaction::new_signed_instructions(
&[from_account.as_ref()],
instructions,
client.get_recent_blockhash().unwrap(),
blockhash,
);
client

View File

@ -419,7 +419,7 @@ impl Replicator {
// check if the account exists
let bal = client.poll_get_balance(&storage_keypair.pubkey());
if bal.is_err() || bal.unwrap() == 0 {
let blockhash = client.get_recent_blockhash().expect("blockhash");
let (blockhash, _fee_calculator) = client.get_recent_blockhash().expect("blockhash");
//TODO the account space needs to be well defined somewhere
let tx = system_transaction::create_account(
keypair,

View File

@ -12,6 +12,7 @@ use jsonrpc_derive::rpc;
use solana_drone::drone::request_airdrop_transaction;
use solana_runtime::bank::Bank;
use solana_sdk::account::Account;
use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::Signature;
use solana_sdk::transaction::{self, Transaction};
@ -74,9 +75,12 @@ impl JsonRpcRequestProcessor {
self.bank().get_balance(&pubkey)
}
fn get_recent_blockhash(&self) -> String {
fn get_recent_blockhash(&self) -> (String, FeeCalculator) {
let id = self.bank().confirmed_last_blockhash();
bs58::encode(id).into_string()
(
bs58::encode(id).into_string(),
self.bank().fee_calculator.clone(),
)
}
pub fn get_signature_status(&self, signature: Signature) -> Option<transaction::Result<()>> {
@ -199,7 +203,7 @@ pub trait RpcSol {
fn get_cluster_nodes(&self, _: Self::Metadata) -> Result<Vec<RpcContactInfo>>;
#[rpc(meta, name = "getRecentBlockhash")]
fn get_recent_blockhash(&self, _: Self::Metadata) -> Result<String>;
fn get_recent_blockhash(&self, _: Self::Metadata) -> Result<(String, FeeCalculator)>;
#[rpc(meta, name = "getSignatureStatus")]
fn get_signature_status(
@ -303,7 +307,7 @@ impl RpcSol for RpcSolImpl {
.collect())
}
fn get_recent_blockhash(&self, meta: Self::Metadata) -> Result<String> {
fn get_recent_blockhash(&self, meta: Self::Metadata) -> Result<(String, FeeCalculator)> {
debug!("get_recent_blockhash rpc request received");
Ok(meta
.request_processor
@ -732,7 +736,10 @@ mod tests {
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getRecentBlockhash"}}"#);
let res = io.handle_request_sync(&req, meta);
let expected = format!(r#"{{"jsonrpc":"2.0","result":"{}","id":1}}"#, blockhash);
let expected = format!(
r#"{{"jsonrpc":"2.0","result":["{}", {{"lamportsPerSignature": 0}}],"id":1}}"#,
blockhash
);
let expected: Response =
serde_json::from_str(&expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))

View File

@ -35,7 +35,7 @@ fn test_rpc_send_tx() {
.send()
.unwrap();
let json: Value = serde_json::from_str(&response.text().unwrap()).unwrap();
let blockhash_vec = bs58::decode(json["result"].as_str().unwrap())
let blockhash_vec = bs58::decode(json["result"][0].as_str().unwrap())
.into_vec()
.unwrap();
let blockhash = Hash::new(&blockhash_vec);

View File

@ -197,7 +197,7 @@ fn new_update_manifest(
.get_account_data(&update_manifest_keypair.pubkey())
.is_err()
{
let recect_blockhash = rpc_client.get_recent_blockhash()?;
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let new_account = config_instruction::create_account::<SignedUpdateManifest>(
&from_keypair.pubkey(),
@ -205,7 +205,7 @@ fn new_update_manifest(
1, // lamports
);
let mut transaction = Transaction::new_unsigned_instructions(vec![new_account]);
transaction.sign(&[from_keypair], recect_blockhash);
transaction.sign(&[from_keypair], recent_blockhash);
rpc_client.send_and_confirm_transaction(&mut transaction, &[from_keypair])?;
}
@ -219,7 +219,7 @@ fn store_update_manifest(
update_manifest_keypair: &Keypair,
update_manifest: &SignedUpdateManifest,
) -> Result<(), Box<dyn std::error::Error>> {
let recect_blockhash = rpc_client.get_recent_blockhash()?;
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let signers = [from_keypair, update_manifest_keypair];
let instruction = config_instruction::store::<SignedUpdateManifest>(
@ -228,7 +228,7 @@ fn store_update_manifest(
);
let message = Message::new_with_payer(vec![instruction], Some(&from_keypair.pubkey()));
let mut transaction = Transaction::new(&signers, message, recect_blockhash);
let mut transaction = Transaction::new(&signers, message, recent_blockhash);
rpc_client.send_and_confirm_transaction(&mut transaction, &[from_keypair])?;
Ok(())
}

View File

@ -50,11 +50,8 @@ pub fn create_builtin_transactions(
.expect(&format!("{}:{}", line!(), file!()));
let instruction = create_invoke_instruction(rando0.pubkey(), program_id, &1u8);
Transaction::new_signed_instructions(
&[&rando0],
vec![instruction],
bank_client.get_recent_blockhash().unwrap(),
)
let (blockhash, _fee_calculator) = bank_client.get_recent_blockhash().unwrap();
Transaction::new_signed_instructions(&[&rando0], vec![instruction], blockhash)
})
.collect()
}
@ -76,11 +73,8 @@ pub fn create_native_loader_transactions(
.expect(&format!("{}:{}", line!(), file!()));
let instruction = create_invoke_instruction(rando0.pubkey(), program_id, &1u8);
Transaction::new_signed_instructions(
&[&rando0],
vec![instruction],
bank_client.get_recent_blockhash().unwrap(),
)
let (blockhash, _fee_calculator) = bank_client.get_recent_blockhash().unwrap();
Transaction::new_signed_instructions(&[&rando0], vec![instruction], blockhash)
})
.collect()
}

View File

@ -1,5 +1,6 @@
use crate::bank::Bank;
use solana_sdk::client::{AsyncClient, Client, SyncClient};
use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::hash::Hash;
use solana_sdk::instruction::Instruction;
use solana_sdk::message::Message;
@ -105,9 +106,10 @@ impl SyncClient for BankClient {
Ok(self.bank.get_signature_status(signature))
}
fn get_recent_blockhash(&self) -> Result<Hash> {
fn get_recent_blockhash(&self) -> Result<(Hash, FeeCalculator)> {
let last_blockhash = self.bank.last_blockhash();
Ok(last_blockhash)
let fee_calculator = self.bank.fee_calculator.clone();
Ok((last_blockhash, fee_calculator))
}
fn get_transaction_count(&self) -> Result<u64> {
@ -167,10 +169,10 @@ impl SyncClient for BankClient {
Ok(())
}
fn get_new_blockhash(&self, blockhash: &Hash) -> Result<Hash> {
let last_blockhash = self.bank.last_blockhash();
fn get_new_blockhash(&self, blockhash: &Hash) -> Result<(Hash, FeeCalculator)> {
let (last_blockhash, fee_calculator) = self.get_recent_blockhash()?;
if last_blockhash != *blockhash {
Ok(last_blockhash)
Ok((last_blockhash, fee_calculator))
} else {
Err(TransportError::IoError(io::Error::new(
io::ErrorKind::Other,

View File

@ -7,6 +7,7 @@
//! Asynchronous implementations are expected to create transactions, sign them, and send
//! them but without waiting to see if the server accepted it.
use crate::fee_calculator::FeeCalculator;
use crate::hash::Hash;
use crate::instruction::Instruction;
use crate::message::Message;
@ -46,7 +47,7 @@ pub trait SyncClient {
) -> Result<Option<transaction::Result<()>>>;
/// Get recent blockhash
fn get_recent_blockhash(&self) -> Result<Hash>;
fn get_recent_blockhash(&self) -> Result<(Hash, FeeCalculator)>;
/// Get transaction count
fn get_transaction_count(&self) -> Result<u64>;
@ -61,7 +62,7 @@ pub trait SyncClient {
/// Poll to confirm a transaction.
fn poll_for_signature(&self, signature: &Signature) -> Result<()>;
fn get_new_blockhash(&self, blockhash: &Hash) -> Result<Hash>;
fn get_new_blockhash(&self, blockhash: &Hash) -> Result<(Hash, FeeCalculator)>;
}
pub trait AsyncClient {

View File

@ -1,6 +1,7 @@
use crate::message::Message;
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct FeeCalculator {
pub lamports_per_signature: u64,
}

View File

@ -388,7 +388,7 @@ fn process_create_vote_account(
commission,
lamports,
);
let recent_blockhash = rpc_client.get_recent_blockhash()?;
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let mut tx = Transaction::new_signed_instructions(&[&config.keypair], ixs, recent_blockhash);
let signature_str = rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair])?;
Ok(signature_str.to_string())
@ -399,7 +399,7 @@ fn process_authorize_voter(
config: &WalletConfig,
authorized_voter_id: &Pubkey,
) -> ProcessResult {
let recent_blockhash = rpc_client.get_recent_blockhash()?;
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ixs = vec![vote_instruction::authorize_voter(
&config.keypair.pubkey(),
authorized_voter_id,
@ -457,7 +457,7 @@ fn process_create_stake_account(
staking_account_id: &Pubkey,
lamports: u64,
) -> ProcessResult {
let recent_blockhash = rpc_client.get_recent_blockhash()?;
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ixs = vec![stake_instruction::create_account(
&config.keypair.pubkey(),
staking_account_id,
@ -474,7 +474,7 @@ fn process_delegate_stake(
staking_account_keypair: &Keypair,
voting_account_id: &Pubkey,
) -> ProcessResult {
let recent_blockhash = rpc_client.get_recent_blockhash()?;
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ixs = vec![stake_instruction::delegate_stake(
&config.keypair.pubkey(),
&staking_account_keypair.pubkey(),
@ -527,7 +527,7 @@ fn process_deploy(
}
}
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let program_id = Keypair::new();
let mut file = File::open(program_location).map_err(|err| {
WalletError::DynamicProgramError(
@ -600,7 +600,7 @@ fn process_pay(
witnesses: &Option<Vec<Pubkey>>,
cancelable: Option<Pubkey>,
) -> ProcessResult {
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
if timestamp == None && *witnesses == None {
let mut tx = system_transaction::transfer(&config.keypair, to, lamports, blockhash, 0);
@ -636,7 +636,7 @@ fn process_pay(
})
.to_string())
} else if timestamp == None {
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let witness = if let Some(ref witness_vec) = *witnesses {
witness_vec[0]
@ -672,7 +672,7 @@ fn process_pay(
}
fn process_cancel(rpc_client: &RpcClient, config: &WalletConfig, pubkey: &Pubkey) -> ProcessResult {
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ix = budget_instruction::apply_signature(
&config.keypair.pubkey(),
pubkey,
@ -703,7 +703,7 @@ fn process_time_elapsed(
request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.keypair.pubkey(), 1)?;
}
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ix = budget_instruction::apply_timestamp(&config.keypair.pubkey(), pubkey, to, dt);
let mut tx = Transaction::new_signed_instructions(&[&config.keypair], vec![ix], blockhash);
@ -726,7 +726,7 @@ fn process_witness(
request_and_confirm_airdrop(&rpc_client, &drone_addr, &config.keypair.pubkey(), 1)?;
}
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ix = budget_instruction::apply_signature(&config.keypair.pubkey(), pubkey, to);
let mut tx = Transaction::new_signed_instructions(&[&config.keypair], vec![ix], blockhash);
let result = rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair]);
@ -891,7 +891,7 @@ pub fn request_and_confirm_airdrop(
to_pubkey: &Pubkey,
lamports: u64,
) -> Result<(), Box<dyn error::Error>> {
let blockhash = rpc_client.get_recent_blockhash()?;
let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let keypair = {
let mut retries = 5;
loop {