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
This commit is contained in:
parent
19448ba078
commit
3b5b71ce44
|
@ -1944,9 +1944,13 @@ impl Blockstore {
|
||||||
self.block_height_cf.put(slot, &block_height)
|
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<Slot> {
|
pub fn get_first_available_block(&self) -> Result<Slot> {
|
||||||
let mut root_iterator = self.rooted_slot_iterator(self.lowest_slot())?;
|
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(
|
pub fn get_rooted_block(
|
||||||
|
@ -7361,8 +7365,6 @@ pub mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
// Purge to freeze index 0
|
|
||||||
blockstore.run_purge(0, 1, PurgeType::PrimaryIndex).unwrap();
|
|
||||||
let slot1 = 20;
|
let slot1 = 20;
|
||||||
for x in 5..9 {
|
for x in 5..9 {
|
||||||
let signature = Signature::new(&[x; 64]);
|
let signature = Signature::new(&[x; 64]);
|
||||||
|
@ -7511,8 +7513,6 @@ pub mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
// Purge to freeze index 0
|
|
||||||
blockstore.run_purge(0, 1, PurgeType::PrimaryIndex).unwrap();
|
|
||||||
for x in 7..9 {
|
for x in 7..9 {
|
||||||
let signature = Signature::new(&[x; 64]);
|
let signature = Signature::new(&[x; 64]);
|
||||||
blockstore
|
blockstore
|
||||||
|
@ -7570,6 +7570,9 @@ pub mod tests {
|
||||||
let ledger_path = get_tmp_ledger_path_auto_delete!();
|
let ledger_path = get_tmp_ledger_path_auto_delete!();
|
||||||
let blockstore = Blockstore::open(ledger_path.path()).unwrap();
|
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<Entry> {
|
fn make_slot_entries_with_transaction_addresses(addresses: &[Pubkey]) -> Vec<Entry> {
|
||||||
let mut entries: Vec<Entry> = Vec::new();
|
let mut entries: Vec<Entry> = Vec::new();
|
||||||
for address in addresses {
|
for address in addresses {
|
||||||
|
@ -7597,11 +7600,7 @@ pub mod tests {
|
||||||
let shreds = entries_to_test_shreds(&entries, slot, slot - 1, true, 0);
|
let shreds = entries_to_test_shreds(&entries, slot, slot - 1, true, 0);
|
||||||
blockstore.insert_shreds(shreds, None, false).unwrap();
|
blockstore.insert_shreds(shreds, None, false).unwrap();
|
||||||
|
|
||||||
for (i, entry) in entries.into_iter().enumerate() {
|
for entry in entries.into_iter() {
|
||||||
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 transaction in entry.transactions {
|
for transaction in entry.transactions {
|
||||||
assert_eq!(transaction.signatures.len(), 1);
|
assert_eq!(transaction.signatures.len(), 1);
|
||||||
blockstore
|
blockstore
|
||||||
|
|
|
@ -941,15 +941,20 @@ impl JsonRpcRequestProcessor {
|
||||||
result: &std::result::Result<T, BlockstoreError>,
|
result: &std::result::Result<T, BlockstoreError>,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
) -> Result<()> {
|
) -> 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 {
|
if let Err(BlockstoreError::SlotCleanedUp) = result {
|
||||||
return Err(RpcCustomError::BlockCleanedUp {
|
return Err(err);
|
||||||
slot,
|
}
|
||||||
first_available_block: self
|
if slot < first_available_block {
|
||||||
.blockstore
|
return Err(err);
|
||||||
.get_first_available_block()
|
|
||||||
.unwrap_or_default(),
|
|
||||||
}
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue