Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.
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
6 changes: 3 additions & 3 deletions zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1328,10 +1328,10 @@ impl<F: Field> ExecutionConfig<F> {
}
}

let rlc_assignments: BTreeSet<_> = block
.rws
.table_assignments()
let rlc_assignments: BTreeSet<_> = step
.rw_indices
.iter()
.map(|rw_idx| block.rws[*rw_idx])
.map(|rw| {
rw.table_assignment_aux(evm_randomness)
.rlc(lookup_randomness)
Expand Down
4 changes: 3 additions & 1 deletion zkevm-circuits/src/witness/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,13 @@ pub fn block_convert<F: Field>(
block: &circuit_input_builder::Block,
code_db: &bus_mapping::state_db::CodeDB,
) -> Result<Block<F>, Error> {
let rws = RwMap::from(&block.container);
rws.check_value();
Ok(Block {
// randomness: F::from(0x100), // Special value to reveal elements after RLC
randomness: F::from(0xcafeu64),
context: block.into(),
rws: RwMap::from(&block.container),
rws,
txs: block
.txs()
.iter()
Expand Down
60 changes: 60 additions & 0 deletions zkevm-circuits/src/witness/rw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::collections::HashMap;
use bus_mapping::operation::{self, AccountField, CallContextField, TxLogField, TxReceiptField};
use eth_types::{Address, Field, ToAddress, ToLittleEndian, ToScalar, Word, U256};
use halo2_proofs::circuit::Value;
use halo2_proofs::halo2curves::bn256::Fr;
use itertools::Itertools;

use crate::evm_circuit::util::rlc;
Expand All @@ -12,6 +13,8 @@ use crate::table::{
};
use crate::util::build_tx_log_address;

use super::MptUpdates;

/// Rw constainer for a witness block
#[derive(Debug, Default, Clone)]
pub struct RwMap(pub HashMap<RwTableTag, Vec<Rw>>);
Expand All @@ -38,6 +41,63 @@ impl RwMap {
debug_assert_eq!(idx, rw_counter - 1);
}
}
/// Check value in the same way like StateCircuit
pub fn check_value(&self) {
let mock_rand = Fr::from(0x1000u64);
let err_msg_first = "first access reads don't change value";
let err_msg_non_first = "non-first access reads don't change value";
let rows = self.table_assignments();
let updates = MptUpdates::mock_from(&rows);
let mut errs = Vec::new();
for idx in 1..rows.len() {
let row = &rows[idx];
let prev_row = &rows[idx - 1];
let is_first = {
let key = |row: &Rw| {
(
row.tag() as u64,
row.id().unwrap_or_default(),
row.address().unwrap_or_default(),
row.field_tag().unwrap_or_default(),
row.storage_key().unwrap_or_default(),
)
};
key(prev_row) != key(row)
};
if !row.is_write() {
let value = row.value_assignment::<Fr>(mock_rand);
if is_first {
// value == init_value
let init_value = updates
.get(row)
.map(|u| u.value_assignments(mock_rand).1)
.unwrap_or_default();
if value != init_value {
errs.push((idx, err_msg_first, *row, *prev_row));
}
} else {
// value == prev_value
let prev_value = prev_row.value_assignment::<Fr>(mock_rand);

if value != prev_value {
errs.push((idx, err_msg_non_first, *row, *prev_row));
}
}
}
}
if !errs.is_empty() {
log::error!("after rw value check, err num: {}", errs.len());
for (idx, err_msg, row, prev_row) in errs {
log::error!(
"err: rw idx: {}, reason: \"{}\", row: {:?}, prev_row: {:?}",
idx,
err_msg,
row,
prev_row
);
}
}
}
/// Calculates the number of Rw::Start rows needed.
/// `target_len` is allowed to be 0 as an "auto" mode,
/// then only 1 Rw::Start row will be prepadded.
Expand Down