Skip to content

Commit

Permalink
feat: add initial tests
Browse files Browse the repository at this point in the history
  • Loading branch information
morph-dev committed Apr 12, 2024
1 parent 502a39d commit 3178b63
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 56 deletions.
7 changes: 5 additions & 2 deletions verkle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
alloy-primitives = { version = "0.7.0", features = ["serde", "ssz"] }
alloy-primitives = { version = "0.7.0", features = ["serde", "ssz", "rand"] }
anyhow = "1.0.82"
ark-ec = "0.4.2"
ark-ed-on-bls12-381-bandersnatch = "0.4.0"
Expand All @@ -17,9 +17,12 @@ db = { path = "../db" }
derive_more = "0.99.17"
ethereum_ssz = "0.5.3"
ethereum_ssz_derive = "0.5.3"
hex = "0.4.3"
once_cell = "1.19.0"
sha2 = "0.10.8"
ssz_types = "0.6.0"

[dev-dependencies]
hex = "0.4.3"
claims = "0.7.1"
rand = "0.8.5"
rstest = "0.19.0"
8 changes: 4 additions & 4 deletions verkle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use alloy_primitives::{B256, U256};
use derive_more::{Deref, Index};
use derive_more::{Constructor, Deref, From, Index};

use banderwagon::Fr;
pub use stem::Stem as TrieStem;
pub use trie::Trie;

mod committer;
mod constants;
pub mod crs;
pub mod nodes;
mod stem;
pub mod stem;
pub mod trie;
mod utils;

pub type TrieValue = U256;

type Db = dyn db::Db<Fr, Vec<u8>>;

#[derive(PartialEq, Eq, Clone, Index, Deref)]
#[derive(PartialEq, Eq, Clone, Copy, Constructor, Index, Deref, From)]
pub struct TrieKey(B256);

impl TrieKey {
Expand Down
6 changes: 3 additions & 3 deletions verkle/src/nodes/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Default for BranchNode {
}

impl NodeTrait for BranchNode {
fn commit(&self) -> Fr {
fn commitment(&self) -> Fr {
self.cp.map_to_scalar_field()
}
}
Expand All @@ -83,7 +83,7 @@ impl Encode for BranchNode {
if node.is_empty() {
None
} else {
Some((index as u8, fr_to_b256(&node.commit())))
Some((index as u8, fr_to_b256(&node.commitment())))
}
})
.collect();
Expand Down Expand Up @@ -115,7 +115,7 @@ impl Decode for BranchNode {
commitments
.get(&i)
.map(|c| Node::Commitment(*c))
.unwrap_or_default()
.unwrap_or_else(|| Node::Empty)
});
let cp = DEFAULT_COMMITER.commit_sparse(commitments.into_iter().collect());

Expand Down
129 changes: 100 additions & 29 deletions verkle/src/nodes/leaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ssz::{Decode, SszDecoderBuilder};
use ssz_derive::Encode;

use crate::{
committer::DEFAULT_COMMITER, constants::VERKLE_NODE_WIDTH, crs::CRS, TrieKey, TrieStem,
committer::DEFAULT_COMMITER, constants::VERKLE_NODE_WIDTH, crs::CRS, stem::Stem, TrieKey,
TrieValue,
};

