More reliable way to detect expired transactions (#10482)

When the root slot is beyond the last valid slot, we can say
with certainty that the blockhash is expired. Unfortunately,
we still can't say the transaction didn't land. It may have
landed a long time ago and the validator has since purged
its transaction status.
This commit is contained in:
Greg Fitzgerald
2020-06-10 17:00:13 -06:00
committed by GitHub
parent 1e3554b33d
commit 9c2c64f8c8
3 changed files with 43 additions and 57 deletions

View File

@@ -12,10 +12,6 @@ use solana_sdk::{
signature::{Signature, Signer},
signers::Signers,
system_instruction,
sysvar::{
recent_blockhashes::{self, RecentBlockhashes},
Sysvar,
},
transaction::Transaction,
transport::{Result, TransportError},
};
@@ -29,6 +25,7 @@ pub trait Client {
) -> Result<Vec<Option<TransactionStatus>>>;
fn get_balance1(&self, pubkey: &Pubkey) -> Result<u64>;
fn get_fees1(&self) -> Result<(Hash, FeeCalculator, Slot)>;
fn get_slot1(&self) -> Result<Slot>;
fn get_account1(&self, pubkey: &Pubkey) -> Result<Option<Account>>;
}
@@ -64,6 +61,11 @@ impl Client for RpcClient {
Ok(result.value)
}
fn get_slot1(&self) -> Result<Slot> {
self.get_slot()
.map_err(|e| TransportError::Custom(e.to_string()))
}
fn get_account1(&self, pubkey: &Pubkey) -> Result<Option<Account>> {
self.get_account(pubkey)
.map(Some)
@@ -103,6 +105,10 @@ impl Client for BankClient {
self.get_recent_blockhash_with_commitment(CommitmentConfig::default())
}
fn get_slot1(&self) -> Result<Slot> {
self.get_slot()
}
fn get_account1(&self, pubkey: &Pubkey) -> Result<Option<Account>> {
self.get_account(pubkey)
}
@@ -170,6 +176,10 @@ impl<C: Client> ThinClient<C> {
self.client.get_fees1()
}
pub fn get_slot(&self) -> Result<Slot> {
self.client.get_slot1()
}
pub fn get_balance(&self, pubkey: &Pubkey) -> Result<u64> {
self.client.get_balance1(pubkey)
}
@@ -177,12 +187,4 @@ impl<C: Client> ThinClient<C> {
pub fn get_account(&self, pubkey: &Pubkey) -> Result<Option<Account>> {
self.client.get_account1(pubkey)
}
pub fn get_recent_blockhashes(&self) -> Result<Vec<Hash>> {
let opt_blockhashes_account = self.get_account(&recent_blockhashes::id())?;
let blockhashes_account = opt_blockhashes_account.unwrap();
let recent_blockhashes = RecentBlockhashes::from_account(&blockhashes_account).unwrap();
let hashes = recent_blockhashes.iter().map(|x| x.blockhash).collect();
Ok(hashes)
}
}