Update fee api to use blockhash (#21054)
This commit is contained in:
parent
aea3c66fa8
commit
bced07a099
|
@ -248,7 +248,7 @@ fn run_accounts_bench(
|
|||
let executor = TransactionExecutor::new(entrypoint_addr);
|
||||
|
||||
// Create and close messages both require 2 signatures, fake a 2 signature message to calculate fees
|
||||
let message = Message::new(
|
||||
let mut message = Message::new(
|
||||
&[
|
||||
Instruction::new_with_bytes(
|
||||
Pubkey::new_unique(),
|
||||
|
@ -270,6 +270,7 @@ fn run_accounts_bench(
|
|||
latest_blockhash = Instant::now();
|
||||
}
|
||||
|
||||
message.recent_blockhash = blockhash;
|
||||
let fee = client
|
||||
.get_fee_for_message(&message)
|
||||
.expect("get_fee_for_message");
|
||||
|
|
|
@ -289,7 +289,7 @@ impl Banks for BanksServer {
|
|||
) -> Option<u64> {
|
||||
let bank = self.bank(commitment);
|
||||
let sanitized_message = SanitizedMessage::try_from(message).ok()?;
|
||||
Some(bank.get_fee_for_message(&sanitized_message))
|
||||
bank.get_fee_for_message(&sanitized_message)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use solana_measure::measure::Measure;
|
|||
use solana_metrics::{self, datapoint_info};
|
||||
use solana_sdk::{
|
||||
client::Client,
|
||||
clock::{DEFAULT_S_PER_SLOT, MAX_PROCESSING_AGE},
|
||||
clock::{DEFAULT_MS_PER_SLOT, DEFAULT_S_PER_SLOT, MAX_PROCESSING_AGE},
|
||||
commitment_config::CommitmentConfig,
|
||||
hash::Hash,
|
||||
instruction::{AccountMeta, Instruction},
|
||||
|
@ -389,6 +389,22 @@ fn generate_txs(
|
|||
}
|
||||
}
|
||||
|
||||
fn get_new_latest_blockhash<T: Client>(client: &Arc<T>, blockhash: &Hash) -> Option<Hash> {
|
||||
let start = Instant::now();
|
||||
while start.elapsed().as_secs() < 5 {
|
||||
if let Ok(new_blockhash) = client.get_latest_blockhash() {
|
||||
if new_blockhash != *blockhash {
|
||||
return Some(new_blockhash);
|
||||
}
|
||||
}
|
||||
debug!("Got same blockhash ({:?}), will retry...", blockhash);
|
||||
|
||||
// Retry ~twice during a slot
|
||||
sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT / 2));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn poll_blockhash<T: Client>(
|
||||
exit_signal: &Arc<AtomicBool>,
|
||||
blockhash: &Arc<RwLock<Hash>>,
|
||||
|
@ -400,7 +416,7 @@ fn poll_blockhash<T: Client>(
|
|||
loop {
|
||||
let blockhash_updated = {
|
||||
let old_blockhash = *blockhash.read().unwrap();
|
||||
if let Ok(new_blockhash) = client.get_new_latest_blockhash(&old_blockhash) {
|
||||
if let Some(new_blockhash) = get_new_latest_blockhash(client, &old_blockhash) {
|
||||
*blockhash.write().unwrap() = new_blockhash;
|
||||
blockhash_last_updated = Instant::now();
|
||||
true
|
||||
|
@ -888,13 +904,14 @@ pub fn generate_and_fund_keypairs<T: 'static + Client + Send + Sync>(
|
|||
// pay for the transaction fees in a new run.
|
||||
let enough_lamports = 8 * lamports_per_account / 10;
|
||||
if first_keypair_balance < enough_lamports || last_keypair_balance < enough_lamports {
|
||||
let single_sig_message = Message::new(
|
||||
let single_sig_message = Message::new_with_blockhash(
|
||||
&[Instruction::new_with_bytes(
|
||||
Pubkey::new_unique(),
|
||||
&[],
|
||||
vec![AccountMeta::new(Pubkey::new_unique(), true)],
|
||||
)],
|
||||
None,
|
||||
&client.get_latest_blockhash().unwrap(),
|
||||
);
|
||||
let max_fee = client.get_fee_for_message(&single_sig_message).unwrap();
|
||||
let extra_fees = extra * max_fee;
|
||||
|
|
|
@ -65,7 +65,7 @@ pub fn check_account_for_spend_multiple_fees_with_commitment(
|
|||
messages: &[&Message],
|
||||
commitment: CommitmentConfig,
|
||||
) -> Result<(), CliError> {
|
||||
let fee = get_fee_for_message(rpc_client, messages)?;
|
||||
let fee = get_fee_for_messages(rpc_client, messages)?;
|
||||
if !check_account_for_balance_with_commitment(
|
||||
rpc_client,
|
||||
account_pubkey,
|
||||
|
@ -90,10 +90,16 @@ pub fn check_account_for_spend_multiple_fees_with_commitment(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_fee_for_message(rpc_client: &RpcClient, messages: &[&Message]) -> Result<u64, CliError> {
|
||||
pub fn get_fee_for_messages(
|
||||
rpc_client: &RpcClient,
|
||||
messages: &[&Message],
|
||||
) -> Result<u64, CliError> {
|
||||
Ok(messages
|
||||
.iter()
|
||||
.map(|message| rpc_client.get_fee_for_message(message))
|
||||
.map(|message| {
|
||||
println!("msg {:?}", message.recent_blockhash);
|
||||
rpc_client.get_fee_for_message(message)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.iter()
|
||||
.sum())
|
||||
|
@ -235,7 +241,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_fee_for_message() {
|
||||
fn test_get_fee_for_messages() {
|
||||
let check_fee_response = json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: json!(1),
|
||||
|
@ -245,14 +251,14 @@ mod tests {
|
|||
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
||||
|
||||
// No messages, no fee.
|
||||
assert_eq!(get_fee_for_message(&rpc_client, &[]).unwrap(), 0);
|
||||
assert_eq!(get_fee_for_messages(&rpc_client, &[]).unwrap(), 0);
|
||||
|
||||
// One message w/ one signature, a fee.
|
||||
let pubkey0 = Pubkey::new(&[0; 32]);
|
||||
let pubkey1 = Pubkey::new(&[1; 32]);
|
||||
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
||||
let message0 = Message::new(&[ix0], Some(&pubkey0));
|
||||
assert_eq!(get_fee_for_message(&rpc_client, &[&message0]).unwrap(), 1);
|
||||
assert_eq!(get_fee_for_messages(&rpc_client, &[&message0]).unwrap(), 1);
|
||||
|
||||
// No signatures, no fee.
|
||||
let check_fee_response = json!(Response {
|
||||
|
@ -264,7 +270,7 @@ mod tests {
|
|||
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
||||
let message = Message::default();
|
||||
assert_eq!(
|
||||
get_fee_for_message(&rpc_client, &[&message, &message]).unwrap(),
|
||||
get_fee_for_messages(&rpc_client, &[&message, &message]).unwrap(),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1710,6 +1710,7 @@ fn do_process_program_write_and_deploy(
|
|||
) -> ProcessResult {
|
||||
// Build messages to calculate fees
|
||||
let mut messages: Vec<&Message> = Vec::new();
|
||||
let blockhash = rpc_client.get_latest_blockhash()?;
|
||||
|
||||
// Initialize buffer account or complete if already partially initialized
|
||||
let (initial_message, write_messages, balance_needed) =
|
||||
|
@ -1755,9 +1756,10 @@ fn do_process_program_write_and_deploy(
|
|||
)
|
||||
};
|
||||
let initial_message = if !initial_instructions.is_empty() {
|
||||
Some(Message::new(
|
||||
Some(Message::new_with_blockhash(
|
||||
&initial_instructions,
|
||||
Some(&config.signers[0].pubkey()),
|
||||
&blockhash,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
|
@ -1777,7 +1779,7 @@ fn do_process_program_write_and_deploy(
|
|||
} else {
|
||||
loader_instruction::write(buffer_pubkey, loader_id, offset, bytes)
|
||||
};
|
||||
Message::new(&[instruction], Some(&payer_pubkey))
|
||||
Message::new_with_blockhash(&[instruction], Some(&payer_pubkey), &blockhash)
|
||||
};
|
||||
|
||||
let mut write_messages = vec![];
|
||||
|
@ -1806,7 +1808,7 @@ fn do_process_program_write_and_deploy(
|
|||
|
||||
let final_message = if let Some(program_signers) = program_signers {
|
||||
let message = if loader_id == &bpf_loader_upgradeable::id() {
|
||||
Message::new(
|
||||
Message::new_with_blockhash(
|
||||
&bpf_loader_upgradeable::deploy_with_max_program_len(
|
||||
&config.signers[0].pubkey(),
|
||||
&program_signers[0].pubkey(),
|
||||
|
@ -1818,11 +1820,13 @@ fn do_process_program_write_and_deploy(
|
|||
programdata_len,
|
||||
)?,
|
||||
Some(&config.signers[0].pubkey()),
|
||||
&blockhash,
|
||||
)
|
||||
} else {
|
||||
Message::new(
|
||||
Message::new_with_blockhash(
|
||||
&[loader_instruction::finalize(buffer_pubkey, loader_id)],
|
||||
Some(&config.signers[0].pubkey()),
|
||||
&blockhash,
|
||||
)
|
||||
};
|
||||
Some(message)
|
||||
|
@ -1876,6 +1880,7 @@ fn do_process_program_upgrade(
|
|||
|
||||
// Build messages to calculate fees
|
||||
let mut messages: Vec<&Message> = Vec::new();
|
||||
let blockhash = rpc_client.get_latest_blockhash()?;
|
||||
|
||||
let (initial_message, write_messages, balance_needed) =
|
||||
if let Some(buffer_signer) = buffer_signer {
|
||||
|
@ -1907,9 +1912,10 @@ fn do_process_program_upgrade(
|
|||
};
|
||||
|
||||
let initial_message = if !initial_instructions.is_empty() {
|
||||
Some(Message::new(
|
||||
Some(Message::new_with_blockhash(
|
||||
&initial_instructions,
|
||||
Some(&config.signers[0].pubkey()),
|
||||
&blockhash,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
|
@ -1925,7 +1931,7 @@ fn do_process_program_upgrade(
|
|||
offset,
|
||||
bytes,
|
||||
);
|
||||
Message::new(&[instruction], Some(&payer_pubkey))
|
||||
Message::new_with_blockhash(&[instruction], Some(&payer_pubkey), &blockhash)
|
||||
};
|
||||
|
||||
// Create and add write messages
|
||||
|
@ -1952,7 +1958,7 @@ fn do_process_program_upgrade(
|
|||
}
|
||||
|
||||
// Create and add final message
|
||||
let final_message = Message::new(
|
||||
let final_message = Message::new_with_blockhash(
|
||||
&[bpf_loader_upgradeable::upgrade(
|
||||
program_id,
|
||||
buffer_pubkey,
|
||||
|
@ -1960,6 +1966,7 @@ fn do_process_program_upgrade(
|
|||
&config.signers[0].pubkey(),
|
||||
)],
|
||||
Some(&config.signers[0].pubkey()),
|
||||
&blockhash,
|
||||
);
|
||||
messages.push(&final_message);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
checks::{check_account_for_balance_with_commitment, get_fee_for_message},
|
||||
checks::{check_account_for_balance_with_commitment, get_fee_for_messages},
|
||||
cli::CliError,
|
||||
};
|
||||
use clap::ArgMatches;
|
||||
|
@ -144,9 +144,10 @@ where
|
|||
F: Fn(u64) -> Message,
|
||||
{
|
||||
let fee = match blockhash {
|
||||
Some(_) => {
|
||||
let dummy_message = build_message(0);
|
||||
get_fee_for_message(rpc_client, &[&dummy_message])?
|
||||
Some(blockhash) => {
|
||||
let mut dummy_message = build_message(0);
|
||||
dummy_message.recent_blockhash = *blockhash;
|
||||
get_fee_for_messages(rpc_client, &[&dummy_message])?
|
||||
}
|
||||
None => 0, // Offline, cannot calulate fee
|
||||
};
|
||||
|
|
|
@ -4285,7 +4285,7 @@ impl RpcClient {
|
|||
|
||||
#[deprecated(
|
||||
since = "1.9.0",
|
||||
note = "Please use `get_new_latest_blockhash` instead"
|
||||
note = "Please do not use, will no longer be available in the future"
|
||||
)]
|
||||
#[allow(deprecated)]
|
||||
pub fn get_new_blockhash(&self, blockhash: &Hash) -> ClientResult<(Hash, FeeCalculator)> {
|
||||
|
@ -4802,7 +4802,9 @@ impl RpcClient {
|
|||
#[allow(deprecated)]
|
||||
pub fn get_fee_for_message(&self, message: &Message) -> ClientResult<u64> {
|
||||
if self.get_node_version()? < semver::Version::new(1, 9, 0) {
|
||||
let Fees { fee_calculator, .. } = self.get_fees()?;
|
||||
let fee_calculator = self
|
||||
.get_fee_calculator_for_blockhash(&message.recent_blockhash)?
|
||||
.ok_or_else(|| ClientErrorKind::Custom("Invalid blockhash".to_string()))?;
|
||||
Ok(fee_calculator
|
||||
.lamports_per_signature
|
||||
.saturating_mul(message.header.num_required_signatures as u64))
|
||||
|
|
|
@ -605,12 +605,6 @@ impl SyncClient for ThinClient {
|
|||
.get_fee_for_message(message)
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
fn get_new_latest_blockhash(&self, blockhash: &Hash) -> TransportResult<Hash> {
|
||||
self.rpc_client()
|
||||
.get_new_latest_blockhash(blockhash)
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncClient for ThinClient {
|
||||
|
|
|
@ -1978,10 +1978,10 @@ impl JsonRpcRequestProcessor {
|
|||
&self,
|
||||
message: &SanitizedMessage,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<Option<u64>>> {
|
||||
) -> RpcResponse<Option<u64>> {
|
||||
let bank = self.bank(commitment);
|
||||
let fee = bank.get_fee_for_message(message);
|
||||
Ok(new_response(&bank, Some(fee)))
|
||||
new_response(&bank, fee)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3706,11 +3706,10 @@ pub mod rpc_full {
|
|||
debug!("get_fee_for_message rpc request received");
|
||||
let (_, message) =
|
||||
decode_and_deserialize::<Message>(data, UiTransactionEncoding::Base64)?;
|
||||
SanitizedMessage::try_from(message)
|
||||
.map_err(|err| {
|
||||
let sanitized_message = SanitizedMessage::try_from(message).map_err(|err| {
|
||||
Error::invalid_params(format!("invalid transaction message: {}", err))
|
||||
})
|
||||
.and_then(|message| meta.get_fee_for_message(&message, commitment))
|
||||
})?;
|
||||
Ok(meta.get_fee_for_message(&sanitized_message, commitment))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3118,8 +3118,11 @@ impl Bank {
|
|||
&self.fee_rate_governor
|
||||
}
|
||||
|
||||
pub fn get_fee_for_message(&self, message: &SanitizedMessage) -> u64 {
|
||||
Self::calculate_fee(message, self.fee_rate_governor.lamports_per_signature)
|
||||
pub fn get_fee_for_message(&self, message: &SanitizedMessage) -> Option<u64> {
|
||||
let blockhash_queue = self.blockhash_queue.read().unwrap();
|
||||
let lamports_per_signature =
|
||||
blockhash_queue.get_lamports_per_signature(message.recent_blockhash())?;
|
||||
Some(Self::calculate_fee(message, lamports_per_signature))
|
||||
}
|
||||
|
||||
pub fn get_fee_for_message_with_lamports_per_signature(
|
||||
|
@ -11022,8 +11025,12 @@ pub(crate) mod tests {
|
|||
assert_eq!(bank.process_transaction(&durable_tx), Ok(()));
|
||||
|
||||
/* Check balances */
|
||||
let mut expected_balance =
|
||||
4_650_000 - bank.get_fee_for_message(&durable_tx.message.try_into().unwrap());
|
||||
let mut recent_message = durable_tx.message;
|
||||
recent_message.recent_blockhash = bank.last_blockhash();
|
||||
let mut expected_balance = 4_650_000
|
||||
- bank
|
||||
.get_fee_for_message(&recent_message.try_into().unwrap())
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance);
|
||||
assert_eq!(bank.get_balance(&nonce_pubkey), 250_000);
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 100_000);
|
||||
|
@ -11075,8 +11082,11 @@ pub(crate) mod tests {
|
|||
))
|
||||
);
|
||||
/* Check fee charged and nonce has advanced */
|
||||
let mut recent_message = durable_tx.message.clone();
|
||||
recent_message.recent_blockhash = bank.last_blockhash();
|
||||
expected_balance -= bank
|
||||
.get_fee_for_message(&SanitizedMessage::try_from(durable_tx.message.clone()).unwrap());
|
||||
.get_fee_for_message(&SanitizedMessage::try_from(recent_message).unwrap())
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance);
|
||||
assert_ne!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap());
|
||||
/* Confirm replaying a TX that failed with InstructionError::* now
|
||||
|
@ -11135,10 +11145,14 @@ pub(crate) mod tests {
|
|||
))
|
||||
);
|
||||
/* Check fee charged and nonce has *not* advanced */
|
||||
let mut recent_message = durable_tx.message;
|
||||
recent_message.recent_blockhash = bank.last_blockhash();
|
||||
assert_eq!(
|
||||
bank.get_balance(&custodian_pubkey),
|
||||
initial_custodian_balance
|
||||
- bank.get_fee_for_message(&durable_tx.message.try_into().unwrap())
|
||||
- bank
|
||||
.get_fee_for_message(&recent_message.try_into().unwrap())
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap());
|
||||
}
|
||||
|
@ -11185,10 +11199,14 @@ pub(crate) mod tests {
|
|||
))
|
||||
);
|
||||
/* Check fee charged and nonce has advanced */
|
||||
let mut recent_message = durable_tx.message;
|
||||
recent_message.recent_blockhash = bank.last_blockhash();
|
||||
assert_eq!(
|
||||
bank.get_balance(&nonce_pubkey),
|
||||
nonce_starting_balance
|
||||
- bank.get_fee_for_message(&durable_tx.message.try_into().unwrap())
|
||||
- bank
|
||||
.get_fee_for_message(&recent_message.try_into().unwrap())
|
||||
.unwrap()
|
||||
);
|
||||
assert_ne!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap());
|
||||
}
|
||||
|
|
|
@ -314,26 +314,16 @@ impl SyncClient for BankClient {
|
|||
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64> {
|
||||
SanitizedMessage::try_from(message.clone())
|
||||
.map(|message| self.bank.get_fee_for_message(&message))
|
||||
.map_err(|_| {
|
||||
.ok()
|
||||
.map(|sanitized_message| self.bank.get_fee_for_message(&sanitized_message))
|
||||
.flatten()
|
||||
.ok_or_else(|| {
|
||||
TransportError::IoError(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Unable calculate fee",
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn get_new_latest_blockhash(&self, blockhash: &Hash) -> Result<Hash> {
|
||||
let latest_blockhash = self.get_latest_blockhash()?;
|
||||
if latest_blockhash != *blockhash {
|
||||
Ok(latest_blockhash)
|
||||
} else {
|
||||
Err(TransportError::IoError(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Unable to get new blockhash",
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BankClient {
|
||||
|
|
|
@ -3042,18 +3042,19 @@ mod tests {
|
|||
|
||||
let slot = slot + 1;
|
||||
let bank2 = Arc::new(Bank::new_from_parent(&bank1, &collector, slot));
|
||||
let blockhash = bank2.last_blockhash();
|
||||
let tx = SanitizedTransaction::from_transaction_for_tests(system_transaction::transfer(
|
||||
&key1,
|
||||
&key2.pubkey(),
|
||||
lamports_to_transfer,
|
||||
bank2.last_blockhash(),
|
||||
blockhash,
|
||||
));
|
||||
let fee = bank2.get_fee_for_message(tx.message());
|
||||
let fee = bank2.get_fee_for_message(tx.message()).unwrap();
|
||||
let tx = system_transaction::transfer(
|
||||
&key1,
|
||||
&key2.pubkey(),
|
||||
lamports_to_transfer - fee,
|
||||
bank2.last_blockhash(),
|
||||
blockhash,
|
||||
);
|
||||
bank2.process_transaction(&tx).unwrap();
|
||||
assert_eq!(
|
||||
|
|
|
@ -245,6 +245,14 @@ impl Message {
|
|||
}
|
||||
|
||||
pub fn new(instructions: &[Instruction], payer: Option<&Pubkey>) -> Self {
|
||||
Self::new_with_blockhash(instructions, payer, &Hash::default())
|
||||
}
|
||||
|
||||
pub fn new_with_blockhash(
|
||||
instructions: &[Instruction],
|
||||
payer: Option<&Pubkey>,
|
||||
blockhash: &Hash,
|
||||
) -> Self {
|
||||
let InstructionKeys {
|
||||
mut signed_keys,
|
||||
unsigned_keys,
|
||||
|
@ -259,7 +267,7 @@ impl Message {
|
|||
num_readonly_signed_accounts,
|
||||
num_readonly_unsigned_accounts,
|
||||
signed_keys,
|
||||
Hash::default(),
|
||||
*blockhash,
|
||||
instructions,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ pub trait SyncClient {
|
|||
/// Get recent blockhash. Uses explicit commitment configuration.
|
||||
#[deprecated(
|
||||
since = "1.9.0",
|
||||
note = "Please use `get_latest_blockhash_with_commitment` and `get_fee_for_message` instead"
|
||||
note = "Please use `get_latest_blockhash_with_commitment` and `get_latest_blockhash_with_commitment` instead"
|
||||
)]
|
||||
fn get_recent_blockhash_with_commitment(
|
||||
&self,
|
||||
|
@ -151,7 +151,7 @@ pub trait SyncClient {
|
|||
|
||||
#[deprecated(
|
||||
since = "1.9.0",
|
||||
note = "Please use `get_new_latest_blockhash` instead"
|
||||
note = "Please do not use, will no longer be available in the future"
|
||||
)]
|
||||
fn get_new_blockhash(&self, blockhash: &Hash) -> Result<(Hash, FeeCalculator)>;
|
||||
|
||||
|
@ -169,9 +169,6 @@ pub trait SyncClient {
|
|||
|
||||
/// Calculate the fee for a `Message`
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64>;
|
||||
|
||||
/// Get a new blockhash after the one specified
|
||||
fn get_new_latest_blockhash(&self, blockhash: &Hash) -> Result<Hash>;
|
||||
}
|
||||
|
||||
pub trait AsyncClient {
|
||||
|
|
|
@ -562,7 +562,7 @@ impl TestValidator {
|
|||
{
|
||||
let rpc_client =
|
||||
RpcClient::new_with_commitment(rpc_url.clone(), CommitmentConfig::processed());
|
||||
let message = Message::new(
|
||||
let mut message = Message::new(
|
||||
&[Instruction::new_with_bytes(
|
||||
Pubkey::new_unique(),
|
||||
&[],
|
||||
|
@ -579,7 +579,9 @@ impl TestValidator {
|
|||
}
|
||||
println!("Waiting for fees to stabilize {:?}...", num_tries);
|
||||
match rpc_client.get_latest_blockhash() {
|
||||
Ok(_) => match rpc_client.get_fee_for_message(&message) {
|
||||
Ok(blockhash) => {
|
||||
message.recent_blockhash = blockhash;
|
||||
match rpc_client.get_fee_for_message(&message) {
|
||||
Ok(fee) => {
|
||||
if fee != 0 {
|
||||
break;
|
||||
|
@ -589,7 +591,8 @@ impl TestValidator {
|
|||
warn!("get_fee_for_message() failed: {:?}", err);
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("get_latest_blockhash() failed: {:?}", err);
|
||||
break;
|
||||
|
|
|
@ -340,7 +340,11 @@ fn build_messages(
|
|||
do_create_associated_token_account,
|
||||
);
|
||||
let fee_payer_pubkey = args.fee_payer.pubkey();
|
||||
let message = Message::new(&instructions, Some(&fee_payer_pubkey));
|
||||
let message = Message::new_with_blockhash(
|
||||
&instructions,
|
||||
Some(&fee_payer_pubkey),
|
||||
&client.get_latest_blockhash()?,
|
||||
);
|
||||
messages.push(message);
|
||||
stake_extras.push((new_stake_account_keypair, lockup_date));
|
||||
}
|
||||
|
@ -1209,14 +1213,15 @@ mod tests {
|
|||
use solana_test_validator::TestValidator;
|
||||
use solana_transaction_status::TransactionConfirmationStatus;
|
||||
|
||||
fn one_signer_message() -> Message {
|
||||
Message::new(
|
||||
fn one_signer_message(client: &RpcClient) -> Message {
|
||||
Message::new_with_blockhash(
|
||||
&[Instruction::new_with_bytes(
|
||||
Pubkey::new_unique(),
|
||||
&[],
|
||||
vec![AccountMeta::new(Pubkey::default(), true)],
|
||||
)],
|
||||
None,
|
||||
&client.get_latest_blockhash().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1598,7 +1603,7 @@ mod tests {
|
|||
&sender_keypair_file,
|
||||
None,
|
||||
);
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args).unwrap();
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args).unwrap();
|
||||
|
||||
// Unfunded payer
|
||||
let unfunded_payer = Keypair::new();
|
||||
|
@ -1612,7 +1617,7 @@ mod tests {
|
|||
.into();
|
||||
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(
|
||||
|
@ -1651,7 +1656,7 @@ mod tests {
|
|||
.unwrap()
|
||||
.into();
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(
|
||||
|
@ -1705,7 +1710,7 @@ mod tests {
|
|||
&sender_keypair_file,
|
||||
None,
|
||||
);
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args).unwrap();
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args).unwrap();
|
||||
|
||||
// Unfunded sender
|
||||
let unfunded_payer = Keypair::new();
|
||||
|
@ -1717,7 +1722,7 @@ mod tests {
|
|||
args.fee_payer = read_keypair_file(&sender_keypair_file).unwrap().into();
|
||||
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(sources, vec![FundingSource::SystemAccount].into());
|
||||
|
@ -1733,7 +1738,7 @@ mod tests {
|
|||
.into();
|
||||
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(sources, vec![FundingSource::FeePayer].into());
|
||||
|
@ -1821,7 +1826,7 @@ mod tests {
|
|||
&sender_keypair_file,
|
||||
Some(stake_args),
|
||||
);
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args).unwrap();
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args).unwrap();
|
||||
|
||||
// Underfunded stake-account
|
||||
let expensive_allocation_amount = 5000.0;
|
||||
|
@ -1831,7 +1836,7 @@ mod tests {
|
|||
lockup_date: "".to_string(),
|
||||
}];
|
||||
let err_result = check_payer_balances(
|
||||
&[one_signer_message()],
|
||||
&[one_signer_message(&client)],
|
||||
&expensive_allocations,
|
||||
&client,
|
||||
&args,
|
||||
|
@ -1859,7 +1864,7 @@ mod tests {
|
|||
.into();
|
||||
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(
|
||||
|
@ -1898,7 +1903,7 @@ mod tests {
|
|||
.unwrap()
|
||||
.into();
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(
|
||||
|
@ -1959,7 +1964,7 @@ mod tests {
|
|||
&sender_keypair_file,
|
||||
Some(stake_args),
|
||||
);
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args).unwrap();
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args).unwrap();
|
||||
|
||||
// Unfunded sender
|
||||
let unfunded_payer = Keypair::new();
|
||||
|
@ -1971,7 +1976,7 @@ mod tests {
|
|||
args.fee_payer = read_keypair_file(&sender_keypair_file).unwrap().into();
|
||||
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(sources, vec![FundingSource::SystemAccount].into());
|
||||
|
@ -1987,7 +1992,7 @@ mod tests {
|
|||
.into();
|
||||
|
||||
let err_result =
|
||||
check_payer_balances(&[one_signer_message()], &allocations, &client, &args)
|
||||
check_payer_balances(&[one_signer_message(&client)], &allocations, &client, &args)
|
||||
.unwrap_err();
|
||||
if let Error::InsufficientFunds(sources, amount) = err_result {
|
||||
assert_eq!(sources, vec![FundingSource::FeePayer].into());
|
||||
|
|
Loading…
Reference in New Issue