Skip to content

Commit

Permalink
Merge branch 'v0.7' into feat/par
Browse files Browse the repository at this point in the history
  • Loading branch information
z2trillion authored Nov 14, 2023
2 parents 7d09897 + 803c349 commit 4af3231
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 154 deletions.
7 changes: 0 additions & 7 deletions src/constraint_builder/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ use halo2_proofs::{
poly::Rotation,
};

#[derive(Clone, Copy)]
pub enum ColumnType {
Advice,
Fixed,
Challenge,
}

#[derive(Clone)]
pub enum Query<F: Clone> {
Constant(F),
Expand Down
9 changes: 3 additions & 6 deletions src/gadgets/key_bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{
};
use crate::{
assignment_map::{Assignment, Column},
constraint_builder::{AdviceColumn, ConstraintBuilder, Query, SelectorColumn},
constraint_builder::{AdviceColumn, ConstraintBuilder, Query},
};
use halo2_proofs::{
arithmetic::FieldExt, circuit::Region, halo2curves::bn256::Fr, plonk::ConstraintSystem,
Expand All @@ -17,8 +17,6 @@ pub trait KeyBitLookup {

#[derive(Clone)]
pub struct KeyBitConfig {
selector: SelectorColumn, // always enabled selector for constraints we want always enabled.

// Lookup columns
value: AdviceColumn, // We're proving value.bit(i) = bit in this gadget
index: AdviceColumn, // 0 <= index < 256
Expand All @@ -39,8 +37,7 @@ impl KeyBitConfig {
range_check_256: &impl RangeCheck256Lookup,
byte_bit: &impl ByteBitLookup,
) -> Self {
let ([selector], [], [value, index, bit, index_div_8, index_mod_8, byte]) =
cb.build_columns(cs);
let ([], [], [value, index, bit, index_div_8, index_mod_8, byte]) = cb.build_columns(cs);

cb.add_lookup(
"0 <= index < 256",
Expand Down Expand Up @@ -80,7 +77,6 @@ impl KeyBitConfig {
);

Self {
selector,
value,
index,
bit,
Expand Down Expand Up @@ -151,6 +147,7 @@ mod test {
rlc_randomness::RlcRandomness,
};
use super::*;
use crate::constraint_builder::SelectorColumn;
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
dev::MockProver,
Expand Down
127 changes: 38 additions & 89 deletions src/gadgets/mpt_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use ethers_core::types::Address;
use halo2_proofs::{
arithmetic::FieldExt,
circuit::{Region, Value},
halo2curves::{bn256::Fr, group::ff::PrimeField},
halo2curves::bn256::Fr,
plonk::{ConstraintSystem, Error},
};
use lazy_static::lazy_static;
Expand All @@ -42,7 +42,7 @@ lazy_static! {
}

pub trait MptUpdateLookup<F: FieldExt> {
fn lookup(&self) -> [Query<F>; 8];
fn lookup(&self) -> [Query<F>; 7];
}

#[derive(Clone)]
Expand Down Expand Up @@ -74,8 +74,10 @@ pub struct MptUpdateConfig {
}

impl<F: FieldExt> MptUpdateLookup<F> for MptUpdateConfig {
fn lookup(&self) -> [Query<F>; 8] {
fn lookup(&self) -> [Query<F>; 7] {
let is_start = || self.segment_type.current_matches(&[SegmentType::Start]);
// Note that one non-start rows, all 7 queries will be 0. This corresponds to a valid
// mpt proof in that in an empty trie, the zero address has nonce = 0.
let old_root_rlc = self.second_phase_intermediate_values[0].current() * is_start();
let new_root_rlc = self.second_phase_intermediate_values[1].current() * is_start();
let proof_type = self.proof_type.current() * is_start();
Expand All @@ -87,7 +89,6 @@ impl<F: FieldExt> MptUpdateLookup<F> for MptUpdateConfig {
* is_start();
let storage_key_rlc = self.storage_key_rlc.current() * is_start();
[
is_start().into(),
address,
storage_key_rlc,
proof_type,
Expand Down Expand Up @@ -417,13 +418,6 @@ fn new_right<F: FieldExt>(config: &MptUpdateConfig) -> Query<F> {
+ (Query::one() - config.direction.current()) * config.sibling.current()
}

fn address_to_fr(a: Address) -> Fr {
let mut bytes = [0u8; 32];
bytes[32 - 20..].copy_from_slice(a.as_bytes());
bytes.reverse();
Fr::from_repr(bytes).unwrap()
}

fn configure_segment_transitions<F: FieldExt>(
cb: &mut ConstraintBuilder<F>,
segment: &OneHot<SegmentType>,
Expand Down Expand Up @@ -649,10 +643,15 @@ fn configure_extension_old<F: FieldExt>(
poseidon: &impl PoseidonLookup,
) {
cb.assert(
"can only delete existing nodes for storage proofs",
"can only delete existing storage trie nodes for storage proofs",
config
.proof_type
.current_matches(&[MPTProofType::StorageChanged]),
.current_matches(&[MPTProofType::StorageChanged])
.and(
config
.segment_type
.current_matches(&[SegmentType::StorageTrie, SegmentType::StorageLeaf0]),
),
);
cb.assert_zero(
"new value is 0 when deleting node",
Expand Down Expand Up @@ -875,10 +874,10 @@ fn configure_nonce<F: FieldExt>(
config.path_type.current_matches(&[PathType::ExtensionNew]),
|cb| {
cb.assert_equal(
"sibling is hash(0, hash(0, 0)) for nonce extension new at AccountLeaf2",
config.sibling.current(),
Query::from(*ZERO_STORAGE_ROOT_KECCAK_CODEHASH_HASH),
);
"sibling is hash(0, hash(0, 0)) for nonce extension new at AccountLeaf2",
config.sibling.current(),
Query::from(*ZERO_STORAGE_ROOT_KECCAK_CODEHASH_HASH),
);
},
);
}
Expand Down Expand Up @@ -948,12 +947,6 @@ fn configure_code_size<F: FieldExt>(
bytes: &impl BytesLookup,
poseidon: &impl PoseidonLookup,
) {
cb.assert(
"new accounts have balance or nonce set first",
config
.path_type
.current_matches(&[PathType::Start, PathType::Common]),
);
for variant in SegmentType::iter() {
let conditional_constraints = |cb: &mut ConstraintBuilder<F>| match variant {
SegmentType::Start | SegmentType::AccountTrie => {
Expand Down Expand Up @@ -1124,19 +1117,21 @@ fn configure_balance<F: FieldExt>(
);
},
);
cb.add_lookup(
"new balance is rlc(new_hash) and fits into 31 bytes",
[
config.new_hash.current(),
Query::from(30),
config.new_value.current(),
],
rlc.lookup(),
);
cb.condition(
config
.path_type
.current_matches(&[PathType::Common, PathType::ExtensionNew]),
config.path_type.current_matches(&[PathType::ExtensionNew]),
|cb| {
cb.add_lookup(
"new balance is rlc(new_hash) and fits into 31 bytes",
[
config.new_hash.current(),
Query::from(30),
config.new_value.current(),
],
rlc.lookup(),
cb.assert_zero(
"sibling (code_size + nonce << 64) is 0 for new account)",
config.sibling.current(),
);
},
);
Expand All @@ -1163,42 +1158,22 @@ fn configure_poseidon_code_hash<F: FieldExt>(
cb: &mut ConstraintBuilder<F>,
config: &MptUpdateConfig,
) {
cb.assert(
"new accounts have balance or nonce set first",
config
.path_type
.current_matches(&[PathType::Start, PathType::Common]),
);
for variant in SegmentType::iter() {
let conditional_constraints = |cb: &mut ConstraintBuilder<F>| match variant {
SegmentType::AccountLeaf0 => {
cb.assert_equal("direction is 1", config.direction.current(), Query::one());
}
SegmentType::AccountLeaf1 => {
cb.assert_equal("direction is 1", config.direction.current(), Query::one());
cb.condition(
config
.path_type
.current_matches(&[PathType::Common, PathType::ExtensionOld]),
|cb| {
cb.assert_equal(
"old_hash is old poseidon code hash",
config.old_value.current(),
config.old_hash.current(),
);
},
cb.assert_equal(
"old_hash is old poseidon code hash",
config.old_value.current(),
config.old_hash.current(),
);
cb.condition(
config
.path_type
.current_matches(&[PathType::Common, PathType::ExtensionNew]),
|cb| {
cb.assert_equal(
"new_hash is new poseidon code hash",
config.new_value.current(),
config.new_hash.current(),
);
},
cb.assert_equal(
"new_hash is new poseidon code hash",
config.new_value.current(),
config.new_hash.current(),
);
}
_ => {}
Expand All @@ -1218,12 +1193,6 @@ fn configure_keccak_code_hash<F: FieldExt>(
rlc: &impl RlcLookup,
randomness: Query<F>,
) {
cb.assert(
"new accounts have balance or nonce set first",
config
.path_type
.current_matches(&[PathType::Start, PathType::Common]),
);
for variant in SegmentType::iter() {
let conditional_constraints = |cb: &mut ConstraintBuilder<F>| match variant {
SegmentType::Start | SegmentType::AccountTrie => {
Expand Down Expand Up @@ -1319,10 +1288,6 @@ fn configure_storage<F: FieldExt>(
cb.assert_equal("direction is 1", config.direction.current(), Query::one());
}
SegmentType::AccountLeaf3 => {
cb.assert(
"storage modifications must be on an existing account",
config.path_type.current_matches(&[PathType::Common]),
);
cb.assert_zero("direction is 0", config.direction.current());
let [key_high, key_low, ..] = config.intermediate_values;
let [rlc_key_high, rlc_key_low, ..] = config.second_phase_intermediate_values;
Expand All @@ -1342,11 +1307,8 @@ fn configure_storage<F: FieldExt>(
let [old_high, old_low, new_high, new_low, ..] = config.intermediate_values;
let [rlc_old_high, rlc_old_low, rlc_new_high, rlc_new_low, ..] =
config.second_phase_intermediate_values;

cb.condition(
config
.path_type
.current_matches(&[PathType::Common, PathType::ExtensionOld]),
config.path_type.current_matches(&[PathType::Common]),
|cb| {
configure_word_rlc(
cb,
Expand All @@ -1357,13 +1319,6 @@ fn configure_storage<F: FieldExt>(
rlc,
randomness.clone(),
);
},
);
cb.condition(
config
.path_type
.current_matches(&[PathType::Common, PathType::ExtensionNew]),
|cb| {
configure_word_rlc(
cb,
[config.new_hash, new_high, new_low],
Expand Down Expand Up @@ -1492,12 +1447,6 @@ fn configure_empty_account<F: FieldExt>(
config: &MptUpdateConfig,
poseidon: &impl PoseidonLookup,
) {
cb.assert(
"path type is start or common for empty account proof",
config
.path_type
.current_matches(&[PathType::Start, PathType::Common]),
);
cb.assert_zero("old value is 0", config.old_value.current());
cb.assert_zero("new value is 0", config.new_value.current());
cb.assert_equal(
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(dead_code)]
#![allow(clippy::too_many_arguments)]
#![deny(unsafe_code)]

Expand Down
10 changes: 7 additions & 3 deletions src/mpt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
assignment_map::{Assignment, AssignmentMap},
constraint_builder::{ConstraintBuilder, SelectorColumn},
constraint_builder::{ConstraintBuilder, Query, SelectorColumn},
gadgets::{
byte_bit::ByteBitGadget,
byte_representation::ByteRepresentationConfig,
Expand Down Expand Up @@ -78,7 +78,6 @@ impl MptCircuitConfig {
// exist in an mpt with root = 0 (i.e. the mpt is empty).
let is_final_row = SelectorColumn(cs.fixed_column());
let padding_row_expressions = [
1.into(),
0.into(),
0.into(),
(MPTProofType::AccountDoesNotExist as u64).into(),
Expand Down Expand Up @@ -155,7 +154,12 @@ impl MptCircuitConfig {
}

pub fn lookup_exprs<F: FieldExt>(&self, meta: &mut VirtualCells<'_, F>) -> [Expression<F>; 8] {
self.mpt_update.lookup().map(|q| q.run(meta))
std::iter::once(Query::from(self.selector.current()))
.chain(self.mpt_update.lookup().into_iter())
.map(|q| q.run(meta))
.collect::<Vec<_>>()
.try_into()
.unwrap()
}

/// The number of minimum number of rows required for the mpt circuit.
Expand Down
Loading

0 comments on commit 4af3231

Please sign in to comment.