Skip to content

Commit

Permalink
Move funcs to encodings module
Browse files Browse the repository at this point in the history
  • Loading branch information
fmoletta committed Nov 1, 2024
1 parent 9da6ec9 commit 8a0fbbb
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 63 deletions.
47 changes: 47 additions & 0 deletions crates/storage/trie/encoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// Converts a slice of compact-encoded nibbles into a byte slice
/// If the nibble slice has odd-length (aka the last byte will be a half byte) returns true else false
pub fn compact_nibbles_to_bytes(compact: &[u8]) -> (Vec<u8>, bool) {
// Convert compact nibbles to nibbles
let nibbles = compact_to_hex(compact);
// Convert nibbles to bytes, accouning for odd number of bytes
let mut last_is_half = false;
let bytes = nibbles
.chunks(2)
.map(|chunk| match chunk.len() {
1 => {
last_is_half = true;
chunk[0] << 4
}
// 2
_ => chunk[0] << 4 | chunk[1],
})
.collect::<Vec<_>>();
(bytes, last_is_half)
}

// Code taken from https://github.com/ethereum/go-ethereum/blob/a1093d98eb3260f2abf340903c2d968b2b891c11/trie/encoding.go#L82
fn compact_to_hex(compact: &[u8]) -> Vec<u8> {
if compact.is_empty() {
return vec![];
}
let mut base = keybytes_to_hex(compact);
// delete terminator flag
if base[0] < 2 {
base = base[..base.len() - 1].to_vec();
}
// apply odd flag
let chop = 2 - (base[0] & 1) as usize;
base[chop..].to_vec()
}

// Code taken from https://github.com/ethereum/go-ethereum/blob/a1093d98eb3260f2abf340903c2d968b2b891c11/trie/encoding.go#L96
fn keybytes_to_hex(keybytes: &[u8]) -> Vec<u8> {
let l = keybytes.len() * 2 + 1;
let mut nibbles = vec![0; l];
for (i, b) in keybytes.iter().enumerate() {
nibbles[i * 2] = b / 16;
nibbles[i * 2 + 1] = b % 16;
}
nibbles[l - 1] = 16;
nibbles
}
78 changes: 15 additions & 63 deletions crates/storage/trie/trie.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod db;
mod encoding;
mod error;
mod nibble;
mod node;
Expand All @@ -12,6 +13,7 @@ mod test_utils;

use std::borrow::Cow;

use encoding::compact_nibbles_to_bytes;
use ethereum_rust_rlp::constants::RLP_NULL;
use ethereum_types::H256;
use node::Node;
Expand Down Expand Up @@ -228,23 +230,21 @@ impl Trie {
return Ok(node.encode_raw(partial_path.offset()));
}
match node {
Node::Branch(branch_node) => {
match partial_path.next().map(usize::from) {
Some(idx) if idx < 16 => {
let child_hash = &branch_node.choices[idx];
if child_hash.is_valid() {
let child_node = self
.state
.get_node(child_hash.clone())?
.expect("inconsistent internal tree structure");
self.get_node_inner(child_node, partial_path, last_byte_is_half)
} else {
Ok(vec![])
}
Node::Branch(branch_node) => match partial_path.next().map(usize::from) {
Some(idx) if idx < 16 => {
let child_hash = &branch_node.choices[idx];
if child_hash.is_valid() {
let child_node = self
.state
.get_node(child_hash.clone())?
.expect("inconsistent internal tree structure");
self.get_node_inner(child_node, partial_path, last_byte_is_half)
} else {
Ok(vec![])
}
_ => Ok(vec![]),
}
}
_ => Ok(vec![]),
},
Node::Extension(extension_node) => {
if partial_path.skip_prefix(&extension_node.prefix)
&& extension_node.child.is_valid()
Expand Down Expand Up @@ -285,54 +285,6 @@ impl Trie {
}
}

/// Converts a slice of compact-encoded nibbles into a byte slice
/// If the nibble slice has odd-length (aka the last byte will be a half byte) returns true else false
fn compact_nibbles_to_bytes(compact: &Vec<u8>) -> (Vec<u8>, bool) {
// Convert compact nibbles to nibbles
let nibbles = compact_to_hex(compact);
// Convert nibbles to bytes, accouning for odd number of bytes
let mut last_is_half = false;
let bytes = nibbles
.chunks(2)
.map(|chunk| match chunk.len() {
1 => {
last_is_half = true;
chunk[0] << 4
}
// 2
_ => chunk[0] << 4 | chunk[1],
})
.collect::<Vec<_>>();
(bytes, last_is_half)
}

// Code taken from https://github.com/ethereum/go-ethereum/blob/a1093d98eb3260f2abf340903c2d968b2b891c11/trie/encoding.go#L82
fn compact_to_hex(compact: &Vec<u8>) -> Vec<u8> {
if compact.is_empty() {
return vec![];
}
let mut base = keybytes_to_hex(compact);
// delete terminator flag
if base[0] < 2 {
base = base[..base.len() - 1].to_vec();
}
// apply odd flag
let chop = 2 - (base[0] & 1) as usize;
base[chop..].to_vec()
}

// Code taken from https://github.com/ethereum/go-ethereum/blob/a1093d98eb3260f2abf340903c2d968b2b891c11/trie/encoding.go#L96
fn keybytes_to_hex(keybytes: &Vec<u8>) -> Vec<u8> {
let l = keybytes.len() * 2 + 1;
let mut nibbles = vec![0; l];
for (i, b) in keybytes.into_iter().enumerate() {
nibbles[i * 2] = b / 16;
nibbles[i * 2 + 1] = b % 16;
}
nibbles[l - 1] = 16;
nibbles
}

impl IntoIterator for Trie {
type Item = Node;

Expand Down

0 comments on commit 8a0fbbb

Please sign in to comment.