chore(deps): bump nybbles, correct some unchecked usages (#6794)

Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
This commit is contained in:
DaniPopes
2024-02-26 18:09:35 +02:00
committed by GitHub
parent ac36fa96ec
commit 285312ea68
9 changed files with 33 additions and 100 deletions

8
Cargo.lock generated
View File

@ -349,9 +349,9 @@ dependencies = [
[[package]]
name = "alloy-trie"
version = "0.2.1"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59974c3c7778ebbcd73356a430fd4608aaf0630b1fdb4f5337bfd70f40b66618"
checksum = "6b9e1498416f7e7f09af8061970e14936846b6271e153aa5ba539a22a7eb414d"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@ -4660,9 +4660,9 @@ dependencies = [
[[package]]
name = "nybbles"
version = "0.1.2"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836816c354fb2c09622b54545a6f98416147346b13cc7eba5f92fab6b3042c93"
checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23"
dependencies = [
"alloy-rlp",
"arbitrary",

View File

@ -180,7 +180,7 @@ alloy-primitives = "0.6"
alloy-dyn-abi = "0.6"
alloy-sol-types = "0.6"
alloy-rlp = "0.3"
alloy-trie = "0.2"
alloy-trie = "0.3"
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
@ -223,7 +223,7 @@ metrics = "0.21.1" # Needed for `metrics-macro` to resolve the crate using `::me
hex-literal = "0.4"
once_cell = "1.17"
syn = "2.0"
nybbles = "0.1"
nybbles = "0.2.1"
smallvec = "1.13"
# proc-macros

View File

@ -25,7 +25,7 @@ alloy-primitives = { workspace = true, features = ["rand", "rlp"] }
alloy-rlp = { workspace = true, features = ["arrayvec"] }
alloy-trie = { workspace = true, features = ["serde"] }
ethers-core = { workspace = true, default-features = false, optional = true }
nybbles = { version = "0.1.2", features = ["serde", "rlp"] }
nybbles = { workspace = true, features = ["serde", "rlp"] }
alloy-genesis.workspace = true
alloy-eips.workspace = true
# crypto
@ -125,7 +125,3 @@ harness = false
name = "trie_root"
required-features = ["arbitrary", "test-utils"]
harness = false
[[bench]]
name = "nibbles"
harness = false

View File

@ -1,65 +0,0 @@
#![allow(missing_docs)]
use criterion::{criterion_group, criterion_main, Criterion};
use proptest::{prelude::*, strategy::ValueTree};
use reth_primitives::trie::Nibbles;
use std::{hint::black_box, time::Duration};
/// Benchmarks the nibble unpacking.
pub fn nibbles_benchmark(c: &mut Criterion) {
let mut g = c.benchmark_group("nibbles");
g.warm_up_time(Duration::from_secs(1));
g.noise_threshold(0.02);
g.bench_function("unpack/32", |b| {
let bytes = get_bytes(32);
b.iter(|| Nibbles::unpack(black_box(&bytes[..])))
});
g.bench_function("unpack/256", |b| {
let bytes = get_bytes(256);
b.iter(|| Nibbles::unpack(black_box(&bytes[..])))
});
g.bench_function("unpack/2048", |b| {
let bytes = get_bytes(2048);
b.iter(|| Nibbles::unpack(black_box(&bytes[..])))
});
g.bench_function("pack/32", |b| {
let nibbles = get_nibbles(32);
b.iter(|| black_box(&nibbles).pack())
});
g.bench_function("pack/256", |b| {
let nibbles = get_nibbles(256);
b.iter(|| black_box(&nibbles).pack())
});
g.bench_function("pack/2048", |b| {
let nibbles = get_nibbles(2048);
b.iter(|| black_box(&nibbles).pack())
});
g.bench_function("encode_path_leaf/31", |b| {
let nibbles = get_nibbles(31);
b.iter(|| black_box(&nibbles).encode_path_leaf(false))
});
g.bench_function("encode_path_leaf/256", |b| {
let nibbles = get_nibbles(256);
b.iter(|| black_box(&nibbles).encode_path_leaf(false))
});
g.bench_function("encode_path_leaf/2048", |b| {
let nibbles = get_nibbles(2048);
b.iter(|| black_box(&nibbles).encode_path_leaf(false))
});
}
fn get_nibbles(len: usize) -> Nibbles {
Nibbles::from_nibbles_unchecked(get_bytes(len))
}
fn get_bytes(len: usize) -> Vec<u8> {
proptest::collection::vec(proptest::arbitrary::any::<u8>(), len)
.new_tree(&mut Default::default())
.unwrap()
.current()
}
criterion_group!(benches, nibbles_benchmark);
criterion_main!(benches);

View File

@ -92,15 +92,14 @@ fn generate_test_data(size: usize) -> (Vec<Nibbles>, Vec<Nibbles>, Vec<bool>) {
let config = ProptestConfig { result_cache: basic_result_cache, ..Default::default() };
let mut runner = TestRunner::new(config);
let mut preload = vec(vec(any::<u8>(), 32), size).new_tree(&mut runner).unwrap().current();
let vec_of_nibbles = |range| vec(any_with::<Nibbles>(range), size);
let mut preload = vec_of_nibbles(32usize.into()).new_tree(&mut runner).unwrap().current();
preload.dedup();
preload.sort();
let preload = preload.into_iter().map(Nibbles::from_nibbles_unchecked).collect::<Vec<_>>();
let mut input = vec(vec(any::<u8>(), 0..=32), size).new_tree(&mut runner).unwrap().current();
let mut input = vec_of_nibbles((0..=32usize).into()).new_tree(&mut runner).unwrap().current();
input.dedup();
input.sort();
let input = input.into_iter().map(Nibbles::from_nibbles_unchecked).collect::<Vec<_>>();
let expected = input
.iter()

View File

@ -176,14 +176,14 @@ mod tests {
#[test]
fn test_contains_with_multiple_inserts_and_duplicates() {
let mut prefix_set = PrefixSetMut::default();
prefix_set.insert(Nibbles::from_nibbles_unchecked(b"123"));
prefix_set.insert(Nibbles::from_nibbles_unchecked(b"124"));
prefix_set.insert(Nibbles::from_nibbles_unchecked(b"456"));
prefix_set.insert(Nibbles::from_nibbles_unchecked(b"123")); // Duplicate
prefix_set.insert(Nibbles::from_nibbles([1, 2, 3]));
prefix_set.insert(Nibbles::from_nibbles([1, 2, 4]));
prefix_set.insert(Nibbles::from_nibbles([4, 5, 6]));
prefix_set.insert(Nibbles::from_nibbles([1, 2, 3])); // Duplicate
assert!(prefix_set.contains(b"12"));
assert!(prefix_set.contains(b"45"));
assert!(!prefix_set.contains(b"78"));
assert!(prefix_set.contains(&[1, 2]));
assert!(prefix_set.contains(&[4, 5]));
assert!(!prefix_set.contains(&[7, 8]));
assert_eq!(prefix_set.len(), 3); // Length should be 3 (excluding duplicate)
}
}

View File

@ -172,14 +172,11 @@ mod tests {
let mut cursor = provider.tx_ref().cursor_dup_write::<tables::StoragesTrie>().unwrap();
let hashed_address = B256::random();
let key = vec![0x2, 0x3];
let key = StoredNibblesSubKey::from(vec![0x2, 0x3]);
let value = BranchNodeCompact::new(1, 1, 1, vec![B256::random()], None);
cursor
.upsert(
hashed_address,
StorageTrieEntry { nibbles: key.clone().into(), node: value.clone() },
)
.upsert(hashed_address, StorageTrieEntry { nibbles: key.clone(), node: value.clone() })
.unwrap();
let mut cursor = DatabaseStorageTrieCursor::new(cursor, hashed_address);

View File

@ -68,11 +68,13 @@ impl CursorSubNode {
}
/// Returns the full key of the current node.
#[inline]
pub fn full_key(&self) -> &Nibbles {
&self.full_key
}
/// Returns `true` if the state flag is set for the current nibble.
#[inline]
pub fn state_flag(&self) -> bool {
self.node
.as_ref()
@ -80,6 +82,7 @@ impl CursorSubNode {
}
/// Returns `true` if the tree flag is set for the current nibble.
#[inline]
pub fn tree_flag(&self) -> bool {
self.node
.as_ref()

View File

@ -171,7 +171,7 @@ impl<C: TrieCursor> TrieWalker<C> {
// Check if the walker needs to backtrack to the previous level in the trie during its
// traversal.
if subnode.nibble() >= 15 || (subnode.nibble() < 0 && !allow_root_to_child_nibble) {
if subnode.nibble() >= 0xf || (subnode.nibble() < 0 && !allow_root_to_child_nibble) {
self.stack.pop();
self.move_to_next_sibling(false)?;
return Ok(())
@ -184,10 +184,13 @@ impl<C: TrieCursor> TrieWalker<C> {
}
// Find the next sibling with state.
while subnode.nibble() < 16 {
loop {
if subnode.state_flag() {
return Ok(())
}
if subnode.nibble() == 0xf {
break
}
subnode.inc_nibble();
}
@ -354,26 +357,26 @@ mod tests {
// No changes
let mut cursor = TrieWalker::new(&mut trie, Default::default());
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles_unchecked([]))); // root
assert_eq!(cursor.key().cloned(), Some(Nibbles::new())); // root
assert!(cursor.can_skip_current_node); // due to root_hash
cursor.advance().unwrap(); // skips to the end of trie
assert_eq!(cursor.key().cloned(), None);
// We insert something that's not part of the existing trie/prefix.
let mut changed = PrefixSetMut::default();
changed.insert(Nibbles::from_nibbles_unchecked([0xF, 0x1]));
changed.insert(Nibbles::from_nibbles([0xF, 0x1]));
let mut cursor = TrieWalker::new(&mut trie, changed.freeze());
// Root node
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles_unchecked([])));
assert_eq!(cursor.key().cloned(), Some(Nibbles::new()));
// Should not be able to skip state due to the changed values
assert!(!cursor.can_skip_current_node);
cursor.advance().unwrap();
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles_unchecked([0x2])));
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles([0x2])));
cursor.advance().unwrap();
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles_unchecked([0x2, 0x1])));
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles([0x2, 0x1])));
cursor.advance().unwrap();
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles_unchecked([0x4])));
assert_eq!(cursor.key().cloned(), Some(Nibbles::from_nibbles([0x4])));
cursor.advance().unwrap();
assert_eq!(cursor.key().cloned(), None); // the end of trie