Skip to content

Commit

Permalink
test writing without merklization or diffs
Browse files Browse the repository at this point in the history
  • Loading branch information
brentstone committed Jan 11, 2024
1 parent 1ca9029 commit 5a6c6f8
Show file tree
Hide file tree
Showing 4 changed files with 391 additions and 2 deletions.
183 changes: 181 additions & 2 deletions apps/src/lib/node/ledger/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ fn new_blake2b() -> Blake2b {
mod tests {
use std::collections::HashMap;

use borsh::BorshDeserialize;
use itertools::Itertools;
use namada::core::ledger::masp_conversions::update_allowed_conversions;
use namada::eth_bridge::storage::proof::BridgePoolRootProof;
Expand All @@ -61,8 +62,8 @@ mod tests {
use namada::ledger::ibc::storage::ibc_key;
use namada::ledger::parameters::{EpochDuration, Parameters};
use namada::ledger::storage::write_log::WriteLog;
use namada::ledger::storage::{types, StoreType, WlStorage};
use namada::ledger::storage_api::{self, StorageWrite};
use namada::ledger::storage::{types, StoreType, WlStorage, DB};
use namada::ledger::storage_api::{self, StorageRead, StorageWrite};
use namada::types::chain::ChainId;
use namada::types::ethereum_events::Uint;
use namada::types::hash::Hash;
Expand Down Expand Up @@ -784,4 +785,182 @@ mod tests {
.map(Result::unwrap);
itertools::assert_equal(iter, expected);
}

#[test]
fn test_persistent_storage_writing_without_merklizing_or_diffs() {
let db_path =
TempDir::new().expect("Unable to create a temporary DB directory");
let storage = PersistentStorage::open(
db_path.path(),
ChainId::default(),
address::nam(),
None,
None,
);
let mut wls = WlStorage {
storage,
write_log: Default::default(),
};

let key1 = Key::parse("testing1").unwrap();
let val1 = 1u64;
let key2 = Key::parse("testing2").unwrap();
let val2 = 2u64;

// Standard write of key-val-1
wls.write(&key1, val1).unwrap();

// Read from WlStorage should return val1
let res = wls.read::<u64>(&key1).unwrap().unwrap();
assert_eq!(res, val1);

// Read from Storage shouldn't return val1 bc the block hasn't been
// committed
let (res, _) = wls.storage.read(&key1).unwrap();
assert!(res.is_none());

// Write key-val-2 without merklizing or diffs
wls.write_without_merkldiffs(&key2, val2).unwrap();

// Read from WlStorage should return val2
let res = wls.read::<u64>(&key2).unwrap().unwrap();
assert_eq!(res, val2);

// Commit block and storage changes
wls.commit_block().unwrap();
wls.storage.block.height = wls.storage.block.height.next_height();

// Read key1 from Storage should return val1 (also implies it is
// merklized)
let (res1, _) = wls.storage.read(&key1).unwrap();
let res1 = u64::try_from_slice(&res1.unwrap()).unwrap();
assert_eq!(res1, 1);

// Check merkle tree inclusion of key-val-1 explicitly
let is_merklized1 = wls.storage.block.tree.has_key(&key1).unwrap();
assert!(is_merklized1);

// Read key2 from Storage - should actually fail because `Storage::read`
// checks that the key is in merkle tree first
let (res2, _) = wls.storage.read(&key2).unwrap();
assert!(res2.is_none());

// But key2 should actually be in storage. Confirm by reading from
// WlStorage and also by reading Storage subspace directly
let res2 = wls.read::<u64>(&key2).unwrap().unwrap();
assert_eq!(res2, val2);
let res2 = wls.storage.db.read_subspace_val(&key2).unwrap().unwrap();
let res2 = u64::try_from_slice(&res2).unwrap();
assert_eq!(res2, 2);

// Check explicitly that key-val-2 is not in merkle tree
let is_merklized2 = wls.storage.block.tree.has_key(&key2).unwrap();
assert!(!is_merklized2);

// Check that the proper diffs exist for key-val-1
let res1 = wls
.storage
.db
.read_diffs_val(&key1, Default::default(), true)
.unwrap();
assert!(res1.is_none());

let res1 = wls
.storage
.db
.read_diffs_val(&key1, Default::default(), false)
.unwrap()
.unwrap();
let res1 = u64::try_from_slice(&res1).unwrap();
assert_eq!(res1, val1);

// Check that there are no diffs for key-val-2
let res2 = wls
.storage
.db
.read_diffs_val(&key2, Default::default(), true)
.unwrap();
assert!(res2.is_none());
let res2 = wls
.storage
.db
.read_diffs_val(&key2, Default::default(), false)
.unwrap();
assert!(res2.is_none());

// Delete the data then commit the block
wls.delete(&key1).unwrap();
wls.delete(&key2).unwrap();
wls.commit_block().unwrap();

// Check the key-vals are removed from the storage subspace
let res1 = wls.read::<u64>(&key1).unwrap();
let res2 = wls.read::<u64>(&key2).unwrap();
assert!(res1.is_none() && res2.is_none());

// Check that the key-vals don't exist in the merkle tree anymore
let is_merklized1 = wls.storage.block.tree.has_key(&key1).unwrap();
let is_merklized2 = wls.storage.block.tree.has_key(&key1).unwrap();
assert!(!is_merklized1 && !is_merklized2);

// Check that key-val-1 diffs are properly updated for blocks 0 and 1
let res1 = wls
.storage
.db
.read_diffs_val(&key1, Default::default(), true)
.unwrap();
assert!(res1.is_none());

let res1 = wls
.storage
.db
.read_diffs_val(&key1, Default::default(), false)
.unwrap()
.unwrap();
let res1 = u64::try_from_slice(&res1).unwrap();
assert_eq!(res1, val1);

let res1 = wls
.storage
.db
.read_diffs_val(&key1, BlockHeight(1), true)
.unwrap()
.unwrap();
let res1 = u64::try_from_slice(&res1).unwrap();
assert_eq!(res1, val1);

let res1 = wls
.storage
.db
.read_diffs_val(&key1, BlockHeight(1), false)
.unwrap();
assert!(res1.is_none());

// Check that key-val-2 diffs don't exist
let res2 = wls
.storage
.db
.read_diffs_val(&key2, BlockHeight(0), true)
.unwrap();
assert!(res2.is_none());
let res2 = wls
.storage
.db
.read_diffs_val(&key2, BlockHeight(0), false)
.unwrap();
assert!(res2.is_none());

let res2 = wls
.storage
.db
.read_diffs_val(&key2, BlockHeight(1), true)
.unwrap();
assert!(res2.is_none());
let res2 = wls
.storage
.db
.read_diffs_val(&key2, BlockHeight(1), false)
.unwrap();
assert!(res2.is_none());
}
}
18 changes: 18 additions & 0 deletions apps/src/lib/node/ledger/storage/rocksdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,24 @@ impl DB for RocksDB {
Ok(false)
}

fn read_diffs_val(
&self,
key: &Key,
height: BlockHeight,
is_old: bool,
) -> Result<Option<Vec<u8>>> {
let diffs_cf = self.get_column_family(DIFFS_CF)?;
let old_new_seg = if is_old { "old" } else { "new" };
let prefix = Key::from(height.to_db_key())
.push(&old_new_seg.to_string().to_db_key())
.unwrap()
.join(key);

self.0
.get_cf(diffs_cf, dbg!(prefix.to_string()))
.map_err(|e| Error::DBError(e.into_string()))
}

fn read_subspace_val(&self, key: &Key) -> Result<Option<Vec<u8>>> {
let subspace_cf = self.get_column_family(SUBSPACE_CF)?;
self.0
Expand Down
16 changes: 16 additions & 0 deletions core/src/ledger/storage/mockdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,22 @@ impl DB for MockDB {
Ok(false)
}

fn read_diffs_val(
&self,
key: &Key,
height: BlockHeight,
is_old: bool,
) -> Result<Option<Vec<u8>>> {
let old_new_seg = if is_old { "old" } else { "new" };

let prefix = Key::from(height.to_db_key())
.push(&old_new_seg.to_string().to_db_key())
.map_err(Error::KeyError)?
.join(key);

Ok(self.0.borrow().get(&prefix.to_string()).cloned())
}

fn read_subspace_val(&self, key: &Key) -> Result<Option<Vec<u8>>> {
let key = Key::parse("subspace").map_err(Error::KeyError)?.join(key);
Ok(self.0.borrow().get(&key.to_string()).cloned())
Expand Down
Loading

0 comments on commit 5a6c6f8

Please sign in to comment.