PROVER_INPUT instruction

This commit is contained in:
Daniel Lubarov 2022-07-18 21:01:06 -07:00
parent 539364c87a
commit b9b3c24cf9
5 changed files with 56 additions and 15 deletions

View File

@ -78,6 +78,7 @@ pub struct CpuColumnsView<T> {
pub is_chainid: T,
pub is_selfbalance: T,
pub is_basefee: T,
pub is_prover_input: T,
pub is_pop: T,
pub is_mload: T,
pub is_mstore: T,
@ -134,7 +135,6 @@ pub struct CpuColumnsView<T> {
pub is_invalid_11: T,
pub is_invalid_12: T,
pub is_invalid_13: T,
pub is_invalid_14: T,
/// If CPU cycle: the opcode, broken up into bits in **big-endian** order.
pub opcode_bits: [T; 8],

View File

@ -75,9 +75,9 @@ const OPCODES: [(u64, usize, usize); 107] = [
(0x46, 0, COL_MAP.is_chainid),
(0x47, 0, COL_MAP.is_selfbalance),
(0x48, 0, COL_MAP.is_basefee),
(0x49, 0, COL_MAP.is_invalid_6),
(0x4a, 1, COL_MAP.is_invalid_7), // 0x4a-0x4b
(0x4c, 2, COL_MAP.is_invalid_8), // 0x4c-0x4f
(0x49, 0, COL_MAP.is_prover_input),
(0x4a, 1, COL_MAP.is_invalid_6), // 0x4a-0x4b
(0x4c, 2, COL_MAP.is_invalid_7), // 0x4c-0x4f
(0x50, 0, COL_MAP.is_pop),
(0x51, 0, COL_MAP.is_mload),
(0x52, 0, COL_MAP.is_mstore),
@ -103,11 +103,11 @@ const OPCODES: [(u64, usize, usize); 107] = [
(0xa3, 0, COL_MAP.is_log3),
(0xa4, 0, COL_MAP.is_log4),
(0xa5, 0, COL_MAP.is_panic),
(0xa6, 1, COL_MAP.is_invalid_9), // 0xa6-0xa7
(0xa8, 3, COL_MAP.is_invalid_10), // 0xa8-0xaf
(0xb0, 4, COL_MAP.is_invalid_11), // 0xb0-0xbf
(0xc0, 5, COL_MAP.is_invalid_12), // 0xc0-0xdf
(0xe0, 4, COL_MAP.is_invalid_13), // 0xe0-0xef
(0xa6, 1, COL_MAP.is_invalid_8), // 0xa6-0xa7
(0xa8, 3, COL_MAP.is_invalid_9), // 0xa8-0xaf
(0xb0, 4, COL_MAP.is_invalid_10), // 0xb0-0xbf
(0xc0, 5, COL_MAP.is_invalid_11), // 0xc0-0xdf
(0xe0, 4, COL_MAP.is_invalid_12), // 0xe0-0xef
(0xf0, 0, COL_MAP.is_create),
(0xf1, 0, COL_MAP.is_call),
(0xf2, 0, COL_MAP.is_callcode),
@ -122,7 +122,7 @@ const OPCODES: [(u64, usize, usize); 107] = [
(0xfb, 0, COL_MAP.is_mload_general),
(0xfc, 0, COL_MAP.is_mstore_general),
(0xfd, 0, COL_MAP.is_revert),
(0xfe, 0, COL_MAP.is_invalid_14),
(0xfe, 0, COL_MAP.is_invalid_13),
(0xff, 0, COL_MAP.is_selfdestruct),
];

View File

@ -1,4 +1,4 @@
use anyhow::bail;
use anyhow::{anyhow, bail};
use ethereum_types::{U256, U512};
/// Halt interpreter execution whenever a jump to this offset is done.
@ -49,6 +49,9 @@ pub(crate) struct Interpreter<'a> {
offset: usize,
pub(crate) stack: Vec<U256>,
pub(crate) memory: EvmMemory,
/// Non-deterministic prover inputs, stored backwards so that popping the last item gives the
/// next prover input.
prover_inputs: Vec<U256>,
running: bool,
}
@ -57,12 +60,25 @@ pub(crate) fn run(
initial_offset: usize,
initial_stack: Vec<U256>,
) -> anyhow::Result<Interpreter> {
run_with_input(code, initial_offset, initial_stack, vec![])
}
pub(crate) fn run_with_input(
code: &[u8],
initial_offset: usize,
initial_stack: Vec<U256>,
mut prover_inputs: Vec<U256>,
) -> anyhow::Result<Interpreter> {
// Prover inputs are stored backwards, so that popping the last item gives the next input.
prover_inputs.reverse();
let mut interpreter = Interpreter {
code,
jumpdests: find_jumpdests(code),
offset: initial_offset,
stack: initial_stack,
memory: EvmMemory::default(),
prover_inputs,
running: true,
};
@ -149,6 +165,7 @@ impl<'a> Interpreter<'a> {
0x45 => todo!(), // "GASLIMIT",
0x46 => todo!(), // "CHAINID",
0x48 => todo!(), // "BASEFEE",
0x49 => self.run_prover_input()?, // "PROVER_INPUT",
0x50 => self.run_pop(), // "POP",
0x51 => self.run_mload(), // "MLOAD",
0x52 => self.run_mstore(), // "MSTORE",
@ -303,6 +320,15 @@ impl<'a> Interpreter<'a> {
self.push(!x);
}
fn run_prover_input(&mut self) -> anyhow::Result<()> {
let input = self
.prover_inputs
.pop()
.ok_or_else(|| anyhow!("Out of prover inputs"))?;
self.stack.push(input);
Ok(())
}
fn run_pop(&mut self) {
self.pop();
}

View File

@ -1,3 +1,4 @@
use ethereum_types::U256;
use plonky2::field::extension::Extendable;
use plonky2::field::polynomial::PolynomialValues;
use plonky2::field::types::Field;
@ -45,18 +46,28 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
current_cpu_row,
memory,
keccak_inputs,
logic_ops: logic_inputs,
logic_ops,
prover_inputs,
..
} = state;
assert_eq!(current_cpu_row, [F::ZERO; NUM_CPU_COLUMNS].into());
assert_eq!(prover_inputs, vec![], "Not all prover inputs were consumed");
let cpu_trace = trace_rows_to_poly_values(cpu_rows);
let keccak_trace = all_stark.keccak_stark.generate_trace(keccak_inputs);
let logic_trace = all_stark.logic_stark.generate_trace(logic_inputs);
let logic_trace = all_stark.logic_stark.generate_trace(logic_ops);
let memory_trace = all_stark.memory_stark.generate_trace(memory.log);
vec![cpu_trace, keccak_trace, logic_trace, memory_trace]
}
fn generate_txn<F: Field>(_state: &mut GenerationState<F>, _txn: &TransactionData) {
todo!()
fn generate_txn<F: Field>(state: &mut GenerationState<F>, txn: &TransactionData) {
// TODO: Add transaction RLP to prover_input.
// Supply Merkle trie proofs as prover inputs.
for proof in &txn.trie_proofs {
let proof = proof
.iter()
.flat_map(|node_rlp| node_rlp.iter().map(|byte| U256::from(*byte)));
state.prover_inputs.extend(proof);
}
}

View File

@ -19,6 +19,9 @@ pub(crate) struct GenerationState<F: Field> {
pub(crate) keccak_inputs: Vec<[u64; keccak::keccak_stark::NUM_INPUTS]>,
pub(crate) logic_ops: Vec<logic::Operation>,
/// Non-deterministic inputs provided by the prover.
pub(crate) prover_inputs: Vec<U256>,
}
impl<F: Field> GenerationState<F> {
@ -111,6 +114,7 @@ impl<F: Field> Default for GenerationState<F> {
memory: MemoryState::default(),
keccak_inputs: vec![],
logic_ops: vec![],
prover_inputs: vec![],
}
}
}