Skip to content

Commit

Permalink
chore: replace StoredBranchNode, StoredTrieMask and `StoredHashBu…
Browse files Browse the repository at this point in the history
…ilderValue` types with `Compact` impl instead (#9573)
  • Loading branch information
joshieDo committed Jul 17, 2024
1 parent 0befab5 commit 89d0281
Show file tree
Hide file tree
Showing 20 changed files with 175 additions and 206 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/storage/codecs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ alloy-consensus = { workspace = true, optional = true }
alloy-eips = { workspace = true, optional = true }
alloy-genesis = { workspace = true, optional = true }
alloy-primitives.workspace = true
alloy-trie.workspace = true

# misc
bytes.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/storage/codecs/src/alloy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ mod authorization_list;
mod genesis_account;
mod log;
mod request;
mod trie;
mod txkind;
mod withdrawal;
138 changes: 138 additions & 0 deletions crates/storage/codecs/src/alloy/trie.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//! Native Compact codec impl for EIP-7685 requests.

use crate::Compact;
use alloy_primitives::B256;
use alloy_trie::{hash_builder::HashBuilderValue, BranchNodeCompact, TrieMask};
use bytes::{Buf, BufMut};

impl Compact for HashBuilderValue {
fn to_compact<B>(self, buf: &mut B) -> usize
where
B: BufMut + AsMut<[u8]>,
{
match self {
Self::Hash(hash) => {
buf.put_u8(0);
1 + hash.to_compact(buf)
}
Self::Bytes(bytes) => {
buf.put_u8(1);
1 + bytes.to_compact(buf)
}
}
}

// # Panics
//
// A panic will be triggered if a HashBuilderValue variant greater than 1 is passed from the
// database.
fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) {
match buf.get_u8() {
0 => {
let (hash, buf) = B256::from_compact(buf, 32);
(Self::Hash(hash), buf)
}
1 => {
let (bytes, buf) = Vec::from_compact(buf, 0);
(Self::Bytes(bytes), buf)
}
_ => unreachable!("Junk data in database: unknown HashBuilderValue variant"),
}
}
}

impl Compact for BranchNodeCompact {
fn to_compact<B>(self, buf: &mut B) -> usize
where
B: bytes::BufMut + AsMut<[u8]>,
{
let mut buf_size = 0;

buf_size += self.state_mask.to_compact(buf);
buf_size += self.tree_mask.to_compact(buf);
buf_size += self.hash_mask.to_compact(buf);

if let Some(root_hash) = self.root_hash {
buf_size += B256::len_bytes();
buf.put_slice(root_hash.as_slice());
}

for hash in &self.hashes {
buf_size += B256::len_bytes();
buf.put_slice(hash.as_slice());
}

buf_size
}

fn from_compact(buf: &[u8], _len: usize) -> (Self, &[u8]) {
let hash_len = B256::len_bytes();

// Assert the buffer is long enough to contain the masks and the hashes.
assert_eq!(buf.len() % hash_len, 6);

// Consume the masks.
let (state_mask, buf) = TrieMask::from_compact(buf, 0);
let (tree_mask, buf) = TrieMask::from_compact(buf, 0);
let (hash_mask, buf) = TrieMask::from_compact(buf, 0);

let mut buf = buf;
let mut num_hashes = buf.len() / hash_len;
let mut root_hash = None;

// Check if the root hash is present
if hash_mask.count_ones() as usize + 1 == num_hashes {
root_hash = Some(B256::from_slice(&buf[..hash_len]));
buf.advance(hash_len);
num_hashes -= 1;
}

// Consume all remaining hashes.
let mut hashes = Vec::<B256>::with_capacity(num_hashes);
for _ in 0..num_hashes {
hashes.push(B256::from_slice(&buf[..hash_len]));
buf.advance(hash_len);
}

(Self::new(state_mask, tree_mask, hash_mask, hashes, root_hash), buf)
}
}

impl Compact for TrieMask {
fn to_compact<B>(self, buf: &mut B) -> usize
where
B: bytes::BufMut + AsMut<[u8]>,
{
buf.put_u16(self.get());
2
}

fn from_compact(mut buf: &[u8], _len: usize) -> (Self, &[u8]) {
let mask = buf.get_u16();
(Self::new(mask), buf)
}
}

#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::hex;

