diff --git a/core/src/rpc.rs b/core/src/rpc.rs
index d1d689d423..eff5f162d2 100644
--- a/core/src/rpc.rs
+++ b/core/src/rpc.rs
@@ -1025,7 +1025,7 @@ impl JsonRpcRequestProcessor {
Some(status)
} else if self.config.enable_rpc_transaction_history && search_transaction_history {
self.blockstore
- .get_transaction_status(signature, true)
+ .get_rooted_transaction_status(signature)
.map_err(|_| Error::internal_error())?
.filter(|(slot, _status_meta)| {
slot <= &self
@@ -1112,20 +1112,22 @@ impl JsonRpcRequestProcessor {
check_is_at_least_confirmed(commitment)?;
if self.config.enable_rpc_transaction_history {
- match self
- .blockstore
- .get_complete_transaction(signature)
- .unwrap_or(None)
- {
+ let confirmed_bank = self.bank(Some(CommitmentConfig::confirmed()));
+ let transaction = if commitment.is_confirmed() {
+ let highest_confirmed_slot = confirmed_bank.slot();
+ self.blockstore
+ .get_complete_transaction(signature, highest_confirmed_slot)
+ } else {
+ self.blockstore.get_rooted_transaction(signature)
+ };
+ match transaction.unwrap_or(None) {
Some(confirmed_transaction) => {
- if commitment.is_confirmed() {
- let confirmed_bank = self.bank(Some(CommitmentConfig::confirmed()));
- if confirmed_bank
+ if commitment.is_confirmed()
+ && confirmed_bank // should be redundant
.status_cache_ancestors()
.contains(&confirmed_transaction.slot)
- {
- return Ok(Some(confirmed_transaction.encode(encoding)));
- }
+ {
+ return Ok(Some(confirmed_transaction.encode(encoding)));
}
if confirmed_transaction.slot
<= self
diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs
index 383af1fb96..528343e25f 100644
--- a/ledger/src/blockstore.rs
+++ b/ledger/src/blockstore.rs
@@ -1,8 +1,8 @@
//! The `blockstore` module provides functions for parallel verification of the
//! Proof of History ledger as well as iterative read, append write, and random
//! access read to a persistent file-based ledger.
-pub use crate::{blockstore_db::BlockstoreError, blockstore_meta::SlotMeta};
use crate::{
+ ancestor_iterator::AncestorIterator,
blockstore_db::{
columns as cf, AccessType, BlockstoreRecoveryMode, Column, Database, IteratorDirection,
IteratorMode, LedgerColumn, Result, WriteBatch,
@@ -14,6 +14,7 @@ use crate::{
next_slots_iterator::NextSlotsIterator,
shred::{Result as ShredResult, Shred, Shredder},
};
+pub use crate::{blockstore_db::BlockstoreError, blockstore_meta::SlotMeta};
use bincode::deserialize;
use log::*;
use rayon::{
@@ -1973,7 +1974,7 @@ impl Blockstore {
fn get_transaction_status_with_counter(
&self,
signature: Signature,
- require_root: bool,
+ confirmed_unrooted_slots: &[Slot],
) -> Result<(Option<(Slot, TransactionStatusMeta)>, u64)> {
let mut counter = 0;
for transaction_status_cf_primary_index in 0..=1 {
@@ -1986,7 +1987,7 @@ impl Blockstore {
if i != transaction_status_cf_primary_index || sig != signature {
break;
}
- if require_root && !self.is_root(slot) || self.meta(slot)?.is_none() {
+ if !self.is_root(slot) && !confirmed_unrooted_slots.contains(&slot) {
continue;
}
let status = self
@@ -2000,50 +2001,73 @@ impl Blockstore {
Ok((None, counter))
}
+ /// Returns a transaction status
+ pub fn get_rooted_transaction_status(
+ &self,
+ signature: Signature,
+ ) -> Result