use crate::{
copy_circuit::util::number_or_hash_to_word,
evm_circuit::util::rlc,
impl_expr,
util::{build_tx_log_address, keccak, word::WordLoHi, Challenges},
witness::{Block, BlockContext, MptUpdateRow, MptUpdates, Rw, RwMap, RwRow, Transaction},
};
use bus_mapping::circuit_input_builder::{CopyDataType, CopyEvent, CopyStep};
use core::iter::once;
use eth_types::{Field, ToScalar, U256};
use gadgets::{
binary_number::BinaryNumberBits,
util::{split_u256, split_u256_limb64},
};
use halo2_proofs::{
circuit::{Layouter, Region, Value},
plonk::{Advice, Column, ConstraintSystem, Error, *},
poly::Rotation,
};
use itertools::Itertools;
use std::array;
use strum_macros::{EnumCount, EnumIter};
pub(crate) mod block_table;
pub(crate) mod bytecode_table;
pub(crate) mod chunk_ctx_table;
pub(crate) mod copy_table;
pub(crate) mod exp_table;
pub(crate) mod keccak_table;
pub mod mpt_table;
pub(crate) mod rw_table;
pub(crate) mod sig_table;
pub(crate) mod tx_table;
pub(crate) mod ux_table;
pub(crate) mod wd_table;
pub use block_table::{BlockContextFieldTag, BlockTable};
pub use bytecode_table::{BytecodeFieldTag, BytecodeTable};
pub use chunk_ctx_table::ChunkCtxTable;
pub use copy_table::CopyTable;
pub use exp_table::ExpTable;
pub use keccak_table::KeccakTable;
pub use ux_table::UXTable;
pub use mpt_table::{MPTProofType, MptTable};
pub use rw_table::RwTable;
pub use sig_table::SigTable;
pub use tx_table::{TxContextFieldTag, TxFieldTag, TxLogFieldTag, TxReceiptFieldTag, TxTable};
pub use wd_table::WdTable;
pub trait LookupTable<F: Field> {
fn columns(&self) -> Vec<Column<Any>>;
fn advice_columns(&self) -> Vec<Column<Advice>> {
self.columns()
.iter()
.map(|&col| col.try_into())
.filter_map(|res| res.ok())
.collect()
}
fn annotations(&self) -> Vec<String>;
fn table_exprs(&self, meta: &mut VirtualCells<F>) -> Vec<Expression<F>> {
self.columns()
.iter()
.map(|&column| meta.query_any(column, Rotation::cur()))
.collect()
}
fn annotate_columns(&self, cs: &mut ConstraintSystem<F>) {
self.columns()
.iter()
.zip(self.annotations().iter())
.for_each(|(&col, ann)| cs.annotate_lookup_any_column(col, || ann))
}
fn annotate_columns_in_region(&self, region: &mut Region<F>) {
self.columns()
.iter()
.zip(self.annotations().iter())
.for_each(|(&col, ann)| region.name_column(|| ann, col))
}
}
impl<F: Field, C: Into<Column<Any>> + Copy, const W: usize> LookupTable<F> for [C; W] {
fn table_exprs(&self, meta: &mut VirtualCells<F>) -> Vec<Expression<F>> {
self.iter()
.map(|column| meta.query_any(*column, Rotation::cur()))
.collect()
}
fn columns(&self) -> Vec<Column<Any>> {
self.iter().map(|&col| col.into()).collect()
}
fn annotations(&self) -> Vec<String> {
vec![]
}
}
#[derive(Clone, Copy, Debug, EnumIter, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum AccountFieldTag {
Nonce = 1,
Balance,
CodeHash,
NonExisting,
}
impl_expr!(AccountFieldTag);
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter)]
pub enum CallContextFieldTag {
RwCounterEndOfReversion = 1,
CallerId,
TxId,
Depth,
CallerAddress,
CalleeAddress,
CallDataOffset,
CallDataLength,
ReturnDataOffset,
ReturnDataLength,
Value,
IsSuccess,
IsPersistent,
IsStatic,
LastCalleeId,
LastCalleeReturnDataOffset,
LastCalleeReturnDataLength,
IsRoot,
IsCreate,
CodeHash,
ProgramCounter,
StackPointer,
GasLeft,
MemorySize,
ReversibleWriteCounter,
}
impl_expr!(CallContextFieldTag);
#[derive(Clone, Copy, Debug, EnumIter, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum StepStateFieldTag {
CallID = 1,
IsRoot,
IsCreate,
CodeHash,
ProgramCounter,
StackPointer,
GasLeft,
MemoryWordSize,
ReversibleWriteCounter,
LogID,
}
impl_expr!(StepStateFieldTag);