Skip to content

Commit

Permalink
Make compatible with previous borsh format
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-near committed Nov 2, 2023
1 parent 191a249 commit bc2d7f7
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 10 deletions.
109 changes: 101 additions & 8 deletions core/store/src/trie/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,38 @@ pub struct TrieRefcountSubtraction {
/// Hash of trie_node_or_value and part of the DB key.
/// Used for uniting with shard id to get actual DB key.
trie_node_or_value_hash: CryptoHash,
/// Obsolete field but which we cannot remove because this data is persisted
/// to the database.
_ignored: IgnoredVecU8,
/// Reference count difference which will be subtracted to the total refcount.
rc: std::num::NonZeroU32,
}

#[derive(Default, BorshSerialize, BorshDeserialize, Clone, Debug)]
struct IgnoredVecU8 {
_ignored: Vec<u8>,
}

impl PartialEq for IgnoredVecU8 {
fn eq(&self, _other: &Self) -> bool {
true
}
}
impl Eq for IgnoredVecU8 {}
impl Hash for IgnoredVecU8 {
fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {}
}
impl PartialOrd for IgnoredVecU8 {
fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
Some(std::cmp::Ordering::Equal)
}
}
impl Ord for IgnoredVecU8 {
fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
std::cmp::Ordering::Equal
}
}

impl TrieRefcountAddition {
pub fn hash(&self) -> &CryptoHash {
&self.trie_node_or_value_hash
Expand All @@ -397,10 +425,13 @@ impl TrieRefcountAddition {
}

pub fn revert(&self) -> TrieRefcountSubtraction {
TrieRefcountSubtraction {
trie_node_or_value_hash: self.trie_node_or_value_hash,
rc: self.rc,
}
TrieRefcountSubtraction::new(self.trie_node_or_value_hash, self.rc)
}
}

impl TrieRefcountSubtraction {
pub fn new(trie_node_or_value_hash: CryptoHash, rc: std::num::NonZeroU32) -> Self {
Self { trie_node_or_value_hash, _ignored: Default::default(), rc }
}
}

Expand Down Expand Up @@ -437,10 +468,10 @@ impl TrieRefcountDeltaMap {
rc: std::num::NonZeroU32::new(rc as u32).unwrap(),
});
} else if rc < 0 {
deletions.push(TrieRefcountSubtraction {
trie_node_or_value_hash: hash,
rc: std::num::NonZeroU32::new((-rc) as u32).unwrap(),
});
deletions.push(TrieRefcountSubtraction::new(
hash,
std::num::NonZeroU32::new((-rc) as u32).unwrap(),
));
}
}
// Sort so that trie changes have unique representation.
Expand Down Expand Up @@ -1750,3 +1781,65 @@ mod tests {
assert_eq!(trie2.get(b"doge").unwrap().unwrap(), b"coin");
}
}

#[cfg(test)]
mod borsh_compatibility_test {
use borsh::{BorshDeserialize, BorshSerialize};
use near_primitives::hash::{hash, CryptoHash};
use near_primitives::types::StateRoot;

use crate::trie::{TrieRefcountAddition, TrieRefcountSubtraction};
use crate::TrieChanges;

#[test]
fn test_trie_changes_compatibility() {
#[derive(BorshSerialize)]
struct LegacyTrieRefcountChange {
trie_node_or_value_hash: CryptoHash,
trie_node_or_value: Vec<u8>,
rc: std::num::NonZeroU32,
}

#[derive(BorshSerialize)]
struct LegacyTrieChanges {
old_root: StateRoot,
new_root: StateRoot,
insertions: Vec<LegacyTrieRefcountChange>,
deletions: Vec<LegacyTrieRefcountChange>,
}

let changes = LegacyTrieChanges {
old_root: hash(b"a"),
new_root: hash(b"b"),
insertions: vec![LegacyTrieRefcountChange {
trie_node_or_value_hash: hash(b"c"),
trie_node_or_value: b"d".to_vec(),
rc: std::num::NonZeroU32::new(1).unwrap(),
}],
deletions: vec![LegacyTrieRefcountChange {
trie_node_or_value_hash: hash(b"e"),
trie_node_or_value: b"f".to_vec(),
rc: std::num::NonZeroU32::new(2).unwrap(),
}],
};

let serialized = borsh::to_vec(&changes).unwrap();
let deserialized = TrieChanges::try_from_slice(&serialized).unwrap();
assert_eq!(
deserialized,
TrieChanges {
old_root: hash(b"a"),
new_root: hash(b"b"),
insertions: vec![TrieRefcountAddition {
trie_node_or_value_hash: hash(b"c"),
trie_node_or_value: b"d".to_vec(),
rc: std::num::NonZeroU32::new(1).unwrap(),
}],
deletions: vec![TrieRefcountSubtraction::new(
hash(b"e"),
std::num::NonZeroU32::new(2).unwrap(),
)],
}
);
}
}
2 changes: 1 addition & 1 deletion core/store/src/trie/shard_tries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl ShardTries {
store_update: &mut StoreUpdate,
) {
let mut ops = Vec::new();
for TrieRefcountSubtraction { trie_node_or_value_hash, rc } in deletions.iter() {
for TrieRefcountSubtraction { trie_node_or_value_hash, rc, .. } in deletions.iter() {
let key = TrieCachingStorage::get_key_from_shard_uid_and_hash(
shard_uid,
trie_node_or_value_hash,
Expand Down
3 changes: 2 additions & 1 deletion core/store/src/trie/state_parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,8 @@ mod tests {
{
map.add(trie_node_or_value_hash, trie_node_or_value, rc.get());
}
for TrieRefcountSubtraction { trie_node_or_value_hash, rc } in changes_set.deletions {
for TrieRefcountSubtraction { trie_node_or_value_hash, rc, .. } in changes_set.deletions
{
map.subtract(trie_node_or_value_hash, rc.get());
}
}
Expand Down

0 comments on commit bc2d7f7

Please sign in to comment.