Expand All @@ -22,7 +22,7 @@ static TWO_POWER_128: Lazy<Fr> = Lazy::new(|| {

#[derive(Index, Encode)]
pub struct LeafNode {
stem: TrieStem,
stem: Stem,
#[index]
values: BTreeMap<u8, TrieValue>,

Expand All @@ -38,7 +38,7 @@ pub struct LeafNode {
}

impl LeafNode {
pub fn new(stem: TrieStem) -> Self {
pub fn new(stem: Stem) -> Self {
let const_c = DEFAULT_COMMITER.commit_sparse(vec![
(0, Fr::one()),
(1, Fr::from_le_bytes_mod_order(stem.as_slice())),
Expand All @@ -59,7 +59,7 @@ impl LeafNode {
result
}

pub fn stem(&self) -> &TrieStem {
pub fn stem(&self) -> &Stem {
&self.stem
}

Expand Down Expand Up @@ -89,7 +89,7 @@ impl LeafNode {
Self::value_low_high_16(&old_value)
});

let low_index = (index % VERKLE_NODE_WIDTH) / 2;
let low_index = index % (VERKLE_NODE_WIDTH / 2) * 2;
let high_index = low_index + 1;

let diff = CRS[low_index] * (value_low_16 - old_value_low_16)
Expand All @@ -110,58 +110,129 @@ impl LeafNode {
}

fn value_low_high_16(value: &TrieValue) -> (Fr, Fr) {
let value_as_le_slice = value.as_le_slice();
(
Fr::from_le_bytes_mod_order(&value.as_le_slice()[0..16]) + TWO_POWER_128.deref(),
Fr::from_le_bytes_mod_order(&value.as_le_slice()[16..32]),
Fr::from_le_bytes_mod_order(&value_as_le_slice[0..16]) + TWO_POWER_128.deref(),
Fr::from_le_bytes_mod_order(&value_as_le_slice[16..32]),
)
}
}

impl NodeTrait for LeafNode {
fn commit(&self) -> Fr {
fn commitment(&self) -> Fr {
self.c.unwrap_or_else(|| self.calculate_commitment())
}

fn commit_mut(&mut self) -> Fr {
fn commit(&mut self) -> Fr {
self.c = self.c.or_else(|| Some(self.calculate_commitment()));
self.c.expect("Value must be present")
}
}

// impl NodeTrait for LeafNode {
// fn commit(&self) -> Fr {
// self.c.unwrap_or_else(|| {
// let c = self.const_c
// + CRS[2] * self.c1.map_to_scalar_field()
// + CRS[3] * self.c2.map_to_scalar_field();
// c.map_to_scalar_field()
// })
// }

// fn commit_and_save(&mut self, db: &mut Db) -> Fr {
// let c = self.commit();
// self.c = Some(c);
// db.write(c, self.as_ssz_bytes()).unwrap();
// c
// }
// }

impl Decode for LeafNode {
fn is_ssz_fixed_len() -> bool {
false
}

fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
let mut decoder_builder = SszDecoderBuilder::new(bytes);
decoder_builder.register_type::<TrieStem>()?;
decoder_builder.register_type::<Stem>()?;
decoder_builder.register_type::<BTreeMap<u8, TrieValue>>()?;

let mut decoder = decoder_builder.build()?;
let stem = decoder.decode_next::<TrieStem>()?;
let stem = decoder.decode_next::<Stem>()?;
let values = decoder.decode_next::<BTreeMap<u8, TrieValue>>()?;

let mut result = Self::new(stem);
result.set_all(values);
Ok(result)
}
}

#[cfg(test)]
mod tests {
use alloy_primitives::{B256, U256};

use crate::utils::fr_to_b256;

use super::*;

#[test]
fn insert_key0_value0() {
let key = TrieKey::new(B256::ZERO);
let mut leaf = LeafNode::new_for_key_value(&key, TrieValue::ZERO);

assert_eq!(
fr_to_b256(&leaf.commit()).to_string(),
"0x1c0727f0c6c9887189f75a9d08b804aba20892a238e147750767eac22a830d08"
);
}

#[test]
fn insert_key1_value1() {
let key = TrieKey::new(U256::from(1).into());
let mut leaf = LeafNode::new_for_key_value(&key, TrieValue::from(1));

assert_eq!(
fr_to_b256(&leaf.commit()).to_string(),
"0x6ef020caaeda01ff573afe6df6460d4aae14b4987e02ea39074f270ce62dfc14"
);
}

#[test]
fn insert_increasing() {
let bytes = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
];
let key = TrieKey::new(B256::from(bytes));
let mut leaf = LeafNode::new_for_key_value(&key, TrieValue::from_le_bytes(bytes));

assert_eq!(
fr_to_b256(&leaf.commit()).to_string(),
"0xb897ba52c5317acd75f5f3c3922f461357d4fb8b685fe63f20a3b2adb014370a"
);
}

#[test]
fn insert_eoa_with_1eth_balance() {
let stem = Stem::from(&TrieKey::from(B256::from([
245, 110, 100, 66, 36, 244, 87, 100, 144, 207, 224, 222, 20, 36, 164, 83, 34, 18, 82,
155, 254, 55, 71, 19, 216, 78, 125, 126, 142, 146, 114, 0,
])));
let values = vec![
[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
],
[
0, 0, 100, 167, 179, 182, 224, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
],
[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
],
[
197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0,
182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112,
],
[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
],
];
let mut leaf = LeafNode::new(stem);
leaf.set_all(
values
.into_iter()
.enumerate()
.map(|(index, value)| (index as u8, TrieValue::from_le_bytes(value))),
);

assert_eq!(
fr_to_b256(&leaf.commit()).to_string(),
"0xcc30be1f0d50eacfacaa3361b8df4d2014a849854a6cf35e6c55e07d6963f519"
);
}
}
26 changes: 12 additions & 14 deletions verkle/src/nodes/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,35 @@ use crate::{Db, TrieKey, TrieValue};
use super::{BranchNode, LeafNode};

pub trait NodeTrait {
fn commit(&self) -> Fr;
fn commitment(&self) -> Fr;

fn commit_mut(&mut self) -> Fr {
self.commit()
fn commit(&mut self) -> Fr {
self.commitment()
}
}

#[derive(Default)]
pub enum Node {
#[default]
Empty,
Branch(BranchNode),
Leaf(LeafNode),
Commitment(Fr),
}

impl NodeTrait for Node {
fn commit(&self) -> Fr {
fn commitment(&self) -> Fr {
match self {
Node::Empty => Fr::zero(),
Node::Branch(branch_node) => branch_node.commit(),
Node::Leaf(leaf_node) => leaf_node.commit(),
Node::Branch(branch_node) => branch_node.commitment(),
Node::Leaf(leaf_node) => leaf_node.commitment(),
Node::Commitment(c) => *c,
}
}

fn commit_mut(&mut self) -> Fr {
fn commit(&mut self) -> Fr {
match self {
Node::Empty => Fr::zero(),
Node::Branch(branch_node) => branch_node.commit_mut(),
Node::Leaf(leaf_node) => leaf_node.commit_mut(),
Node::Branch(branch_node) => branch_node.commit(),
Node::Leaf(leaf_node) => leaf_node.commit(),
Node::Commitment(c) => *c,
}
}
Expand All @@ -52,12 +50,12 @@ impl Node {
}

pub fn check(&self, commitment: &Fr) -> Result<()> {
if &self.commit() == commitment {
if &self.commitment() == commitment {
Ok(())
} else {
Err(anyhow!(
"Node's commitment {:?} doesn't match expected {commitment:?}",
self.commit()
self.commitment()
))
}
}
Expand Down Expand Up @@ -102,7 +100,7 @@ impl Node {
} else {
let mut branch_node = BranchNode::new();
branch_node.set(
key[depth] as usize,
leaf_node.stem()[depth] as usize,
Node::Leaf(mem::replace(
leaf_node,
LeafNode::new(TrieKey(B256::ZERO).stem()),
Expand Down
Loading

0 comments on commit 3178b63

Please sign in to comment.