Skip to content

Commit

Permalink
REMOVE!! Hacked in smt logic
Browse files Browse the repository at this point in the history
- We need to access this normally with a feature gate, but just to rush
  getting something going, we're going to copy it in for now.
  • Loading branch information
BGluth committed Apr 10, 2024
1 parent 5a5ca5c commit 4c9b2b8
Show file tree
Hide file tree
Showing 8 changed files with 746 additions and 0 deletions.
1 change: 1 addition & 0 deletions trace_decoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ hex = { workspace = true }
hex-literal = { workspace = true }
keccak-hash = { workspace = true }
log = { workspace = true }
plonky2 = "0.2.1"
rlp = { workspace = true }
rlp-derive = { workspace = true }
serde = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions trace_decoder/src/compact/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod compact_smt_processing;
pub mod compact_to_mpt_trie;
pub mod compact_to_smt_trie;
mod compact_to_trie_common;
mod tmp;

#[cfg(test)]
pub(crate) mod complex_test_payloads;
103 changes: 103 additions & 0 deletions trace_decoder/src/compact/tmp/bits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::ops::Add;

use ethereum_types::{BigEndianHash, H256, U256};
use serde::{Deserialize, Serialize};

pub type Bit = bool;

#[derive(
Copy, Clone, Deserialize, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Debug,
)]
pub struct Bits {
/// The number of bits in this sequence.
pub count: usize,
/// A packed encoding of these bits. Only the first (least significant)
/// `count` bits are used. The rest are unused and should be zero.
pub packed: U256,
}

impl From<U256> for Bits {
fn from(packed: U256) -> Self {
Bits { count: 256, packed }
}
}

impl From<H256> for Bits {
fn from(packed: H256) -> Self {
Bits {
count: 256,
packed: packed.into_uint(),
}
}
}

impl Add for Bits {
type Output = Self;

fn add(self, rhs: Self) -> Self::Output {
assert!(self.count + rhs.count <= 256, "Overflow");
Self {
count: self.count + rhs.count,
packed: self.packed * (U256::one() << rhs.count) + rhs.packed,
}
}
}

impl Bits {
pub fn empty() -> Self {
Bits {
count: 0,
packed: U256::zero(),
}
}

pub fn is_empty(&self) -> bool {
self.count == 0
}

pub fn pop_next_bit(&mut self) -> Bit {
assert!(!self.is_empty(), "Cannot pop from empty bits");
let b = !(self.packed & U256::one()).is_zero();
self.packed >>= 1;
self.count -= 1;
b
}

pub fn get_bit(&self, i: usize) -> Bit {
assert!(i < self.count, "Index out of bounds");
!(self.packed & (U256::one() << (self.count - 1 - i))).is_zero()
}

pub fn push_bit(&mut self, bit: Bit) {
self.packed = self.packed * 2 + U256::from(bit as u64);
self.count += 1;
}

pub fn add_bit(&self, bit: Bit) -> Self {
let mut x = *self;
x.push_bit(bit);
x
}

pub fn common_prefix(&self, k: &Bits) -> (Self, Option<(Bit, Bit)>) {
let mut a = *self;
let mut b = *k;
while a.count > b.count {
a.pop_next_bit();
}
while a.count < b.count {
b.pop_next_bit();
}
if a == b {
return (a, None);
}
let mut a_bit = a.pop_next_bit();
let mut b_bit = b.pop_next_bit();
while a != b {
a_bit = a.pop_next_bit();
b_bit = b.pop_next_bit();
}
assert_ne!(a_bit, b_bit, "Sanity check.");
(a, Some((a_bit, b_bit)))
}
}
23 changes: 23 additions & 0 deletions trace_decoder/src/compact/tmp/db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::collections::HashMap;

use super::smt::{Key, Node};

pub trait Db: Default {
fn get_node(&self, key: &Key) -> Option<&Node>;
fn set_node(&mut self, key: Key, value: Node);
}

#[derive(Debug, Clone, Default)]
pub struct MemoryDb {
pub db: HashMap<Key, Node>,
}

impl Db for MemoryDb {
fn get_node(&self, key: &Key) -> Option<&Node> {
self.db.get(key)
}

fn set_node(&mut self, key: Key, value: Node) {
self.db.insert(key, value);
}
}
99 changes: 99 additions & 0 deletions trace_decoder/src/compact/tmp/keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#![allow(clippy::needless_range_loop)]

