Use last_valid_block_height in services and client apps (#19163)
* Add deprecated tag to Bank::get_blockhash_last_valid_slot * Update SendTransactionService to use last_valid_block_height * Update solana-tokens to use last_valid_block_height * Remove dangling file * Update solana program to use last_valid_block_height * Update Banks crates to use last_valid_block_height
This commit is contained in:
parent
c4f2e5f88c
commit
5970083b4d
|
@ -62,7 +62,7 @@ impl BanksClient {
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, Slot)>> + '_ {
|
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, u64)>> + '_ {
|
||||||
self.inner
|
self.inner
|
||||||
.get_fees_with_commitment_and_context(ctx, commitment)
|
.get_fees_with_commitment_and_context(ctx, commitment)
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,14 @@ impl BanksClient {
|
||||||
self.inner.get_slot_with_context(ctx, commitment)
|
self.inner.get_slot_with_context(ctx, commitment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_block_height_with_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
commitment: CommitmentLevel,
|
||||||
|
) -> impl Future<Output = io::Result<Slot>> + '_ {
|
||||||
|
self.inner.get_block_height_with_context(ctx, commitment)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn process_transaction_with_commitment_and_context(
|
pub fn process_transaction_with_commitment_and_context(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
|
@ -119,7 +127,7 @@ impl BanksClient {
|
||||||
/// use them to calculate the transaction fee.
|
/// use them to calculate the transaction fee.
|
||||||
pub fn get_fees(
|
pub fn get_fees(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, Slot)>> + '_ {
|
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, u64)>> + '_ {
|
||||||
self.get_fees_with_commitment_and_context(context::current(), CommitmentLevel::default())
|
self.get_fees_with_commitment_and_context(context::current(), CommitmentLevel::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,12 +203,18 @@ impl BanksClient {
|
||||||
self.process_transactions_with_commitment(transactions, CommitmentLevel::default())
|
self.process_transactions_with_commitment(transactions, CommitmentLevel::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the most recent rooted slot height. All transactions at or below this height
|
/// Return the most recent rooted slot. All transactions at or below this slot
|
||||||
/// are said to be finalized. The cluster will not fork to a higher slot height.
|
/// are said to be finalized. The cluster will not fork to a higher slot.
|
||||||
pub fn get_root_slot(&mut self) -> impl Future<Output = io::Result<Slot>> + '_ {
|
pub fn get_root_slot(&mut self) -> impl Future<Output = io::Result<Slot>> + '_ {
|
||||||
self.get_slot_with_context(context::current(), CommitmentLevel::default())
|
self.get_slot_with_context(context::current(), CommitmentLevel::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the most recent rooted block height. All transactions at or below this height
|
||||||
|
/// are said to be finalized. The cluster will not fork to a higher block height.
|
||||||
|
pub fn get_root_block_height(&mut self) -> impl Future<Output = io::Result<Slot>> + '_ {
|
||||||
|
self.get_block_height_with_context(context::current(), CommitmentLevel::default())
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the account at the given address at the slot corresponding to the given
|
/// Return the account at the given address at the slot corresponding to the given
|
||||||
/// commitment level. If the account is not found, None is returned.
|
/// commitment level. If the account is not found, None is returned.
|
||||||
pub fn get_account_with_commitment(
|
pub fn get_account_with_commitment(
|
||||||
|
@ -386,7 +400,7 @@ mod tests {
|
||||||
Runtime::new()?.block_on(async {
|
Runtime::new()?.block_on(async {
|
||||||
let client_transport = start_local_server(bank_forks, block_commitment_cache).await;
|
let client_transport = start_local_server(bank_forks, block_commitment_cache).await;
|
||||||
let mut banks_client = start_client(client_transport).await?;
|
let mut banks_client = start_client(client_transport).await?;
|
||||||
let (_, recent_blockhash, last_valid_slot) = banks_client.get_fees().await?;
|
let (_, recent_blockhash, last_valid_block_height) = banks_client.get_fees().await?;
|
||||||
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
||||||
let signature = transaction.signatures[0];
|
let signature = transaction.signatures[0];
|
||||||
banks_client.send_transaction(transaction).await?;
|
banks_client.send_transaction(transaction).await?;
|
||||||
|
@ -394,8 +408,8 @@ mod tests {
|
||||||
let mut status = banks_client.get_transaction_status(signature).await?;
|
let mut status = banks_client.get_transaction_status(signature).await?;
|
||||||
|
|
||||||
while status.is_none() {
|
while status.is_none() {
|
||||||
let root_slot = banks_client.get_root_slot().await?;
|
let root_block_height = banks_client.get_root_block_height().await?;
|
||||||
if root_slot > last_valid_slot {
|
if root_block_height > last_valid_block_height {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sleep(Duration::from_millis(100)).await;
|
sleep(Duration::from_millis(100)).await;
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub trait Banks {
|
||||||
async fn get_transaction_status_with_context(signature: Signature)
|
async fn get_transaction_status_with_context(signature: Signature)
|
||||||
-> Option<TransactionStatus>;
|
-> Option<TransactionStatus>;
|
||||||
async fn get_slot_with_context(commitment: CommitmentLevel) -> Slot;
|
async fn get_slot_with_context(commitment: CommitmentLevel) -> Slot;
|
||||||
|
async fn get_block_height_with_context(commitment: CommitmentLevel) -> u64;
|
||||||
async fn process_transaction_with_commitment_and_context(
|
async fn process_transaction_with_commitment_and_context(
|
||||||
transaction: Transaction,
|
transaction: Transaction,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
|
|
|
@ -110,7 +110,7 @@ impl BanksServer {
|
||||||
self,
|
self,
|
||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
blockhash: &Hash,
|
blockhash: &Hash,
|
||||||
last_valid_slot: Slot,
|
last_valid_block_height: u64,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
) -> Option<transaction::Result<()>> {
|
) -> Option<transaction::Result<()>> {
|
||||||
let mut status = self
|
let mut status = self
|
||||||
|
@ -119,7 +119,7 @@ impl BanksServer {
|
||||||
while status.is_none() {
|
while status.is_none() {
|
||||||
sleep(Duration::from_millis(200)).await;
|
sleep(Duration::from_millis(200)).await;
|
||||||
let bank = self.bank(commitment);
|
let bank = self.bank(commitment);
|
||||||
if bank.slot() > last_valid_slot {
|
if bank.block_height() > last_valid_block_height {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
status = bank.get_signature_status_with_blockhash(signature, blockhash);
|
status = bank.get_signature_status_with_blockhash(signature, blockhash);
|
||||||
|
@ -145,16 +145,19 @@ fn verify_transaction(
|
||||||
impl Banks for BanksServer {
|
impl Banks for BanksServer {
|
||||||
async fn send_transaction_with_context(self, _: Context, transaction: Transaction) {
|
async fn send_transaction_with_context(self, _: Context, transaction: Transaction) {
|
||||||
let blockhash = &transaction.message.recent_blockhash;
|
let blockhash = &transaction.message.recent_blockhash;
|
||||||
let last_valid_slot = self
|
let last_valid_block_height = self
|
||||||
.bank_forks
|
.bank_forks
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.root_bank()
|
.root_bank()
|
||||||
.get_blockhash_last_valid_slot(blockhash)
|
.get_blockhash_last_valid_block_height(blockhash)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
||||||
let info =
|
let info = TransactionInfo::new(
|
||||||
TransactionInfo::new(signature, serialize(&transaction).unwrap(), last_valid_slot);
|
signature,
|
||||||
|
serialize(&transaction).unwrap(),
|
||||||
|
last_valid_block_height,
|
||||||
|
);
|
||||||
self.transaction_sender.send(info).unwrap();
|
self.transaction_sender.send(info).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,11 +165,13 @@ impl Banks for BanksServer {
|
||||||
self,
|
self,
|
||||||
_: Context,
|
_: Context,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
) -> (FeeCalculator, Hash, Slot) {
|
) -> (FeeCalculator, Hash, u64) {
|
||||||
let bank = self.bank(commitment);
|
let bank = self.bank(commitment);
|
||||||
let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator();
|
let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator();
|
||||||
let last_valid_slot = bank.get_blockhash_last_valid_slot(&blockhash).unwrap();
|
let last_valid_block_height = bank
|
||||||
(fee_calculator, blockhash, last_valid_slot)
|
.get_blockhash_last_valid_block_height(&blockhash)
|
||||||
|
.unwrap();
|
||||||
|
(fee_calculator, blockhash, last_valid_block_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_status_with_context(
|
async fn get_transaction_status_with_context(
|
||||||
|
@ -209,6 +214,10 @@ impl Banks for BanksServer {
|
||||||
self.slot(commitment)
|
self.slot(commitment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_block_height_with_context(self, _: Context, commitment: CommitmentLevel) -> u64 {
|
||||||
|
self.bank(commitment).block_height()
|
||||||
|
}
|
||||||
|
|
||||||
async fn process_transaction_with_commitment_and_context(
|
async fn process_transaction_with_commitment_and_context(
|
||||||
self,
|
self,
|
||||||
_: Context,
|
_: Context,
|
||||||
|
@ -223,18 +232,21 @@ impl Banks for BanksServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let blockhash = &transaction.message.recent_blockhash;
|
let blockhash = &transaction.message.recent_blockhash;
|
||||||
let last_valid_slot = self
|
let last_valid_block_height = self
|
||||||
.bank_forks
|
.bank_forks
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.root_bank()
|
.root_bank()
|
||||||
.get_blockhash_last_valid_slot(blockhash)
|
.get_blockhash_last_valid_block_height(blockhash)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
||||||
let info =
|
let info = TransactionInfo::new(
|
||||||
TransactionInfo::new(signature, serialize(&transaction).unwrap(), last_valid_slot);
|
signature,
|
||||||
|
serialize(&transaction).unwrap(),
|
||||||
|
last_valid_block_height,
|
||||||
|
);
|
||||||
self.transaction_sender.send(info).unwrap();
|
self.transaction_sender.send(info).unwrap();
|
||||||
self.poll_signature_status(&signature, blockhash, last_valid_slot, commitment)
|
self.poll_signature_status(&signature, blockhash, last_valid_block_height, commitment)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_metrics::{datapoint_warn, inc_new_counter_info};
|
use solana_metrics::{datapoint_warn, inc_new_counter_info};
|
||||||
use solana_runtime::{bank::Bank, bank_forks::BankForks};
|
use solana_runtime::{bank::Bank, bank_forks::BankForks};
|
||||||
use solana_sdk::{clock::Slot, signature::Signature};
|
use solana_sdk::signature::Signature;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
net::{SocketAddr, UdpSocket},
|
net::{SocketAddr, UdpSocket},
|
||||||
|
@ -24,15 +24,19 @@ pub struct SendTransactionService {
|
||||||
pub struct TransactionInfo {
|
pub struct TransactionInfo {
|
||||||
pub signature: Signature,
|
pub signature: Signature,
|
||||||
pub wire_transaction: Vec<u8>,
|
pub wire_transaction: Vec<u8>,
|
||||||
pub last_valid_slot: Slot,
|
pub last_valid_block_height: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionInfo {
|
impl TransactionInfo {
|
||||||
pub fn new(signature: Signature, wire_transaction: Vec<u8>, last_valid_slot: Slot) -> Self {
|
pub fn new(
|
||||||
|
signature: Signature,
|
||||||
|
wire_transaction: Vec<u8>,
|
||||||
|
last_valid_block_height: u64,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
signature,
|
signature,
|
||||||
wire_transaction,
|
wire_transaction,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +128,7 @@ impl SendTransactionService {
|
||||||
result.rooted += 1;
|
result.rooted += 1;
|
||||||
inc_new_counter_info!("send_transaction_service-rooted", 1);
|
inc_new_counter_info!("send_transaction_service-rooted", 1);
|
||||||
false
|
false
|
||||||
} else if transaction_info.last_valid_slot < root_bank.slot() {
|
} else if transaction_info.last_valid_block_height < root_bank.block_height() {
|
||||||
info!("Dropping expired transaction: {}", signature);
|
info!("Dropping expired transaction: {}", signature);
|
||||||
result.expired += 1;
|
result.expired += 1;
|
||||||
inc_new_counter_info!("send_transaction_service-expired", 1);
|
inc_new_counter_info!("send_transaction_service-expired", 1);
|
||||||
|
|
|
@ -23,6 +23,7 @@ use solana_client::{
|
||||||
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
|
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
|
||||||
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
|
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
|
||||||
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
||||||
|
rpc_response::Fees,
|
||||||
tpu_client::{TpuClient, TpuClientConfig},
|
tpu_client::{TpuClient, TpuClientConfig},
|
||||||
};
|
};
|
||||||
use solana_rbpf::{
|
use solana_rbpf::{
|
||||||
|
@ -35,7 +36,6 @@ use solana_sdk::{
|
||||||
account_utils::StateMut,
|
account_utils::StateMut,
|
||||||
bpf_loader, bpf_loader_deprecated,
|
bpf_loader, bpf_loader_deprecated,
|
||||||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||||
clock::Slot,
|
|
||||||
commitment_config::CommitmentConfig,
|
commitment_config::CommitmentConfig,
|
||||||
instruction::Instruction,
|
instruction::Instruction,
|
||||||
instruction::InstructionError,
|
instruction::InstructionError,
|
||||||
|
@ -1943,8 +1943,12 @@ fn send_deploy_messages(
|
||||||
if let Some(write_messages) = write_messages {
|
if let Some(write_messages) = write_messages {
|
||||||
if let Some(write_signer) = write_signer {
|
if let Some(write_signer) = write_signer {
|
||||||
trace!("Writing program data");
|
trace!("Writing program data");
|
||||||
let (blockhash, _, last_valid_slot) = rpc_client
|
let Fees {
|
||||||
.get_recent_blockhash_with_commitment(config.commitment)?
|
blockhash,
|
||||||
|
last_valid_block_height,
|
||||||
|
..
|
||||||
|
} = rpc_client
|
||||||
|
.get_fees_with_commitment(config.commitment)?
|
||||||
.value;
|
.value;
|
||||||
let mut write_transactions = vec![];
|
let mut write_transactions = vec![];
|
||||||
for message in write_messages.iter() {
|
for message in write_messages.iter() {
|
||||||
|
@ -1959,7 +1963,7 @@ fn send_deploy_messages(
|
||||||
write_transactions,
|
write_transactions,
|
||||||
&[payer_signer, write_signer],
|
&[payer_signer, write_signer],
|
||||||
config.commitment,
|
config.commitment,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
)
|
)
|
||||||
.map_err(|err| format!("Data writes to account failed: {}", err))?;
|
.map_err(|err| format!("Data writes to account failed: {}", err))?;
|
||||||
}
|
}
|
||||||
|
@ -2029,7 +2033,7 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||||
mut transactions: Vec<Transaction>,
|
mut transactions: Vec<Transaction>,
|
||||||
signer_keys: &T,
|
signer_keys: &T,
|
||||||
commitment: CommitmentConfig,
|
commitment: CommitmentConfig,
|
||||||
mut last_valid_slot: Slot,
|
mut last_valid_block_height: u64,
|
||||||
) -> Result<(), Box<dyn error::Error>> {
|
) -> Result<(), Box<dyn error::Error>> {
|
||||||
let progress_bar = new_spinner_progress_bar();
|
let progress_bar = new_spinner_progress_bar();
|
||||||
let mut send_retries = 5;
|
let mut send_retries = 5;
|
||||||
|
@ -2069,7 +2073,7 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||||
|
|
||||||
// Collect statuses for all the transactions, drop those that are confirmed
|
// Collect statuses for all the transactions, drop those that are confirmed
|
||||||
loop {
|
loop {
|
||||||
let mut slot = 0;
|
let mut block_height = 0;
|
||||||
let pending_signatures = pending_transactions.keys().cloned().collect::<Vec<_>>();
|
let pending_signatures = pending_transactions.keys().cloned().collect::<Vec<_>>();
|
||||||
for pending_signatures_chunk in
|
for pending_signatures_chunk in
|
||||||
pending_signatures.chunks(MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS)
|
pending_signatures.chunks(MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS)
|
||||||
|
@ -2094,12 +2098,12 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slot = rpc_client.get_slot()?;
|
block_height = rpc_client.get_block_height()?;
|
||||||
progress_bar.set_message(format!(
|
progress_bar.set_message(format!(
|
||||||
"[{}/{}] Transactions confirmed. Retrying in {} slots",
|
"[{}/{}] Transactions confirmed. Retrying in {} blocks",
|
||||||
num_transactions - pending_transactions.len(),
|
num_transactions - pending_transactions.len(),
|
||||||
num_transactions,
|
num_transactions,
|
||||||
last_valid_slot.saturating_sub(slot)
|
last_valid_block_height.saturating_sub(block_height)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2107,7 +2111,7 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if slot > last_valid_slot {
|
if block_height > last_valid_block_height {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2137,10 +2141,12 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||||
send_retries -= 1;
|
send_retries -= 1;
|
||||||
|
|
||||||
// Re-sign any failed transactions with a new blockhash and retry
|
// Re-sign any failed transactions with a new blockhash and retry
|
||||||
let (blockhash, _fee_calculator, new_last_valid_slot) = rpc_client
|
let Fees {
|
||||||
.get_recent_blockhash_with_commitment(commitment)?
|
blockhash,
|
||||||
.value;
|
last_valid_block_height: new_last_valid_block_height,
|
||||||
last_valid_slot = new_last_valid_slot;
|
..
|
||||||
|
} = rpc_client.get_fees_with_commitment(commitment)?.value;
|
||||||
|
last_valid_block_height = new_last_valid_block_height;
|
||||||
transactions = vec![];
|
transactions = vec![];
|
||||||
for (_, mut transaction) in pending_transactions.into_iter() {
|
for (_, mut transaction) in pending_transactions.into_iter() {
|
||||||
transaction.try_sign(signer_keys, blockhash)?;
|
transaction.try_sign(signer_keys, blockhash)?;
|
||||||
|
|
|
@ -122,10 +122,10 @@ mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
blockhash_query,
|
blockhash_query,
|
||||||
rpc_request::RpcRequest,
|
rpc_request::RpcRequest,
|
||||||
rpc_response::{Response, RpcFeeCalculator, RpcResponseContext},
|
rpc_response::{Response, RpcFeeCalculator, RpcFees, RpcResponseContext},
|
||||||
};
|
};
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use serde_json::{self, json, Value};
|
use serde_json::{self, json};
|
||||||
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
||||||
use solana_sdk::{account::Account, hash::hash, nonce, system_program};
|
use solana_sdk::{account::Account, hash::hash, nonce, system_program};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -288,10 +288,12 @@ mod tests {
|
||||||
let rpc_fee_calc = FeeCalculator::new(42);
|
let rpc_fee_calc = FeeCalculator::new(42);
|
||||||
let get_recent_blockhash_response = json!(Response {
|
let get_recent_blockhash_response = json!(Response {
|
||||||
context: RpcResponseContext { slot: 1 },
|
context: RpcResponseContext { slot: 1 },
|
||||||
value: json!((
|
value: json!(RpcFees {
|
||||||
Value::String(rpc_blockhash.to_string()),
|
blockhash: rpc_blockhash.to_string(),
|
||||||
serde_json::to_value(rpc_fee_calc.clone()).unwrap()
|
fee_calculator: rpc_fee_calc.clone(),
|
||||||
)),
|
last_valid_slot: 42,
|
||||||
|
last_valid_block_height: 42,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
let get_fee_calculator_for_blockhash_response = json!(Response {
|
let get_fee_calculator_for_blockhash_response = json!(Response {
|
||||||
context: RpcResponseContext { slot: 1 },
|
context: RpcResponseContext { slot: 1 },
|
||||||
|
@ -300,10 +302,7 @@ mod tests {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
let mut mocks = HashMap::new();
|
let mut mocks = HashMap::new();
|
||||||
mocks.insert(
|
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response.clone());
|
||||||
RpcRequest::GetRecentBlockhash,
|
|
||||||
get_recent_blockhash_response.clone(),
|
|
||||||
);
|
|
||||||
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BlockhashQuery::default()
|
BlockhashQuery::default()
|
||||||
|
@ -312,10 +311,7 @@ mod tests {
|
||||||
(rpc_blockhash, rpc_fee_calc.clone()),
|
(rpc_blockhash, rpc_fee_calc.clone()),
|
||||||
);
|
);
|
||||||
let mut mocks = HashMap::new();
|
let mut mocks = HashMap::new();
|
||||||
mocks.insert(
|
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response.clone());
|
||||||
RpcRequest::GetRecentBlockhash,
|
|
||||||
get_recent_blockhash_response.clone(),
|
|
||||||
);
|
|
||||||
mocks.insert(
|
mocks.insert(
|
||||||
RpcRequest::GetFeeCalculatorForBlockhash,
|
RpcRequest::GetFeeCalculatorForBlockhash,
|
||||||
get_fee_calculator_for_blockhash_response,
|
get_fee_calculator_for_blockhash_response,
|
||||||
|
@ -328,10 +324,7 @@ mod tests {
|
||||||
(test_blockhash, rpc_fee_calc),
|
(test_blockhash, rpc_fee_calc),
|
||||||
);
|
);
|
||||||
let mut mocks = HashMap::new();
|
let mut mocks = HashMap::new();
|
||||||
mocks.insert(
|
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response);
|
||||||
RpcRequest::GetRecentBlockhash,
|
|
||||||
get_recent_blockhash_response,
|
|
||||||
);
|
|
||||||
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BlockhashQuery::None(test_blockhash)
|
BlockhashQuery::None(test_blockhash)
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
use crate::{fee_calculator::FeeCalculator, hash::Hash};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Fees {
|
|
||||||
pub blockhash: Hash,
|
|
||||||
pub fee_calculator: FeeCalculator,
|
|
||||||
pub last_valid_block_height: u64,
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ use {
|
||||||
rpc_config::RpcBlockProductionConfig,
|
rpc_config::RpcBlockProductionConfig,
|
||||||
rpc_request::RpcRequest,
|
rpc_request::RpcRequest,
|
||||||
rpc_response::{
|
rpc_response::{
|
||||||
Response, RpcAccountBalance, RpcBlockProduction, RpcBlockProductionRange,
|
Response, RpcAccountBalance, RpcBlockProduction, RpcBlockProductionRange, RpcFees,
|
||||||
RpcResponseContext, RpcSimulateTransactionResult, RpcStakeActivation, RpcSupply,
|
RpcResponseContext, RpcSimulateTransactionResult, RpcStakeActivation, RpcSupply,
|
||||||
RpcVersionInfo, RpcVoteAccountStatus, StakeActivationState,
|
RpcVersionInfo, RpcVoteAccountStatus, StakeActivationState,
|
||||||
},
|
},
|
||||||
|
@ -123,6 +123,16 @@ impl RpcSender for MockSender {
|
||||||
context: RpcResponseContext { slot: 1 },
|
context: RpcResponseContext { slot: 1 },
|
||||||
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
|
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
|
||||||
})?,
|
})?,
|
||||||
|
"getFees" => serde_json::to_value(Response {
|
||||||
|
context: RpcResponseContext { slot: 1 },
|
||||||
|
value: serde_json::to_value(RpcFees {
|
||||||
|
blockhash: PUBKEY.to_string(),
|
||||||
|
fee_calculator: FeeCalculator::default(),
|
||||||
|
last_valid_slot: 42,
|
||||||
|
last_valid_block_height: 42,
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
})?,
|
||||||
"getSignatureStatuses" => {
|
"getSignatureStatuses" => {
|
||||||
let status: transaction::Result<()> = if self.url == "account_in_use" {
|
let status: transaction::Result<()> = if self.url == "account_in_use" {
|
||||||
Err(TransactionError::AccountInUse)
|
Err(TransactionError::AccountInUse)
|
||||||
|
|
|
@ -544,6 +544,7 @@ impl JsonRpcRequestProcessor {
|
||||||
fn get_fees(&self, commitment: Option<CommitmentConfig>) -> RpcResponse<RpcFees> {
|
fn get_fees(&self, commitment: Option<CommitmentConfig>) -> RpcResponse<RpcFees> {
|
||||||
let bank = self.bank(commitment);
|
let bank = self.bank(commitment);
|
||||||
let (blockhash, fee_calculator) = bank.confirmed_last_blockhash();
|
let (blockhash, fee_calculator) = bank.confirmed_last_blockhash();
|
||||||
|
#[allow(deprecated)]
|
||||||
let last_valid_slot = bank
|
let last_valid_slot = bank
|
||||||
.get_blockhash_last_valid_slot(&blockhash)
|
.get_blockhash_last_valid_slot(&blockhash)
|
||||||
.expect("bank blockhash queue should contain blockhash");
|
.expect("bank blockhash queue should contain blockhash");
|
||||||
|
@ -2140,7 +2141,7 @@ fn _send_transaction(
|
||||||
meta: JsonRpcRequestProcessor,
|
meta: JsonRpcRequestProcessor,
|
||||||
transaction: Transaction,
|
transaction: Transaction,
|
||||||
wire_transaction: Vec<u8>,
|
wire_transaction: Vec<u8>,
|
||||||
last_valid_slot: Slot,
|
last_valid_block_height: u64,
|
||||||
durable_nonce_info: Option<(Pubkey, Hash)>,
|
durable_nonce_info: Option<(Pubkey, Hash)>,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
if transaction.signatures.is_empty() {
|
if transaction.signatures.is_empty() {
|
||||||
|
@ -2150,7 +2151,7 @@ fn _send_transaction(
|
||||||
let transaction_info = TransactionInfo::new(
|
let transaction_info = TransactionInfo::new(
|
||||||
signature,
|
signature,
|
||||||
wire_transaction,
|
wire_transaction,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
durable_nonce_info,
|
durable_nonce_info,
|
||||||
);
|
);
|
||||||
meta.transaction_sender
|
meta.transaction_sender
|
||||||
|
@ -3233,7 +3234,9 @@ pub mod rpc_full {
|
||||||
} else {
|
} else {
|
||||||
bank.confirmed_last_blockhash().0
|
bank.confirmed_last_blockhash().0
|
||||||
};
|
};
|
||||||
let last_valid_slot = bank.get_blockhash_last_valid_slot(&blockhash).unwrap_or(0);
|
let last_valid_block_height = bank
|
||||||
|
.get_blockhash_last_valid_block_height(&blockhash)
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
let transaction =
|
let transaction =
|
||||||
request_airdrop_transaction(&faucet_addr, &pubkey, lamports, blockhash).map_err(
|
request_airdrop_transaction(&faucet_addr, &pubkey, lamports, blockhash).map_err(
|
||||||
|
@ -3248,7 +3251,13 @@ pub mod rpc_full {
|
||||||
Error::internal_error()
|
Error::internal_error()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
_send_transaction(meta, transaction, wire_transaction, last_valid_slot, None)
|
_send_transaction(
|
||||||
|
meta,
|
||||||
|
transaction,
|
||||||
|
wire_transaction,
|
||||||
|
last_valid_block_height,
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_transaction(
|
fn send_transaction(
|
||||||
|
@ -3267,8 +3276,8 @@ pub mod rpc_full {
|
||||||
.map(|commitment| CommitmentConfig { commitment });
|
.map(|commitment| CommitmentConfig { commitment });
|
||||||
let preflight_bank = &*meta.bank(preflight_commitment);
|
let preflight_bank = &*meta.bank(preflight_commitment);
|
||||||
|
|
||||||
let mut last_valid_slot = preflight_bank
|
let mut last_valid_block_height = preflight_bank
|
||||||
.get_blockhash_last_valid_slot(&transaction.message.recent_blockhash)
|
.get_blockhash_last_valid_block_height(&transaction.message.recent_blockhash)
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let durable_nonce_info = solana_sdk::transaction::uses_durable_nonce(&transaction)
|
let durable_nonce_info = solana_sdk::transaction::uses_durable_nonce(&transaction)
|
||||||
|
@ -3280,11 +3289,12 @@ pub mod rpc_full {
|
||||||
})
|
})
|
||||||
.map(|&pubkey| (pubkey, transaction.message.recent_blockhash));
|
.map(|&pubkey| (pubkey, transaction.message.recent_blockhash));
|
||||||
if durable_nonce_info.is_some() {
|
if durable_nonce_info.is_some() {
|
||||||
// While it uses a defined constant, this last_valid_slot value is chosen arbitrarily.
|
// While it uses a defined constant, this last_valid_block_height value is chosen arbitrarily.
|
||||||
// It provides a fallback timeout for durable-nonce transaction retries in case of
|
// It provides a fallback timeout for durable-nonce transaction retries in case of
|
||||||
// malicious packing of the retry queue. Durable-nonce transactions are otherwise
|
// malicious packing of the retry queue. Durable-nonce transactions are otherwise
|
||||||
// retried until the nonce is advanced.
|
// retried until the nonce is advanced.
|
||||||
last_valid_slot = preflight_bank.slot() + MAX_RECENT_BLOCKHASHES as u64;
|
last_valid_block_height =
|
||||||
|
preflight_bank.block_height() + MAX_RECENT_BLOCKHASHES as u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.skip_preflight {
|
if !config.skip_preflight {
|
||||||
|
@ -3345,7 +3355,7 @@ pub mod rpc_full {
|
||||||
meta,
|
meta,
|
||||||
transaction,
|
transaction,
|
||||||
wire_transaction,
|
wire_transaction,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
durable_nonce_info,
|
durable_nonce_info,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,7 @@ use {
|
||||||
solana_poh::poh_recorder::PohRecorder,
|
solana_poh::poh_recorder::PohRecorder,
|
||||||
solana_runtime::{bank::Bank, bank_forks::BankForks},
|
solana_runtime::{bank::Bank, bank_forks::BankForks},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, NUM_CONSECUTIVE_LEADER_SLOTS},
|
clock::NUM_CONSECUTIVE_LEADER_SLOTS, hash::Hash, nonce_account, pubkey::Pubkey,
|
||||||
hash::Hash,
|
|
||||||
nonce_account,
|
|
||||||
pubkey::Pubkey,
|
|
||||||
signature::Signature,
|
signature::Signature,
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
|
@ -34,7 +31,7 @@ pub struct SendTransactionService {
|
||||||
pub struct TransactionInfo {
|
pub struct TransactionInfo {
|
||||||
pub signature: Signature,
|
pub signature: Signature,
|
||||||
pub wire_transaction: Vec<u8>,
|
pub wire_transaction: Vec<u8>,
|
||||||
pub last_valid_slot: Slot,
|
pub last_valid_block_height: u64,
|
||||||
pub durable_nonce_info: Option<(Pubkey, Hash)>,
|
pub durable_nonce_info: Option<(Pubkey, Hash)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +39,13 @@ impl TransactionInfo {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
signature: Signature,
|
signature: Signature,
|
||||||
wire_transaction: Vec<u8>,
|
wire_transaction: Vec<u8>,
|
||||||
last_valid_slot: Slot,
|
last_valid_block_height: u64,
|
||||||
durable_nonce_info: Option<(Pubkey, Hash)>,
|
durable_nonce_info: Option<(Pubkey, Hash)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
signature,
|
signature,
|
||||||
wire_transaction,
|
wire_transaction,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
durable_nonce_info,
|
durable_nonce_info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,7 +241,7 @@ impl SendTransactionService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if transaction_info.last_valid_slot < root_bank.slot() {
|
if transaction_info.last_valid_block_height < root_bank.block_height() {
|
||||||
info!("Dropping expired transaction: {}", signature);
|
info!("Dropping expired transaction: {}", signature);
|
||||||
result.expired += 1;
|
result.expired += 1;
|
||||||
inc_new_counter_info!("send_transaction_service-expired", 1);
|
inc_new_counter_info!("send_transaction_service-expired", 1);
|
||||||
|
@ -391,7 +388,12 @@ mod test {
|
||||||
info!("Expired transactions are dropped...");
|
info!("Expired transactions are dropped...");
|
||||||
transactions.insert(
|
transactions.insert(
|
||||||
Signature::default(),
|
Signature::default(),
|
||||||
TransactionInfo::new(Signature::default(), vec![], root_bank.slot() - 1, None),
|
TransactionInfo::new(
|
||||||
|
Signature::default(),
|
||||||
|
vec![],
|
||||||
|
root_bank.block_height() - 1,
|
||||||
|
None,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
let result = SendTransactionService::process_transactions(
|
let result = SendTransactionService::process_transactions(
|
||||||
&working_bank,
|
&working_bank,
|
||||||
|
@ -414,7 +416,7 @@ mod test {
|
||||||
info!("Rooted transactions are dropped...");
|
info!("Rooted transactions are dropped...");
|
||||||
transactions.insert(
|
transactions.insert(
|
||||||
rooted_signature,
|
rooted_signature,
|
||||||
TransactionInfo::new(rooted_signature, vec![], working_bank.slot(), None),
|
TransactionInfo::new(rooted_signature, vec![], working_bank.block_height(), None),
|
||||||
);
|
);
|
||||||
let result = SendTransactionService::process_transactions(
|
let result = SendTransactionService::process_transactions(
|
||||||
&working_bank,
|
&working_bank,
|
||||||
|
@ -437,7 +439,7 @@ mod test {
|
||||||
info!("Failed transactions are dropped...");
|
info!("Failed transactions are dropped...");
|
||||||
transactions.insert(
|
transactions.insert(
|
||||||
failed_signature,
|
failed_signature,
|
||||||
TransactionInfo::new(failed_signature, vec![], working_bank.slot(), None),
|
TransactionInfo::new(failed_signature, vec![], working_bank.block_height(), None),
|
||||||
);
|
);
|
||||||
let result = SendTransactionService::process_transactions(
|
let result = SendTransactionService::process_transactions(
|
||||||
&working_bank,
|
&working_bank,
|
||||||
|
@ -460,7 +462,12 @@ mod test {
|
||||||
info!("Non-rooted transactions are kept...");
|
info!("Non-rooted transactions are kept...");
|
||||||
transactions.insert(
|
transactions.insert(
|
||||||
non_rooted_signature,
|
non_rooted_signature,
|
||||||
TransactionInfo::new(non_rooted_signature, vec![], working_bank.slot(), None),
|
TransactionInfo::new(
|
||||||
|
non_rooted_signature,
|
||||||
|
vec![],
|
||||||
|
working_bank.block_height(),
|
||||||
|
None,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
let result = SendTransactionService::process_transactions(
|
let result = SendTransactionService::process_transactions(
|
||||||
&working_bank,
|
&working_bank,
|
||||||
|
@ -484,7 +491,12 @@ mod test {
|
||||||
info!("Unknown transactions are retried...");
|
info!("Unknown transactions are retried...");
|
||||||
transactions.insert(
|
transactions.insert(
|
||||||
Signature::default(),
|
Signature::default(),
|
||||||
TransactionInfo::new(Signature::default(), vec![], working_bank.slot(), None),
|
TransactionInfo::new(
|
||||||
|
Signature::default(),
|
||||||
|
vec![],
|
||||||
|
working_bank.block_height(),
|
||||||
|
None,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
let result = SendTransactionService::process_transactions(
|
let result = SendTransactionService::process_transactions(
|
||||||
&working_bank,
|
&working_bank,
|
||||||
|
@ -542,7 +554,7 @@ mod test {
|
||||||
.transfer(2, &mint_keypair, &mint_keypair.pubkey())
|
.transfer(2, &mint_keypair, &mint_keypair.pubkey())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let last_valid_slot = working_bank.slot() + 300;
|
let last_valid_block_height = working_bank.block_height() + 300;
|
||||||
|
|
||||||
let failed_signature = {
|
let failed_signature = {
|
||||||
let blockhash = working_bank.last_blockhash();
|
let blockhash = working_bank.last_blockhash();
|
||||||
|
@ -561,7 +573,7 @@ mod test {
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
rooted_signature,
|
rooted_signature,
|
||||||
vec![],
|
vec![],
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
Some((nonce_address, durable_nonce)),
|
Some((nonce_address, durable_nonce)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -588,7 +600,7 @@ mod test {
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
rooted_signature,
|
rooted_signature,
|
||||||
vec![],
|
vec![],
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
Some((nonce_address, Hash::new_unique())),
|
Some((nonce_address, Hash::new_unique())),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -617,7 +629,7 @@ mod test {
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
Signature::default(),
|
Signature::default(),
|
||||||
vec![],
|
vec![],
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
Some((nonce_address, Hash::new_unique())),
|
Some((nonce_address, Hash::new_unique())),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -638,13 +650,13 @@ mod test {
|
||||||
..ProcessTransactionsResult::default()
|
..ProcessTransactionsResult::default()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// ... or last_valid_slot timeout has passed
|
// ... or last_valid_block_height timeout has passed
|
||||||
transactions.insert(
|
transactions.insert(
|
||||||
Signature::default(),
|
Signature::default(),
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
Signature::default(),
|
Signature::default(),
|
||||||
vec![],
|
vec![],
|
||||||
root_bank.slot() - 1,
|
root_bank.block_height() - 1,
|
||||||
Some((nonce_address, durable_nonce)),
|
Some((nonce_address, durable_nonce)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -672,7 +684,7 @@ mod test {
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
failed_signature,
|
failed_signature,
|
||||||
vec![],
|
vec![],
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
Some((nonce_address, Hash::new_unique())), // runtime should advance nonce on failed transactions
|
Some((nonce_address, Hash::new_unique())), // runtime should advance nonce on failed transactions
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -700,7 +712,7 @@ mod test {
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
non_rooted_signature,
|
non_rooted_signature,
|
||||||
vec![],
|
vec![],
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
Some((nonce_address, Hash::new_unique())), // runtime advances nonce when transaction lands
|
Some((nonce_address, Hash::new_unique())), // runtime advances nonce when transaction lands
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -729,7 +741,7 @@ mod test {
|
||||||
TransactionInfo::new(
|
TransactionInfo::new(
|
||||||
Signature::default(),
|
Signature::default(),
|
||||||
vec![],
|
vec![],
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
Some((nonce_address, durable_nonce)),
|
Some((nonce_address, durable_nonce)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2692,7 +2692,10 @@ impl Bank {
|
||||||
&self.fee_rate_governor
|
&self.fee_rate_governor
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEPRECATED
|
#[deprecated(
|
||||||
|
since = "1.6.11",
|
||||||
|
note = "Please use `get_blockhash_last_valid_block_height`"
|
||||||
|
)]
|
||||||
pub fn get_blockhash_last_valid_slot(&self, blockhash: &Hash) -> Option<Slot> {
|
pub fn get_blockhash_last_valid_slot(&self, blockhash: &Hash) -> Option<Slot> {
|
||||||
let blockhash_queue = self.blockhash_queue.read().unwrap();
|
let blockhash_queue = self.blockhash_queue.read().unwrap();
|
||||||
// This calculation will need to be updated to consider epoch boundaries if BlockhashQueue
|
// This calculation will need to be updated to consider epoch boundaries if BlockhashQueue
|
||||||
|
|
|
@ -156,6 +156,7 @@ impl SyncClient for BankClient {
|
||||||
_commitment_config: CommitmentConfig,
|
_commitment_config: CommitmentConfig,
|
||||||
) -> Result<(Hash, FeeCalculator, u64)> {
|
) -> Result<(Hash, FeeCalculator, u64)> {
|
||||||
let (blockhash, fee_calculator) = self.bank.last_blockhash_with_fee_calculator();
|
let (blockhash, fee_calculator) = self.bank.last_blockhash_with_fee_calculator();
|
||||||
|
#[allow(deprecated)]
|
||||||
let last_valid_slot = self
|
let last_valid_slot = self
|
||||||
.bank
|
.bank
|
||||||
.get_blockhash_last_valid_slot(&blockhash)
|
.get_blockhash_last_valid_slot(&blockhash)
|
||||||
|
|
|
@ -19,6 +19,7 @@ use solana_client::{
|
||||||
rpc_client::RpcClient,
|
rpc_client::RpcClient,
|
||||||
rpc_config::RpcSendTransactionConfig,
|
rpc_config::RpcSendTransactionConfig,
|
||||||
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
||||||
|
rpc_response::Fees,
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
clock::Slot,
|
clock::Slot,
|
||||||
|
@ -386,8 +387,12 @@ fn send_messages(
|
||||||
if args.dry_run {
|
if args.dry_run {
|
||||||
Ok((Transaction::new_unsigned(message), std::u64::MAX))
|
Ok((Transaction::new_unsigned(message), std::u64::MAX))
|
||||||
} else {
|
} else {
|
||||||
let (blockhash, _fee_calculator, last_valid_slot) = client
|
let Fees {
|
||||||
.get_recent_blockhash_with_commitment(CommitmentConfig::default())?
|
blockhash,
|
||||||
|
last_valid_block_height,
|
||||||
|
..
|
||||||
|
} = client
|
||||||
|
.get_fees_with_commitment(CommitmentConfig::default())?
|
||||||
.value;
|
.value;
|
||||||
let transaction = Transaction::new(&signers, message, blockhash);
|
let transaction = Transaction::new(&signers, message, blockhash);
|
||||||
let config = RpcSendTransactionConfig {
|
let config = RpcSendTransactionConfig {
|
||||||
|
@ -395,11 +400,11 @@ fn send_messages(
|
||||||
..RpcSendTransactionConfig::default()
|
..RpcSendTransactionConfig::default()
|
||||||
};
|
};
|
||||||
client.send_transaction_with_config(&transaction, config)?;
|
client.send_transaction_with_config(&transaction, config)?;
|
||||||
Ok((transaction, last_valid_slot))
|
Ok((transaction, last_valid_block_height))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
Ok((transaction, last_valid_slot)) => {
|
Ok((transaction, last_valid_block_height)) => {
|
||||||
let new_stake_account_address_option =
|
let new_stake_account_address_option =
|
||||||
args.stake_args.as_ref().map(|_| &new_stake_account_address);
|
args.stake_args.as_ref().map(|_| &new_stake_account_address);
|
||||||
db::set_transaction_info(
|
db::set_transaction_info(
|
||||||
|
@ -409,7 +414,7 @@ fn send_messages(
|
||||||
&transaction,
|
&transaction,
|
||||||
new_stake_account_address_option,
|
new_stake_account_address_option,
|
||||||
false,
|
false,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
lockup_date,
|
lockup_date,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -658,7 +663,7 @@ fn update_finalized_transactions(
|
||||||
if info.finalized_date.is_some() {
|
if info.finalized_date.is_some() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((&info.transaction, info.last_valid_slot))
|
Some((&info.transaction, info.last_valid_block_height))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -700,8 +705,8 @@ fn log_transaction_confirmations(
|
||||||
statuses: Vec<Option<TransactionStatus>>,
|
statuses: Vec<Option<TransactionStatus>>,
|
||||||
confirmations: &mut Option<usize>,
|
confirmations: &mut Option<usize>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let root_slot = client.get_slot()?;
|
let finalized_block_height = client.get_block_height()?;
|
||||||
for ((transaction, last_valid_slot), opt_transaction_status) in unconfirmed_transactions
|
for ((transaction, last_valid_block_height), opt_transaction_status) in unconfirmed_transactions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(statuses.into_iter())
|
.zip(statuses.into_iter())
|
||||||
{
|
{
|
||||||
|
@ -709,8 +714,8 @@ fn log_transaction_confirmations(
|
||||||
db,
|
db,
|
||||||
&transaction.signatures[0],
|
&transaction.signatures[0],
|
||||||
opt_transaction_status,
|
opt_transaction_status,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
root_slot,
|
finalized_block_height,
|
||||||
) {
|
) {
|
||||||
Ok(Some(confs)) => {
|
Ok(Some(confs)) => {
|
||||||
*confirmations = Some(cmp::min(confs, confirmations.unwrap_or(usize::MAX)));
|
*confirmations = Some(cmp::min(confs, confirmations.unwrap_or(usize::MAX)));
|
||||||
|
@ -1982,7 +1987,7 @@ mod tests {
|
||||||
let sender = Keypair::new();
|
let sender = Keypair::new();
|
||||||
let recipient = Pubkey::new_unique();
|
let recipient = Pubkey::new_unique();
|
||||||
let amount = sol_to_lamports(1.0);
|
let amount = sol_to_lamports(1.0);
|
||||||
let last_valid_slot = 222;
|
let last_valid_block_height = 222;
|
||||||
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
||||||
|
|
||||||
// Queue db data
|
// Queue db data
|
||||||
|
@ -1993,7 +1998,7 @@ mod tests {
|
||||||
&transaction,
|
&transaction,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -2082,7 +2087,7 @@ mod tests {
|
||||||
new_stake_account_address: None,
|
new_stake_account_address: None,
|
||||||
finalized_date: None,
|
finalized_date: None,
|
||||||
transaction,
|
transaction,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
lockup_date: None,
|
lockup_date: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -2104,7 +2109,7 @@ mod tests {
|
||||||
let sender = Keypair::new();
|
let sender = Keypair::new();
|
||||||
let recipient = Pubkey::new_unique();
|
let recipient = Pubkey::new_unique();
|
||||||
let amount = sol_to_lamports(1.0);
|
let amount = sol_to_lamports(1.0);
|
||||||
let last_valid_slot = 222;
|
let last_valid_block_height = 222;
|
||||||
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
||||||
|
|
||||||
// Queue db data
|
// Queue db data
|
||||||
|
@ -2115,7 +2120,7 @@ mod tests {
|
||||||
&transaction,
|
&transaction,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -2186,7 +2191,7 @@ mod tests {
|
||||||
new_stake_account_address: None,
|
new_stake_account_address: None,
|
||||||
finalized_date: None,
|
finalized_date: None,
|
||||||
transaction,
|
transaction,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
lockup_date: None,
|
lockup_date: None,
|
||||||
}));
|
}));
|
||||||
assert!(transaction_info.contains(&TransactionInfo {
|
assert!(transaction_info.contains(&TransactionInfo {
|
||||||
|
@ -2195,7 +2200,7 @@ mod tests {
|
||||||
new_stake_account_address: None,
|
new_stake_account_address: None,
|
||||||
finalized_date: None,
|
finalized_date: None,
|
||||||
transaction: Transaction::new_unsigned(message),
|
transaction: Transaction::new_unsigned(message),
|
||||||
last_valid_slot: std::u64::MAX,
|
last_valid_block_height: std::u64::MAX,
|
||||||
lockup_date: None,
|
lockup_date: None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -2281,7 +2286,7 @@ mod tests {
|
||||||
let sender = Keypair::new();
|
let sender = Keypair::new();
|
||||||
let recipient = Pubkey::new_unique();
|
let recipient = Pubkey::new_unique();
|
||||||
let amount = sol_to_lamports(1.0);
|
let amount = sol_to_lamports(1.0);
|
||||||
let last_valid_slot = 222;
|
let last_valid_block_height = 222;
|
||||||
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
||||||
|
|
||||||
// Queue unconfirmed transaction into db
|
// Queue unconfirmed transaction into db
|
||||||
|
@ -2292,7 +2297,7 @@ mod tests {
|
||||||
&transaction,
|
&transaction,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -2374,7 +2379,7 @@ mod tests {
|
||||||
let sender = Keypair::new();
|
let sender = Keypair::new();
|
||||||
let recipient = Pubkey::new_unique();
|
let recipient = Pubkey::new_unique();
|
||||||
let amount = sol_to_lamports(1.0);
|
let amount = sol_to_lamports(1.0);
|
||||||
let last_valid_slot = 222;
|
let last_valid_block_height = 222;
|
||||||
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
let transaction = transfer(&client, amount, &sender, &recipient).unwrap();
|
||||||
|
|
||||||
// Queue unconfirmed transaction into db
|
// Queue unconfirmed transaction into db
|
||||||
|
@ -2385,7 +2390,7 @@ mod tests {
|
||||||
&transaction,
|
&transaction,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct TransactionInfo {
|
||||||
pub new_stake_account_address: Option<Pubkey>,
|
pub new_stake_account_address: Option<Pubkey>,
|
||||||
pub finalized_date: Option<DateTime<Utc>>,
|
pub finalized_date: Option<DateTime<Utc>>,
|
||||||
pub transaction: Transaction,
|
pub transaction: Transaction,
|
||||||
pub last_valid_slot: Slot,
|
pub last_valid_block_height: Slot,
|
||||||
pub lockup_date: Option<DateTime<Utc>>,
|
pub lockup_date: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ impl Default for TransactionInfo {
|
||||||
new_stake_account_address: None,
|
new_stake_account_address: None,
|
||||||
finalized_date: None,
|
finalized_date: None,
|
||||||
transaction,
|
transaction,
|
||||||
last_valid_slot: 0,
|
last_valid_block_height: 0,
|
||||||
lockup_date: None,
|
lockup_date: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ pub fn set_transaction_info(
|
||||||
transaction: &Transaction,
|
transaction: &Transaction,
|
||||||
new_stake_account_address: Option<&Pubkey>,
|
new_stake_account_address: Option<&Pubkey>,
|
||||||
finalized: bool,
|
finalized: bool,
|
||||||
last_valid_slot: Slot,
|
last_valid_block_height: u64,
|
||||||
lockup_date: Option<DateTime<Utc>>,
|
lockup_date: Option<DateTime<Utc>>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let finalized_date = if finalized { Some(Utc::now()) } else { None };
|
let finalized_date = if finalized { Some(Utc::now()) } else { None };
|
||||||
|
@ -118,7 +118,7 @@ pub fn set_transaction_info(
|
||||||
new_stake_account_address: new_stake_account_address.cloned(),
|
new_stake_account_address: new_stake_account_address.cloned(),
|
||||||
finalized_date,
|
finalized_date,
|
||||||
transaction: transaction.clone(),
|
transaction: transaction.clone(),
|
||||||
last_valid_slot,
|
last_valid_block_height,
|
||||||
lockup_date,
|
lockup_date,
|
||||||
};
|
};
|
||||||
let signature = transaction.signatures[0];
|
let signature = transaction.signatures[0];
|
||||||
|
@ -134,11 +134,11 @@ pub fn update_finalized_transaction(
|
||||||
db: &mut PickleDb,
|
db: &mut PickleDb,
|
||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
opt_transaction_status: Option<TransactionStatus>,
|
opt_transaction_status: Option<TransactionStatus>,
|
||||||
last_valid_slot: Slot,
|
last_valid_block_height: u64,
|
||||||
root_slot: Slot,
|
finalized_block_height: u64,
|
||||||
) -> Result<Option<usize>, Error> {
|
) -> Result<Option<usize>, Error> {
|
||||||
if opt_transaction_status.is_none() {
|
if opt_transaction_status.is_none() {
|
||||||
if root_slot > last_valid_slot {
|
if finalized_block_height > last_valid_block_height {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Signature not found {} and blockhash expired. Transaction either dropped or the validator purged the transaction status.",
|
"Signature not found {} and blockhash expired. Transaction either dropped or the validator purged the transaction status.",
|
||||||
signature
|
signature
|
||||||
|
|
Loading…
Reference in New Issue