Skip to content

Commit a8559f4

Browse files
authored
Feature/delete datastore entries tu 2 (#4806)
* Improve unit test for delete_datastore_entries * Cargo clippy fixes * Use end_prefix in get_entire_datastore_raw
1 parent 4719402 commit a8559f4

File tree

1 file changed

+65
-12
lines changed

1 file changed

+65
-12
lines changed

Diff for: massa-ledger-worker/src/ledger_db.rs

+65-12
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,6 @@ fn delete_datastore_entries(
475475
) {
476476
// datastore
477477
let key_prefix = datastore_prefix_from_address(addr, &[]);
478-
479478
for (serialized_key, _) in db
480479
.iterator_cf(
481480
STATE_CF,
@@ -524,6 +523,30 @@ impl LedgerDB {
524523
addresses
525524
}
526525

526+
/// Get the entire datastore for a given address (no deserialization)
527+
///
528+
/// IMPORTANT: This should only be used for debug purposes.
529+
#[allow(dead_code)]
530+
#[cfg(any(test, feature = "test-exports"))]
531+
pub fn get_entire_datastore_raw(
532+
&self,
533+
addr: &Address,
534+
) -> std::collections::BTreeMap<Vec<u8>, Vec<u8>> {
535+
let db = self.db.read();
536+
537+
let key_prefix = datastore_prefix_from_address(addr, &[]);
538+
// Need an end_prefix otherwise the iterator can return entries not belonging to the given
539+
// address
540+
let end_prefix = key_prefix[0..key_prefix.len() - 1].to_vec();
541+
542+
db.iterator_cf(
543+
STATE_CF,
544+
MassaIteratorMode::From(&key_prefix, MassaDirection::Forward),
545+
)
546+
.take_while(|(k, _)| k.starts_with(&end_prefix))
547+
.collect()
548+
}
549+
527550
/// Get the entire datastore for a given address.
528551
///
529552
/// IMPORTANT: This should only be used for debug purposes.
@@ -591,13 +614,13 @@ mod tests {
591614
use std::sync::Arc;
592615
use tempfile::TempDir;
593616

594-
fn init_test_ledger(addr: Address) -> (LedgerDB, BTreeMap<Vec<u8>, Vec<u8>>) {
617+
fn setup_test_ledger(addr: Address) -> (LedgerDB, DBBatch, BTreeMap<Vec<u8>, Vec<u8>>) {
595618
// init data
596619

597620
let mut data = BTreeMap::new();
598-
data.insert(b"1".to_vec(), b"a".to_vec());
599621
data.insert(b"2".to_vec(), b"b".to_vec());
600622
data.insert(b"3".to_vec(), b"c".to_vec());
623+
601624
let entry = LedgerEntry {
602625
balance: Amount::from_str("42").unwrap(),
603626
datastore: data.clone(),
@@ -630,20 +653,25 @@ mod tests {
630653

631654
ledger_db.put_entry(&addr, entry, &mut batch);
632655
ledger_db.update_entry(&addr, entry_update, &mut batch);
633-
ledger_db
634-
.db
635-
.write()
636-
.write_batch(batch, Default::default(), None);
656+
// ledger_db
657+
// .db
658+
// .write()
659+
// .write_batch(batch, Default::default(), None);
637660

638661
// return db and initial data
639-
(ledger_db, data)
662+
// (ledger_db, data)
663+
(ledger_db, batch, data)
640664
}
641665

642666
/// Functional test of `LedgerDB`
643667
#[test]
644668
fn test_ledger_db() {
645669
let addr = Address::from_public_key(&KeyPair::generate(0).unwrap().get_public_key());
646-
let (ledger_db, data) = init_test_ledger(addr);
670+
let (ledger_db, batch, data) = setup_test_ledger(addr);
671+
ledger_db
672+
.db
673+
.write()
674+
.write_batch(batch, Default::default(), None);
647675

648676
let amount_deserializer =
649677
AmountDeserializer::new(Included(Amount::MIN), Included(Amount::MAX));
@@ -702,7 +730,31 @@ mod tests {
702730
fn test_ledger_delete() {
703731
let keypair = KeyPair::generate(0).unwrap();
704732
let addr = Address::from_public_key(&keypair.get_public_key());
705-
let (ledger_db, _data) = init_test_ledger(addr);
733+
let (ledger_db, mut batch, _data) = setup_test_ledger(addr);
734+
735+
// Add a key, value into db with a prefix right after datastore (datastore indent = 3, here we use indent = 4)
736+
// This is to test if delete_datastore_entries only delete datastore entries
737+
let mut datastore_key = vec![];
738+
ledger_db
739+
.key_serializer_db
740+
.serialize(
741+
&Key::new(&addr, KeyType::DATASTORE(b"a".to_vec())),
742+
&mut datastore_key,
743+
)
744+
.expect(KEY_SER_ERROR);
745+
let datastore_key_len = datastore_key.len();
746+
// We modify the datastore key indent (from 3 to 4) so this is not a 'datastore' key anymore
747+
datastore_key[datastore_key_len - 2] = DATASTORE_IDENT + 1;
748+
// Value is not important here
749+
let datastore_value = b"a".to_vec();
750+
batch.insert(datastore_key.clone(), Some(datastore_value.clone()));
751+
//
752+
753+
// Write batch into db
754+
ledger_db
755+
.db
756+
.write()
757+
.write_batch(batch, Default::default(), None);
706758

707759
let datastore = ledger_db.get_entire_datastore(&addr);
708760
// println!("datastore: {:?}", datastore);
@@ -717,8 +769,9 @@ mod tests {
717769
guard.write_batch(batch, Default::default(), None);
718770
drop(guard);
719771

720-
let datastore = ledger_db.get_entire_datastore(&addr);
772+
let datastore = ledger_db.get_entire_datastore_raw(&addr);
721773
// println!("datastore: {:?}", datastore);
722-
assert!(datastore.is_empty());
774+
assert_eq!(datastore.len(), 1);
775+
assert!(datastore.contains_key(&datastore_key));
723776
}
724777
}

0 commit comments

Comments
 (0)