/// This module contains functions to generate keys for the SMT.
/// See https://github.com/0xPolygonHermez/zkevm-commonjs/blob/main/src/smt-utils.js for reference implementation.
use ethereum_types::{Address, U256};
use plonky2::{field::types::Field, hash::poseidon::Poseidon};

use super::smt::{Key, F};

const HASH_ZEROS: [u64; 4] = [
4330397376401421145,
14124799381142128323,
8742572140681234676,
14345658006221440202,
];

const SMT_KEY_BALANCE: u64 = 0;
const SMT_KEY_NONCE: u64 = 1;
const SMT_KEY_CODE: u64 = 2;
const SMT_KEY_STORAGE: u64 = 3;
const SMT_KEY_LENGTH: u64 = 4;

pub fn key_balance(addr: Address) -> Key {
let mut arr = [F::ZERO; 12];
for i in 0..5 {
arr[i] = F::from_canonical_u32(u32::from_be_bytes(
addr.0[16 - 4 * i..16 - 4 * i + 4].try_into().unwrap(),
));
}

arr[6] = F::from_canonical_u64(SMT_KEY_BALANCE);
arr[8..12].copy_from_slice(&HASH_ZEROS.map(F::from_canonical_u64));

Key(F::poseidon(arr)[0..4].try_into().unwrap())
}

pub fn key_nonce(addr: Address) -> Key {
let mut arr = [F::ZERO; 12];
for i in 0..5 {
arr[i] = F::from_canonical_u32(u32::from_be_bytes(
addr.0[16 - 4 * i..16 - 4 * i + 4].try_into().unwrap(),
));
}

arr[6] = F::from_canonical_u64(SMT_KEY_NONCE);
arr[8..12].copy_from_slice(&HASH_ZEROS.map(F::from_canonical_u64));

Key(F::poseidon(arr)[0..4].try_into().unwrap())
}

pub fn key_code(addr: Address) -> Key {
let mut arr = [F::ZERO; 12];
for i in 0..5 {
arr[i] = F::from_canonical_u32(u32::from_be_bytes(
addr.0[16 - 4 * i..16 - 4 * i + 4].try_into().unwrap(),
));
}

arr[6] = F::from_canonical_u64(SMT_KEY_CODE);
arr[8..12].copy_from_slice(&HASH_ZEROS.map(F::from_canonical_u64));

Key(F::poseidon(arr)[0..4].try_into().unwrap())
}

pub fn key_storage(addr: Address, slot: U256) -> Key {
let mut arr = [F::ZERO; 12];
for i in 0..5 {
arr[i] = F::from_canonical_u32(u32::from_be_bytes(
addr.0[16 - 4 * i..16 - 4 * i + 4].try_into().unwrap(),
));
}

arr[6] = F::from_canonical_u64(SMT_KEY_STORAGE);
let capacity: [F; 4] = {
let mut arr = [F::ZERO; 12];
for i in 0..4 {
arr[2 * i] = F::from_canonical_u32(slot.0[i] as u32);
arr[2 * i + 1] = F::from_canonical_u32((slot.0[i] >> 32) as u32);
}
F::poseidon(arr)[0..4].try_into().unwrap()
};
arr[8..12].copy_from_slice(&capacity);

Key(F::poseidon(arr)[0..4].try_into().unwrap())
}

pub fn key_code_length(addr: Address) -> Key {
let mut arr = [F::ZERO; 12];
for i in 0..5 {
arr[i] = F::from_canonical_u32(u32::from_be_bytes(
addr.0[16 - 4 * i..16 - 4 * i + 4].try_into().unwrap(),
));
}

arr[6] = F::from_canonical_u64(SMT_KEY_LENGTH);
arr[8..12].copy_from_slice(&HASH_ZEROS.map(F::from_canonical_u64));

Key(F::poseidon(arr)[0..4].try_into().unwrap())
}
8 changes: 8 additions & 0 deletions trace_decoder/src/compact/tmp/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! REMOVE THIS MODULE BEFORE MERGING INTO DEVELOP!!! THIS IS ONLY INTENDED TO
//! PUT OFF THE HARD TASK OF FEATURE GATING THE BRANCH `feat/type2`!!
mod bits;
mod db;
pub(crate) mod keys;
pub(crate) mod smt;
mod utils;
Loading

0 comments on commit 4c9b2b8

Please sign in to comment.