Skip to content

Commit

Permalink
Merge branch 'develop' into benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
Nashtare authored Jun 12, 2024
2 parents 1cdf25c + 46eb449 commit cdb5e92
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 8 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.4.0] - 2024-06-12

### Changed
- Some cleanup ([#190](https://github.com/0xPolygonZero/zk_evm/pull/190))
- Silence jumpdest analysis logs ([#193](https://github.com/0xPolygonZero/zk_evm/pull/193))
- Charge call value gas prior to call ([#199](https://github.com/0xPolygonZero/zk_evm/pull/199))
- refactor: fix todos ([#162](https://github.com/0xPolygonZero/zk_evm/pull/162))
- Remove print call in trace_decoder ([#208](https://github.com/0xPolygonZero/zk_evm/pull/208))
- Update CODEOWNERS ([#224](https://github.com/0xPolygonZero/zk_evm/pull/224))
- Fix access lists pointers check ([#217](https://github.com/0xPolygonZero/zk_evm/pull/217))
- Add a few QoL useability functions to the interface ([#169](https://github.com/0xPolygonZero/zk_evm/pull/169))
- Amortize `sha2` compression loop ([#231](https://github.com/0xPolygonZero/zk_evm/pull/231))
- ci: add cargo audit job ([#236](https://github.com/0xPolygonZero/zk_evm/pull/236))
- fix: Revert interpreter stack display ([#238](https://github.com/0xPolygonZero/zk_evm/pull/238))
- Fix clippy `doc_lazy_continuation` ([#247](https://github.com/0xPolygonZero/zk_evm/pull/247))
- perf: Improve `blake2` precompile ([#239](https://github.com/0xPolygonZero/zk_evm/pull/239))
- fix: rustdoc and tests ([#255](https://github.com/0xPolygonZero/zk_evm/pull/255))
- Native trace processing support ([#246](https://github.com/0xPolygonZero/zk_evm/pull/246))
- Added `Clone` to a few error types in `mpt_trie` ([#259](https://github.com/0xPolygonZero/zk_evm/pull/259))
- cleanup: remove outdated segment ([#262](https://github.com/0xPolygonZero/zk_evm/pull/262))
- fix: add G2 subgroup check for `ECPAIRING` ([#268](https://github.com/0xPolygonZero/zk_evm/pull/268))
- add partial trie builder ([#258](https://github.com/0xPolygonZero/zk_evm/pull/258))

## [0.3.1] - 2024-04-22

Expand Down
4 changes: 2 additions & 2 deletions evm_arithmetization/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "evm_arithmetization"
description = "Implementation of STARKs for the Ethereum Virtual Machine"
version = "0.1.3"
version = "0.2.0"
authors = ["Daniel Lubarov <[email protected]>", "William Borgeaud <[email protected]>"]
readme = "README.md"
categories = ["cryptography"]
Expand Down Expand Up @@ -41,7 +41,7 @@ tiny-keccak = "2.0.2"
serde_json = { workspace = true }

# Local dependencies
mpt_trie = { version = "0.2.1", path = "../mpt_trie" }
mpt_trie = { version = "0.3.0", path = "../mpt_trie" }

[target.'cfg(not(target_env = "msvc"))'.dependencies]
jemallocator = "0.5.0"
Expand Down
2 changes: 1 addition & 1 deletion mpt_trie/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "mpt_trie"
description = "Types and utility functions for building/working with partial Ethereum tries."
version = "0.2.1"
version = "0.3.0"
authors = ["Polygon Zero <[email protected]>"]
readme = "README.md"
edition.workspace = true
Expand Down
168 changes: 168 additions & 0 deletions mpt_trie/src/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
//! A builder for constructing a partial trie from a collection of proofs.
use std::collections::HashMap;
use std::sync::Arc;

use ethereum_types::H256;
use keccak_hash::keccak;

use super::{
nibbles::Nibbles,
partial_trie::{Node, PartialTrie, WrappedNode},
};

/// The hash of an empty trie.
const EMPTY_TRIE_HASH: H256 = H256([
0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e,
0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21,
]);

#[derive(Debug)]
/// A builder for constructing a partial trie from a collection of nodes.
pub struct PartialTrieBuilder<T> {
root: H256,
nodes: HashMap<H256, Vec<u8>>,
_marker: std::marker::PhantomData<T>,
}

impl<T: PartialTrie> PartialTrieBuilder<T> {
/// Creates a new `PartialTrieBuilder` with the given root and nodes.
pub fn new(root: H256, nodes: HashMap<H256, Vec<u8>>) -> Self {
PartialTrieBuilder {
root,
nodes,
_marker: std::marker::PhantomData,
}
}

/// Inserts a proof into the builder.
///
/// The proof is a collection of nodes that are used to construct the
/// partial trie.
pub fn insert_proof(&mut self, proof: Vec<Vec<u8>>) {
for node in proof {
self.nodes.insert(keccak(&node), node.to_vec());
}
}

/// Inserts variants of extension and leaf nodes into the builder.
pub fn insert_short_node_variants_from_proof(&mut self, proof: Vec<Vec<u8>>) {
for node in proof {
let bytes = rlp::decode_list::<Vec<u8>>(&node);
match bytes.len() {
2 => self.insert_short_node_variants(bytes),
_ => continue,
}
}
}

/// Builds the partial trie from the nodes and root.
pub fn build(self) -> T {
construct_partial_trie(self.root, &self.nodes)
}

fn insert_short_node_variants(&mut self, bytes: Vec<Vec<u8>>) {
let is_leaf = is_leaf_node(&bytes);
let mut nibbles = Nibbles::from_bytes_be(&bytes[0][..]).unwrap();
while !nibbles.is_empty() {
nibbles.pop_next_nibble_front();
let node = rlp::encode_list::<Vec<u8>, _>(&[
nibbles.to_hex_prefix_encoding(is_leaf).to_vec(),
bytes[1].clone(),
]);
self.nodes.entry(keccak(&node)).or_insert(node.to_vec());
}
}
}

/// Constructs a partial trie from a root hash and a collection of nodes.
fn construct_partial_trie<T: PartialTrie>(hash: H256, nodes: &HashMap<H256, Vec<u8>>) -> T {
let bytes = match nodes.get(&hash) {
Some(value) => rlp::decode_list::<Vec<u8>>(value),
None if [H256::zero(), EMPTY_TRIE_HASH].contains(&hash) => return T::default(),
None => return T::new(Node::Hash(hash)),
};

decode_node(bytes, nodes)
}

fn decode_node<T: PartialTrie>(bytes: Vec<Vec<u8>>, nodes: &HashMap<H256, Vec<u8>>) -> T {
let node = match bytes.len() {
17 => parse_branch_node(bytes, nodes),
2 if is_extension_node(&bytes) => parse_extension_node(bytes, nodes),
2 if is_leaf_node(&bytes) => parse_leaf_node(bytes),
_ => unreachable!(),
};

T::new(node)
}

/// Returns true if the node is an extension node.
fn is_extension_node(bytes: &[Vec<u8>]) -> bool {
(bytes[0][0] >> 4 == 0) | (bytes[0][0] >> 4 == 1)
}

/// Returns true if the node is a leaf node.
fn is_leaf_node(bytes: &[Vec<u8>]) -> bool {
(bytes[0][0] >> 4 == 2) | (bytes[0][0] >> 4 == 3)
}

/// Parses a branch node from the given bytes.
fn parse_branch_node<T: PartialTrie>(
bytes: Vec<Vec<u8>>,
nodes: &HashMap<H256, Vec<u8>>,
) -> Node<T> {
let children = (0..16)
.map(|i| {
let child = match bytes[i].is_empty() {
true => T::default(),
false => parse_child_node(&bytes[i], nodes),
};
Arc::new(Box::new(child))
})
.collect::<Vec<WrappedNode<T>>>();

Node::<T>::Branch {
children: children.try_into().unwrap(),
value: bytes[16].clone(),
}
}

/// Parses an extension node from the given bytes.
fn parse_extension_node<T: PartialTrie>(
bytes: Vec<Vec<u8>>,
nodes: &HashMap<H256, Vec<u8>>,
) -> Node<T> {
let mut encoded_path = Nibbles::from_bytes_be(&bytes[0][..]).unwrap();

if encoded_path.pop_next_nibble_front() == 0 {
encoded_path.pop_next_nibble_front();
}

Node::Extension {
nibbles: encoded_path,
child: Arc::new(Box::new(parse_child_node(&bytes[1], nodes))),
}
}

/// Parses a leaf node from the given bytes.
fn parse_leaf_node<T: PartialTrie>(bytes: Vec<Vec<u8>>) -> Node<T> {
let mut encoded_path = Nibbles::from_bytes_be(&bytes[0][..]).unwrap();

if encoded_path.pop_next_nibble_front() == 2 {
encoded_path.pop_next_nibble_front();
}

Node::Leaf {
nibbles: encoded_path,
value: bytes[1].clone(),
}
}

/// Parses a child node from the given bytes.
fn parse_child_node<T: PartialTrie>(bytes: &[u8], nodes: &HashMap<H256, Vec<u8>>) -> T {
match bytes.len() {
x if x < 32 => decode_node(rlp::decode_list::<Vec<u8>>(bytes), nodes),
_ => construct_partial_trie(H256::from_slice(bytes), nodes),
}
}
1 change: 1 addition & 0 deletions mpt_trie/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

pub mod builder;
pub mod nibbles;
pub mod partial_trie;
pub mod special_query;
Expand Down
4 changes: 2 additions & 2 deletions proof_gen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "proof_gen"
description = "Generates block proofs from zero proof IR."
version = "0.1.3"
version = "0.2.0"
authors = ["Polygon Zero <[email protected]>"]
edition.workspace = true
license.workspace = true
Expand All @@ -17,4 +17,4 @@ plonky2 = { workspace = true }
serde = { workspace = true }

# Local dependencies
evm_arithmetization = { version = "0.1.3", path = "../evm_arithmetization" }
evm_arithmetization = { version = "0.2.0", path = "../evm_arithmetization" }
6 changes: 3 additions & 3 deletions trace_decoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "trace_decoder"
description = "Processes trace payloads into Intermediate Representation (IR) format."
authors = ["Polygon Zero <[email protected]>"]
version = "0.3.1"
version = "0.4.0"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand All @@ -27,8 +27,8 @@ serde_with = "3.4.0"
thiserror = { workspace = true }

# Local dependencies
mpt_trie = { version = "0.2.1", path = "../mpt_trie" }
evm_arithmetization = { version = "0.1.3", path = "../evm_arithmetization" }
mpt_trie = { version = "0.3.0", path = "../mpt_trie" }
evm_arithmetization = { version = "0.2.0", path = "../evm_arithmetization" }

[dev-dependencies]
criterion = "0.5.1"
Expand Down

0 comments on commit cdb5e92

Please sign in to comment.