#[test]
fn node_encoding() {
let n = BranchNodeCompact::new(
0xf607,
0x0005,
0x4004,
vec![
hex!("90d53cd810cc5d4243766cd4451e7b9d14b736a1148b26b3baac7617f617d321").into(),
hex!("cc35c964dda53ba6c0b87798073a9628dbc9cd26b5cce88eb69655a9c609caf1").into(),
],
Some(hex!("aaaabbbb0006767767776fffffeee44444000005567645600000000eeddddddd").into()),
);

let mut out = Vec::new();
let compact_len = n.clone().to_compact(&mut out);
assert_eq!(BranchNodeCompact::from_compact(&out, compact_len).0, n);
}
}
2 changes: 1 addition & 1 deletion crates/storage/db-api/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl_compression_for_compact!(
Receipt,
TxType,
StorageEntry,
StoredBranchNode,
BranchNodeCompact,
StoredNibbles,
StoredNibblesSubKey,
StorageTrieEntry,
Expand Down
4 changes: 2 additions & 2 deletions crates/storage/db/src/tables/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use reth_primitives::{
use reth_primitives_traits::IntegerList;
use reth_prune_types::{PruneCheckpoint, PruneSegment};
use reth_stages_types::StageCheckpoint;
use reth_trie_common::{StorageTrieEntry, StoredBranchNode, StoredNibbles, StoredNibblesSubKey};
use reth_trie_common::{BranchNodeCompact, StorageTrieEntry, StoredNibbles, StoredNibblesSubKey};
use serde::{Deserialize, Serialize};
use std::fmt;

Expand Down Expand Up @@ -381,7 +381,7 @@ tables! {
table HashedStorages<Key = B256, Value = StorageEntry, SubKey = B256>;

/// Stores the current state's Merkle Patricia Tree.
table AccountsTrie<Key = StoredNibbles, Value = StoredBranchNode>;
table AccountsTrie<Key = StoredNibbles, Value = BranchNodeCompact>;

/// From HashedAddress => NibblesSubKey => Intermediate value
table StoragesTrie<Key = B256, Value = StorageTrieEntry, SubKey = StoredNibblesSubKey>;
Expand Down
3 changes: 0 additions & 3 deletions crates/trie/common/src/hash_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@
mod state;
pub use state::HashBuilderState;

mod value;
pub(crate) use value::StoredHashBuilderValue;

pub use alloy_trie::hash_builder::*;
19 changes: 9 additions & 10 deletions crates/trie/common/src/hash_builder/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::StoredHashBuilderValue;
use crate::{StoredTrieMask, TrieMask};
use crate::TrieMask;
use alloy_trie::{hash_builder::HashBuilderValue, HashBuilder};
use bytes::Buf;
use nybbles::Nibbles;
Expand Down Expand Up @@ -77,24 +76,24 @@ impl Compact for HashBuilderState {
len += 2 + item.len();
}

len += StoredHashBuilderValue(self.value).to_compact(buf);
len += self.value.to_compact(buf);

buf.put_u16(self.groups.len() as u16);
len += 2;
for item in &self.groups {
len += StoredTrieMask(*item).to_compact(buf);
len += (*item).to_compact(buf);
}

buf.put_u16(self.tree_masks.len() as u16);
len += 2;
for item in &self.tree_masks {
len += StoredTrieMask(*item).to_compact(buf);
len += (*item).to_compact(buf);
}

buf.put_u16(self.hash_masks.len() as u16);
len += 2;
for item in &self.hash_masks {
len += StoredTrieMask(*item).to_compact(buf);
len += (*item).to_compact(buf);
}

buf.put_u8(self.stored_in_database as u8);
Expand All @@ -113,28 +112,28 @@ impl Compact for HashBuilderState {
buf.advance(item_len);
}

let (StoredHashBuilderValue(value), mut buf) = StoredHashBuilderValue::from_compact(buf, 0);
let (value, mut buf) = HashBuilderValue::from_compact(buf, 0);

let groups_len = buf.get_u16() as usize;
let mut groups = Vec::with_capacity(groups_len);
for _ in 0..groups_len {
let (StoredTrieMask(item), rest) = StoredTrieMask::from_compact(buf, 0);
let (item, rest) = TrieMask::from_compact(buf, 0);
groups.push(item);
buf = rest;
}

let tree_masks_len = buf.get_u16() as usize;
let mut tree_masks = Vec::with_capacity(tree_masks_len);
for _ in 0..tree_masks_len {
let (StoredTrieMask(item), rest) = StoredTrieMask::from_compact(buf, 0);
let (item, rest) = TrieMask::from_compact(buf, 0);
tree_masks.push(item);
buf = rest;
}

let hash_masks_len = buf.get_u16() as usize;
let mut hash_masks = Vec::with_capacity(hash_masks_len);
for _ in 0..hash_masks_len {
let (StoredTrieMask(item), rest) = StoredTrieMask::from_compact(buf, 0);
let (item, rest) = TrieMask::from_compact(buf, 0);
hash_masks.push(item);
buf = rest;
}
Expand Down
43 changes: 0 additions & 43 deletions crates/trie/common/src/hash_builder/value.rs

This file was deleted.

8 changes: 1 addition & 7 deletions crates/trie/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,9 @@ pub mod hash_builder;
mod account;
pub use account::TrieAccount;

mod mask;
pub(crate) use mask::StoredTrieMask;

mod nibbles;
pub use nibbles::{Nibbles, StoredNibbles, StoredNibblesSubKey};

pub mod nodes;
pub use nodes::StoredBranchNode;

mod storage;
pub use storage::StorageTrieEntry;

Expand All @@ -36,4 +30,4 @@ pub use proofs::{AccountProof, StorageProof};

pub mod root;

pub use alloy_trie::{proof, BranchNodeCompact, HashBuilder, TrieMask, EMPTY_ROOT_HASH};
pub use alloy_trie::{nodes::*, proof, BranchNodeCompact, HashBuilder, TrieMask, EMPTY_ROOT_HASH};
20 changes: 0 additions & 20 deletions crates/trie/common/src/mask.rs

This file was deleted.

Loading

0 comments on commit 89d0281

Please sign in to comment.