From 3b5b71ce44038ca7e039378fa1421d1275139ef2 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Mon, 28 Feb 2022 23:57:41 -0700 Subject: [PATCH] Improve UX querying rpc for blocks at or before the snapshot from boot (#23403) * Bump first-available block to first complete block * Remove obsolete purges in tests (PrimaryIndex toggling no longer in use * Check first-available block in Rpc check_slot_cleaned_up --- ledger/src/blockstore.rs | 19 +++++++++---------- rpc/src/rpc.rs | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 88700eeaa26041..5cdc4f629f1702 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -1944,9 +1944,13 @@ impl Blockstore { self.block_height_cf.put(slot, &block_height) } + /// The first complete block that is available in the Blockstore ledger pub fn get_first_available_block(&self) -> Result { let mut root_iterator = self.rooted_slot_iterator(self.lowest_slot())?; - Ok(root_iterator.next().unwrap_or_default()) + // The block at root-index 0 cannot be complete, because it is missing its parent + // blockhash. A parent blockhash must be calculated from the entries of the previous block. + // Therefore, the first available complete block is that at root-index 1. + Ok(root_iterator.nth(1).unwrap_or_default()) } pub fn get_rooted_block( @@ -7361,8 +7365,6 @@ pub mod tests { ) .unwrap(); } - // Purge to freeze index 0 - blockstore.run_purge(0, 1, PurgeType::PrimaryIndex).unwrap(); let slot1 = 20; for x in 5..9 { let signature = Signature::new(&[x; 64]); @@ -7511,8 +7513,6 @@ pub mod tests { ) .unwrap(); } - // Purge to freeze index 0 - blockstore.run_purge(0, 1, PurgeType::PrimaryIndex).unwrap(); for x in 7..9 { let signature = Signature::new(&[x; 64]); blockstore @@ -7570,6 +7570,9 @@ pub mod tests { let ledger_path = get_tmp_ledger_path_auto_delete!(); let blockstore = Blockstore::open(ledger_path.path()).unwrap(); + let (shreds, _) = make_slot_entries(1, 0, 4); + blockstore.insert_shreds(shreds, None, false).unwrap(); + fn make_slot_entries_with_transaction_addresses(addresses: &[Pubkey]) -> Vec { let mut entries: Vec = Vec::new(); for address in addresses { @@ -7597,11 +7600,7 @@ pub mod tests { let shreds = entries_to_test_shreds(&entries, slot, slot - 1, true, 0); blockstore.insert_shreds(shreds, None, false).unwrap(); - for (i, entry) in entries.into_iter().enumerate() { - if slot == 4 && i == 2 { - // Purge to freeze index 0 and write address-signatures in new primary index - blockstore.run_purge(0, 1, PurgeType::PrimaryIndex).unwrap(); - } + for entry in entries.into_iter() { for transaction in entry.transactions { assert_eq!(transaction.signatures.len(), 1); blockstore diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index b29e24c9f5af32..8a06896a02132e 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -941,15 +941,20 @@ impl JsonRpcRequestProcessor { result: &std::result::Result, slot: Slot, ) -> Result<()> { + let first_available_block = self + .blockstore + .get_first_available_block() + .unwrap_or_default(); + let err: Error = RpcCustomError::BlockCleanedUp { + slot, + first_available_block, + } + .into(); if let Err(BlockstoreError::SlotCleanedUp) = result { - return Err(RpcCustomError::BlockCleanedUp { - slot, - first_available_block: self - .blockstore - .get_first_available_block() - .unwrap_or_default(), - } - .into()); + return Err(err); + } + if slot < first_available_block { + return Err(err); } Ok(()) }