From d697aab0dc3602ee8da43b8399b68d2c46d05f48 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Thu, 6 Aug 2020 16:21:46 -0600 Subject: [PATCH 1/2] Fix blockstore empty panic (#11423) * Add panicking test * Add failing test: fresh transaction-status column shouldn't point at valid root 0 * Prevent transaction status match outside of primary-index bounds * Initialize transaction-status and address-signature primer entries with Slot::MAX * Revert "Add failing test: fresh transaction-status column shouldn't point at valid root 0" This reverts commit cbad2a9fae22e5531e3b4ff1b0a9d6a223826c71. * Revert "Initialize transaction-status and address-signature primer entries with Slot::MAX" This reverts commit ffaeac0669d0cbe18dd68b5ce177e15a92360b72. (cherry picked from commit 1061b5066561b84e47ae28b915b70ca5d567f9cb) # Conflicts: # ledger/src/blockstore.rs --- ledger/src/blockstore.rs | 24 ++++++++++++++++++++++-- ledger/src/blockstore_db.rs | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 7bb40e74823ad3..19e1937dbb9274 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -1797,9 +1797,9 @@ impl Blockstore { (transaction_status_cf_primary_index, signature, 0), IteratorDirection::Forward, ))?; - for ((_, sig, slot), data) in index_iterator { + for ((i, sig, slot), data) in index_iterator { counter += 1; - if sig != signature { + if i != transaction_status_cf_primary_index || sig != signature { break; } if self.is_root(slot) { @@ -1834,9 +1834,16 @@ impl Blockstore { "blockstore-rpc-api", ("method", "get_confirmed_transaction".to_string(), String) ); +<<<<<<< HEAD if let Some((slot, status)) = self.get_transaction_status(signature.clone())? { let transaction = self.find_transaction_in_slot(slot, signature)? .expect("Transaction to exist in slot entries if it exists in statuses and hasn't been cleaned up"); +======= + if let Some((slot, status)) = self.get_transaction_status(signature)? { + let transaction = self + .find_transaction_in_slot(slot, signature)? + .ok_or(BlockstoreError::TransactionStatusSlotMismatch)?; // Should not happen +>>>>>>> 1061b5066... Fix blockstore empty panic (#11423) let encoding = encoding.unwrap_or(UiTransactionEncoding::Json); let encoded_transaction = EncodedTransaction::encode(transaction, encoding); Ok(Some(ConfirmedTransaction { @@ -6059,6 +6066,19 @@ pub mod tests { } } + #[test] + fn test_empty_transaction_status() { + let blockstore_path = get_tmp_ledger_path!(); + let blockstore = Blockstore::open(&blockstore_path).unwrap(); + blockstore.set_roots(&[0]).unwrap(); + assert_eq!( + blockstore + .get_confirmed_transaction(Signature::default(), None) + .unwrap(), + None + ); + } + #[test] fn test_get_confirmed_signatures_for_address() { let blockstore_path = get_tmp_ledger_path!(); diff --git a/ledger/src/blockstore_db.rs b/ledger/src/blockstore_db.rs index 52766386c26f2b..bd3d1c0070cba6 100644 --- a/ledger/src/blockstore_db.rs +++ b/ledger/src/blockstore_db.rs @@ -57,6 +57,7 @@ pub enum BlockstoreError { SlotCleanedUp, UnpackError(#[from] UnpackError), UnableToSetOpenFileDescriptorLimit, + TransactionStatusSlotMismatch, } pub type Result = std::result::Result; From b3c8ebf3a7b58dcb5dcb1fbd18068be1e1710096 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Thu, 6 Aug 2020 17:51:45 -0600 Subject: [PATCH 2/2] Fix conflict --- ledger/src/blockstore.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 19e1937dbb9274..95b8452586952e 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -1834,16 +1834,10 @@ impl Blockstore { "blockstore-rpc-api", ("method", "get_confirmed_transaction".to_string(), String) ); -<<<<<<< HEAD if let Some((slot, status)) = self.get_transaction_status(signature.clone())? { - let transaction = self.find_transaction_in_slot(slot, signature)? - .expect("Transaction to exist in slot entries if it exists in statuses and hasn't been cleaned up"); -======= - if let Some((slot, status)) = self.get_transaction_status(signature)? { let transaction = self .find_transaction_in_slot(slot, signature)? .ok_or(BlockstoreError::TransactionStatusSlotMismatch)?; // Should not happen ->>>>>>> 1061b5066... Fix blockstore empty panic (#11423) let encoding = encoding.unwrap_or(UiTransactionEncoding::Json); let encoded_transaction = EncodedTransaction::encode(transaction, encoding); Ok(Some(ConfirmedTransaction {