Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
einar-polygon committed Sep 12, 2024
1 parent dc2f6fc commit 2dee812
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 345 deletions.
27 changes: 0 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ enum-as-inner = "0.6.0"
env_logger = "0.11.3"
eth_trie = "0.4.0"
ethereum-types = "0.14.1"
evm-disassembler = "0.5.0"
futures = "0.3.30"
hashbrown = "0.14.5"
hex = "0.4.3"
Expand Down
11 changes: 4 additions & 7 deletions evm_arithmetization/src/cpu/kernel/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! the future execution and generate nondeterministically the corresponding
//! jumpdest table, before the actual CPU carries on with contract execution.
use core::option::Option::None;
use std::collections::{BTreeSet, HashMap};

use anyhow::anyhow;
Expand Down Expand Up @@ -75,8 +76,7 @@ pub(crate) struct Interpreter<F: Field> {
pub(crate) fn simulate_cpu_and_get_user_jumps<F: Field>(
final_label: &str,
state: &GenerationState<F>,
// TODO(einar): remove second component of pair.
) -> (Option<JumpDestTableProcessed>, ContextJumpDests) {
) -> Option<(JumpDestTableProcessed, JumpDestTableWitness)> {
match state.jumpdest_table {
Some(_) => Default::default(),
None => {
Expand All @@ -97,18 +97,15 @@ pub(crate) fn simulate_cpu_and_get_user_jumps<F: Field>(

let clock = interpreter.get_clock();

interpreter
let jdtw = interpreter
.generation_state
.set_jumpdest_analysis_inputs(interpreter.jumpdest_table.clone());

log::debug!(
"Simulated CPU for jumpdest analysis halted after {:?} cycles.",
clock
);
(
interpreter.generation_state.jumpdest_table,
ContextJumpDests(interpreter.jumpdest_table),
)
(interpreter.generation_state.jumpdest_table).map(|x| (x, jdtw))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion evm_arithmetization/src/cpu/kernel/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl<F: Field> Interpreter<F> {
}

pub(crate) fn set_jumpdest_analysis_inputs(&mut self, jumps: HashMap<usize, BTreeSet<usize>>) {
self.generation_state.set_jumpdest_analysis_inputs(jumps);
let _ = self.generation_state.set_jumpdest_analysis_inputs(jumps);
}

pub(crate) fn extract_kernel_memory(self, segment: Segment, range: Range<usize>) -> Vec<U256> {
Expand Down
26 changes: 20 additions & 6 deletions evm_arithmetization/src/generation/jumpdest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{
ops::{Deref, DerefMut},
};

use itertools::{sorted, Itertools};
use keccak_hash::H256;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -74,7 +75,7 @@ impl JumpDestTableWitness {
assert!(self.0[code_hash].0.contains_key(&batch_ctx));
assert!(self.0[code_hash].0[&batch_ctx].contains(offset));
}
dbg!(&self);
// dbg!(&self);
}
}

Expand All @@ -89,28 +90,41 @@ impl JumpDestTableWitness {

impl Display for JumpDestTableWitness {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "=== JumpDest table ===")?;
writeln!(f, "=== JumpDestTableWitness ===")?;

for (code, ctxtbls) in &self.0 {
write!(f, "codehash: {:?}\n{}", code, ctxtbls)?;
write!(f, "codehash: {:#x}\n{}", code, ctxtbls)?;
}
Ok(())
}
}

impl Display for ContextJumpDests {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for (ctx, offsets) in &self.0 {
write!(f, " ctx: {}, offsets: [", ctx)?;
let v: Vec<_> = self.0.iter().sorted().collect();
for (ctx, offsets) in v.into_iter() {
write!(f, " ctx: {:>4}: [", ctx)?;
for offset in offsets {
write!(f, "{:#10x} ", offset)?;
write!(f, "{:#}, ", offset)?;
}
writeln!(f, "]")?;
}
Ok(())
}
}

impl Display for JumpDestTableProcessed {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "=== JumpDestTableProcessed ===")?;

let v = sorted(self.0.clone());
for (ctx, code) in v {
writeln!(f, "ctx: {:?} {:?}", ctx, code)?;
}
Ok(())
}
}

impl Deref for ContextJumpDests {
type Target = HashMap<usize, BTreeSet<usize>>;

Expand Down
34 changes: 22 additions & 12 deletions evm_arithmetization/src/generation/prover_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use std::str::FromStr;
use anyhow::{bail, Error, Result};
use ethereum_types::{BigEndianHash, H256, U256, U512};
use itertools::Itertools;
use keccak_hash::keccak;
use num_bigint::BigUint;
use plonky2::field::types::Field;
use serde::{Deserialize, Serialize};

use super::jumpdest::JumpDestTableProcessed;
use super::jumpdest::{JumpDestTableProcessed, JumpDestTableWitness};
use super::linked_list::LinkedList;
use super::mpt::load_state_mpt;
use crate::cpu::kernel::cancun_constants::KZG_VERSIONED_HASH;
Expand Down Expand Up @@ -805,16 +806,20 @@ impl<F: Field> GenerationState<F> {
// Simulate the user's code and (unnecessarily) part of the kernel code,
// skipping the validate table call

// log::info!("{:?} Generating JUMPDEST tables", tx_hash);
self.jumpdest_table = if let Some(jumpdest_table_rpc) = &self.inputs.batch_jumpdest_table {
let jumpdest_table_processed =
set_jumpdest_analysis_inputs_rpc(jumpdest_table_rpc, &self.inputs.contract_code);
Some(jumpdest_table_processed)
} else {
let (jumpdest_table_processed, _) =
simulate_cpu_and_get_user_jumps("terminate_common", self);
jumpdest_table_processed
};
dbg!(&self.inputs.batch_jumpdest_table);
eprintln!("Generating JUMPDEST tables");
// w for witness
let rpcw = self.inputs.batch_jumpdest_table.as_ref();
let rpc = rpcw.map(|jdt| set_jumpdest_analysis_inputs_rpc(jdt, &self.inputs.contract_code));

if let Some((_sim, simw)) = simulate_cpu_and_get_user_jumps("terminate_common", self) {
if rpcw.is_some() && rpcw.unwrap() != &simw.clone() {
println!("SIMW {}", simw.clone());
println!("RPCW {}", rpcw.unwrap());
assert_eq!(simw.clone(), *rpcw.unwrap());
}
}
self.jumpdest_table = rpc;

Ok(())
}
Expand All @@ -825,10 +830,14 @@ impl<F: Field> GenerationState<F> {
pub(crate) fn set_jumpdest_analysis_inputs(
&mut self,
jumpdest_table: HashMap<usize, BTreeSet<usize>>,
) {
) -> JumpDestTableWitness {
let mut jdtw = JumpDestTableWitness::default();
self.jumpdest_table = Some(JumpDestTableProcessed::new(HashMap::from_iter(
jumpdest_table.into_iter().map(|(ctx, jumpdest_table)| {
let code = self.get_code(ctx).unwrap();
for offset in jumpdest_table.clone() {
jdtw.insert(keccak(code.clone()), ctx, offset);
}
if let Some(&largest_address) = jumpdest_table.last() {
let proofs = get_proofs_and_jumpdests(&code, largest_address, jumpdest_table);
(ctx, proofs)
Expand All @@ -837,6 +846,7 @@ impl<F: Field> GenerationState<F> {
}
}),
)));
jdtw
}

pub(crate) fn get_current_code(&self) -> Result<Vec<u8>, ProgramError> {
Expand Down
9 changes: 5 additions & 4 deletions test_native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,17 @@ RANDOMBLOCKS=`shuf --input-range=$CANCUN-$TIP -n $NUMRANDOMBLOCKS | sort`
GITHASH=`git rev-parse --short HEAD`
echo "Testing against mainnet, current revision: $GITHASH."

MAINNETBLOCKS="$MAINNETBLOCKS $RANDOMBLOCKS"
echo "Testing blocks: $MAINNETBLOCKS"
#BLOCKS="$MAINNETBLOCKS $RANDOMBLOCKS"
BLOCKS="$MAINNETBLOCKS"
echo "Testing blocks: $BLOCKS"

echo "Downloading witnesses.."

for BLOCK in $MAINNETBLOCKS; do
for BLOCK in $BLOCKS; do
WITNESS="witnesses/$BLOCK.native.$GITHASH.witness.json"
until [ -f $WITNESS -a -s $WITNESS ]; do
echo "Fetching block $BLOCK"
cargo run --quiet --release --bin rpc -- --backoff 3000 --max-retries 100 --rpc-url $RPC --rpc-type native fetch --start-block $BLOCK --end-block $BLOCK 1> $WITNESS
cargo run --release --bin rpc -- --backoff 3000 --max-retries 100 --rpc-url $RPC --rpc-type native fetch --start-block $BLOCK --end-block $BLOCK 1> $WITNESS
EXITCODE=$?

if [ -n $EXITCODE -a -f $WITNESS -a -s $WITNESS ]
Expand Down
2 changes: 1 addition & 1 deletion zero_bin/prover/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct CliProverConfig {
#[arg(short, long, help_heading = HELP_HEADING, default_value_t = 19)]
max_cpu_len_log: usize,
/// Number of transactions in a batch to process at once.
#[arg(short, long, help_heading = HELP_HEADING, default_value_t = 10)]
#[arg(short, long, help_heading = HELP_HEADING, default_value_t = 1)]
batch_size: usize,
/// If true, save the public inputs to disk on error.
#[arg(short='i', long, help_heading = HELP_HEADING, default_value_t = false)]
Expand Down
1 change: 0 additions & 1 deletion zero_bin/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ prover = { workspace = true }
alloy-serde = { workspace = true }
alloy-primitives = { workspace = true }
keccak-hash = { workspace = true }
evm-disassembler = { workspace = true }

[build-dependencies]
cargo_metadata = { workspace = true }
Expand Down
81 changes: 6 additions & 75 deletions zero_bin/rpc/src/jerigon.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
use std::collections::BTreeSet;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::collections::BTreeMap;
use std::ops::Deref as _;

use alloy::providers::ext::DebugApi;
use alloy::rpc::types::trace::geth::{AccountState, DiffMode, PreStateMode, StructLog};
use alloy::rpc::types::trace::geth::StructLog;
use alloy::{
primitives::B256,
providers::Provider,
rpc::types::{eth::BlockId, trace::geth::GethTrace, Block, BlockTransactionsKind, Transaction},
transports::Transport,
};
use alloy_primitives::{keccak256, Address};
use alloy_primitives::Address;
use anyhow::Context as _;
use compat::Compat as _;
use evm_arithmetization::jumpdest::JumpDestTableWitness;
use evm_arithmetization::CodeDb;
use futures::stream::FuturesOrdered;
use futures::StreamExt as _;
use keccak_hash::H256;
use prover::BlockProverInput;
use serde::Deserialize;
use serde_json::json;
use trace_decoder::{
BlockTrace, BlockTraceTriePreImages, CombinedPreImages, ContractCodeUsage, TxnInfo, TxnMeta,
TxnTrace,
BlockTrace, BlockTraceTriePreImages, CombinedPreImages, TxnInfo, TxnMeta, TxnTrace,
};
use zero_bin_common::provider::CachedProvider;

Expand Down Expand Up @@ -177,80 +172,16 @@ where
_ => None,
};

let tx_trace = tx_trace
let tx_traces = tx_trace
.iter()
.map(|(h, t)| (Address::from(h.to_fixed_bytes()), t.clone()))
.collect();

// let code_db = match (pre_trace, diff_trace) {
// (
// GethTrace::PreStateTracer(PreStateFrame::Default(read)),
// GethTrace::PreStateTracer(PreStateFrame::Diff(diff)),
// ) => process_tx_traces(access_list, read, diff).await?,
// _ => unreachable!(),
// };
let code_db = Default::default();

let jumpdest_table: Option<JumpDestTableWitness> = struct_logs_opt.and_then(|struct_log| {
jumpdest::generate_jumpdest_table(tx, &struct_log, &tx_trace, &code_db)
jumpdest::generate_jumpdest_table(tx, &struct_log, &tx_traces)
.map(Some)
.unwrap_or_default()
});

Ok(jumpdest_table)
}

/// Processes the transaction traces and updates the accounts state.
async fn process_tx_traces(
mut access_list: HashMap<Address, HashSet<H256>>,
read_trace: PreStateMode,
diff_trace: DiffMode,
) -> anyhow::Result<CodeDb> {
let DiffMode {
pre: pre_trace,
post: post_trace,
} = diff_trace;

let addresses: HashSet<_> = read_trace
.0
.keys()
.chain(post_trace.keys())
.chain(pre_trace.keys())
.chain(access_list.keys())
.copied()
.collect();

let mut code_db = BTreeSet::new();

for address in addresses {
let read_state = read_trace.0.get(&address);
let post_state = post_trace.get(&address);

let code = process_code(post_state, read_state, &mut code_db).await;
}

Ok(code_db)
}

/// Processes the code usage for the given account state.
async fn process_code(
post_state: Option<&AccountState>,
read_state: Option<&AccountState>,
code_db: &mut CodeDb,
) -> Option<ContractCodeUsage> {
match (
post_state.and_then(|x| x.code.as_ref()),
read_state.and_then(|x| x.code.as_ref()),
) {
(Some(post_code), _) => {
code_db.insert(post_code.to_vec());
Some(ContractCodeUsage::Write(post_code.to_vec()))
}
(_, Some(read_code)) => {
let code_hash = keccak256(read_code).compat();
code_db.insert(read_code.to_vec());
Some(ContractCodeUsage::Read(code_hash))
}
_ => None,
}
}
Loading

0 comments on commit 2dee812

Please sign in to comment.