diff --git a/ledger/src/blockstore/blockstore_purge.rs b/ledger/src/blockstore/blockstore_purge.rs index 0d4ad0a911..0d171cb091 100644 --- a/ledger/src/blockstore/blockstore_purge.rs +++ b/ledger/src/blockstore/blockstore_purge.rs @@ -273,21 +273,13 @@ impl Blockstore { .cloned() .flat_map(|entry| entry.transactions) { - batch.delete::((0, transaction.signatures[0], slot))?; - batch.delete::((1, transaction.signatures[0], slot))?; - for pubkey in transaction.message.account_keys { - batch.delete::(( - 0, - pubkey, - slot, - transaction.signatures[0], - ))?; - batch.delete::(( - 1, - pubkey, - slot, - transaction.signatures[0], - ))?; + if let Some(&signature) = transaction.signatures.get(0) { + batch.delete::((0, signature, slot))?; + batch.delete::((1, signature, slot))?; + for pubkey in transaction.message.account_keys { + batch.delete::((0, pubkey, slot, signature))?; + batch.delete::((1, pubkey, slot, signature))?; + } } } } @@ -332,7 +324,15 @@ impl Blockstore { #[cfg(test)] pub mod tests { use super::*; - use crate::{blockstore::tests::make_slot_entries_with_transactions, get_tmp_ledger_path}; + use crate::{ + blockstore::tests::make_slot_entries_with_transactions, entry::next_entry_mut, + get_tmp_ledger_path, + }; + use bincode::serialize; + use solana_sdk::{ + hash::{hash, Hash}, + message::Message, + }; // check that all columns are either empty or start at `min_slot` fn test_all_empty_or_min(blockstore: &Blockstore, min_slot: Slot) { @@ -1133,4 +1133,30 @@ pub mod tests { } Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction"); } + + #[test] + fn test_purge_special_columns_exact_no_sigs() { + let blockstore_path = get_tmp_ledger_path!(); + { + let blockstore = Blockstore::open(&blockstore_path).unwrap(); + + let slot = 1; + let mut entries: Vec = vec![]; + for x in 0..5 { + let mut tx = Transaction::new_unsigned(Message::default()); + tx.signatures = vec![]; + entries.push(next_entry_mut(&mut Hash::default(), 0, vec![tx])); + let mut tick = create_ticks(1, 0, hash(&serialize(&x).unwrap())); + entries.append(&mut tick); + } + let shreds = entries_to_test_shreds(entries, slot, slot - 1, true, 0); + blockstore.insert_shreds(shreds, None, false).unwrap(); + + let mut write_batch = blockstore.db.batch().unwrap(); + blockstore + .purge_special_columns_exact(&mut write_batch, slot, slot + 1) + .unwrap(); + } + Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction"); + } }