Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: replace StoredBranchNode, StoredTrieMask and StoredHashBuilderValue types with Compact impl instead #9573

Merged
merged 1 commit into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -207,7 +207,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
Loading