Skip to content

Commit

Permalink
fix: remove stack related ops
Browse files Browse the repository at this point in the history
  • Loading branch information
eigmax committed Oct 15, 2023
1 parent 0788691 commit 77799fd
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 22 deletions.
299 changes: 299 additions & 0 deletions src/generation/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
use std::collections::HashMap;

use anyhow::anyhow;
use ethereum_types::{Address, BigEndianHash, H256, U256};
use plonky2::field::extension::Extendable;
use plonky2::field::polynomial::PolynomialValues;
use plonky2::hash::hash_types::RichField;
use plonky2::timed;
use plonky2::util::timing::TimingTree;
use serde::{Deserialize, Serialize};
use GlobalMetadata::{
ReceiptTrieRootDigestAfter, ReceiptTrieRootDigestBefore, StateTrieRootDigestAfter,
StateTrieRootDigestBefore, TransactionTrieRootDigestAfter, TransactionTrieRootDigestBefore,
};

use crate::all_stark::{AllStark, NUM_TABLES};
use crate::config::StarkConfig;
use crate::cpu::bootstrap_kernel::generate_bootstrap_kernel;
use crate::cpu::columns::CpuColumnsView;
use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::generation::outputs::{get_outputs, GenerationOutputs};
use crate::generation::state::GenerationState;
use crate::memory::segments::Segment;
use crate::proof::{BlockHashes, BlockMetadata, ExtraBlockData, PublicValues, TrieRoots};
use crate::util::h2u;
use crate::witness::memory::{MemoryAddress, MemoryChannel};
use crate::witness::transition::transition;

use crate::witness::util::mem_write_log;

/// Inputs needed for trace generation.
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
pub struct GenerationInputs {
pub txn_number_before: U256,
pub gas_used_before: U256,
pub block_bloom_before: [U256; 8],
pub gas_used_after: U256,
pub block_bloom_after: [U256; 8],

pub signed_txns: Vec<Vec<u8>>,
/// Expected trie roots after the transactions are executed.
pub trie_roots_after: TrieRoots,
/// State trie root of the genesis block.
pub genesis_state_trie_root: H256,

/// Mapping between smart contract code hashes and the contract byte code.
/// All account smart contracts that are invoked will have an entry present.
pub contract_code: HashMap<H256, Vec<u8>>,

pub block_metadata: BlockMetadata,

pub block_hashes: BlockHashes,

/// A list of known addresses in the input state trie (which itself doesn't hold addresses,
/// only state keys). This is only useful for debugging, so that we can return addresses in the
/// post-state rather than state keys. (See `GenerationOutputs`, and in particular
/// `AddressOrStateKey`.) If the caller is not interested in the post-state, this can be left
/// empty.
pub addresses: Vec<Address>,
}

fn apply_metadata_and_tries_memops<F: RichField + Extendable<D>, const D: usize>(
state: &mut GenerationState<F>,
inputs: &GenerationInputs,
) {
let metadata = &inputs.block_metadata;
let tries = &inputs.tries;
let trie_roots_after = &inputs.trie_roots_after;
let fields = [
(
GlobalMetadata::BlockBeneficiary,
U256::from_big_endian(&metadata.block_beneficiary.0),
),
(GlobalMetadata::BlockTimestamp, metadata.block_timestamp),
(GlobalMetadata::BlockNumber, metadata.block_number),
(GlobalMetadata::BlockDifficulty, metadata.block_difficulty),
(
GlobalMetadata::BlockRandom,
metadata.block_random.into_uint(),
),
(GlobalMetadata::BlockGasLimit, metadata.block_gaslimit),
(GlobalMetadata::BlockChainId, metadata.block_chain_id),
(GlobalMetadata::BlockBaseFee, metadata.block_base_fee),
(
GlobalMetadata::BlockCurrentHash,
h2u(inputs.block_hashes.cur_hash),
),
(GlobalMetadata::BlockGasUsed, metadata.block_gas_used),
(GlobalMetadata::BlockGasUsedBefore, inputs.gas_used_before),
(GlobalMetadata::BlockGasUsedAfter, inputs.gas_used_after),
(GlobalMetadata::TxnNumberBefore, inputs.txn_number_before),
(
GlobalMetadata::TxnNumberAfter,
inputs.txn_number_before + inputs.signed_txns.len(),
),
(
GlobalMetadata::StateTrieRootDigestBefore,
h2u(tries.state_trie.hash()),
),
(
GlobalMetadata::TransactionTrieRootDigestBefore,
h2u(tries.transactions_trie.hash()),
),
(
GlobalMetadata::ReceiptTrieRootDigestBefore,
h2u(tries.receipts_trie.hash()),
),
(
GlobalMetadata::StateTrieRootDigestAfter,
h2u(trie_roots_after.state_root),
),
(
GlobalMetadata::TransactionTrieRootDigestAfter,
h2u(trie_roots_after.transactions_root),
),
(
GlobalMetadata::ReceiptTrieRootDigestAfter,
h2u(trie_roots_after.receipts_root),
),
];

let channel = MemoryChannel::GeneralPurpose(0);
let mut ops = fields
.map(|(field, val)| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::GlobalMetadata, field as usize),
state,
val,
)
})
.to_vec();

// Write the block's final block bloom filter.
ops.extend((0..8).map(|i| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::GlobalBlockBloom, i),
state,
metadata.block_bloom[i],
)
}));
// Write the block's bloom filter before the current transaction.
ops.extend(
(0..8)
.map(|i| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::GlobalBlockBloom, i + 8),
state,
inputs.block_bloom_before[i],
)
})
.collect::<Vec<_>>(),
);
// Write the block's bloom filter after the current transaction.
ops.extend(
(0..8)
.map(|i| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::GlobalBlockBloom, i + 16),
state,
inputs.block_bloom_after[i],
)
})
.collect::<Vec<_>>(),
);
// Write previous block hashes.
ops.extend(
(0..256)
.map(|i| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::BlockHashes, i),
state,
h2u(inputs.block_hashes.prev_hashes[i]),
)
})
.collect::<Vec<_>>(),
);

state.memory.apply_ops(&ops);
state.traces.memory_ops.extend(ops);
}

pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
all_stark: &AllStark<F, D>,
inputs: GenerationInputs,
config: &StarkConfig,
timing: &mut TimingTree,
) -> anyhow::Result<(
[Vec<PolynomialValues<F>>; NUM_TABLES],
PublicValues,
GenerationOutputs,
)> {
let mut state = GenerationState::<F>::new(inputs.clone(), &KERNEL.code)
.map_err(|err| anyhow!("Failed to parse all the initial prover inputs: {:?}", err))?;

apply_metadata_and_tries_memops(&mut state, &inputs);

generate_bootstrap_kernel::<F>(&mut state);

timed!(timing, "simulate CPU", simulate_cpu(&mut state)?);

assert!(
state.mpt_prover_inputs.is_empty(),
"All MPT data should have been consumed"
);

log::info!(
"Trace lengths (before padding): {:?}",
state.traces.get_lengths()
);

let outputs = get_outputs(&mut state)
.map_err(|err| anyhow!("Failed to generate post-state info: {:?}", err))?;

let read_metadata = |field| state.memory.read_global_metadata(field);
let trie_roots_before = TrieRoots {
state_root: H256::from_uint(&read_metadata(StateTrieRootDigestBefore)),
transactions_root: H256::from_uint(&read_metadata(TransactionTrieRootDigestBefore)),
receipts_root: H256::from_uint(&read_metadata(ReceiptTrieRootDigestBefore)),
};
let trie_roots_after = TrieRoots {
state_root: H256::from_uint(&read_metadata(StateTrieRootDigestAfter)),
transactions_root: H256::from_uint(&read_metadata(TransactionTrieRootDigestAfter)),
receipts_root: H256::from_uint(&read_metadata(ReceiptTrieRootDigestAfter)),
};

let gas_used_after = read_metadata(GlobalMetadata::BlockGasUsedAfter);
let txn_number_after = read_metadata(GlobalMetadata::TxnNumberAfter);

let extra_block_data = ExtraBlockData {
genesis_state_trie_root: inputs.genesis_state_trie_root,
txn_number_before: inputs.txn_number_before,
txn_number_after,
gas_used_before: inputs.gas_used_before,
gas_used_after,
block_bloom_before: inputs.block_bloom_before,
block_bloom_after: inputs.block_bloom_after,
};

let public_values = PublicValues {
trie_roots_before,
trie_roots_after,
block_metadata: inputs.block_metadata,
block_hashes: inputs.block_hashes,
extra_block_data,
};

let tables = timed!(
timing,
"convert trace data to tables",
state.traces.into_tables(all_stark, config, timing)
);
Ok((tables, public_values, outputs))
}

fn simulate_cpu<F: RichField + Extendable<D>, const D: usize>(
state: &mut GenerationState<F>,
) -> anyhow::Result<()> {
let halt_pc = KERNEL.global_labels["halt"];

loop {
// If we've reached the kernel's halt routine, and our trace length is a power of 2, stop.
let pc = state.registers.program_counter;
let halt = state.registers.is_kernel && pc == halt_pc;
if halt {
log::info!("CPU halted after {} cycles", state.traces.clock());

// Padding
let mut row = CpuColumnsView::<F>::default();
row.clock = F::from_canonical_usize(state.traces.clock());
row.context = F::from_canonical_usize(state.registers.context);
row.program_counter = F::from_canonical_usize(pc);
row.is_kernel_mode = F::ONE;
row.gas = [
F::from_canonical_u32(state.registers.gas_used as u32),
F::from_canonical_u32((state.registers.gas_used >> 32) as u32),
];
row.stack_len = F::from_canonical_usize(state.registers.stack_len);

loop {
state.traces.push_cpu(row);
row.clock += F::ONE;
if state.traces.clock().is_power_of_two() {
break;
}
}
log::info!("CPU trace padded to {} cycles", state.traces.clock());

return Ok(());
}

transition(state)?;
}
}
39 changes: 20 additions & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
pub mod all_stark;
pub mod arithmetic;
pub mod config;
pub mod constraint_consumer;
pub mod cpu;
pub mod cross_table_lookup;
pub mod evaluation_frame;
pub mod keccak;
pub mod keccak_sponge;
pub mod logic;
pub mod lookup;
pub mod memory;
pub mod proof;
pub mod prover;
pub mod stark;
pub mod stark_testing;
pub mod util;
pub mod vanishing_poly;
pub mod witness;
pub(crate) mod all_stark;
pub(crate) mod arithmetic;
pub(crate) mod config;
pub(crate) mod constraint_consumer;
pub(crate) mod cpu;
pub(crate) mod cross_table_lookup;
pub(crate) mod evaluation_frame;
pub(crate) mod keccak;
pub(crate) mod keccak_sponge;
pub(crate) mod logic;
pub(crate) mod lookup;
pub(crate) mod memory;
pub(crate) mod proof;
pub(crate) mod prover;
pub(crate) mod stark;
pub(crate) mod stark_testing;
pub(crate) mod util;
pub(crate) mod vanishing_poly;
pub(crate) mod witness;
pub(crate) mod generation;
4 changes: 1 addition & 3 deletions src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,13 @@ use crate::cross_table_lookup::{
};
use crate::evaluation_frame::StarkEvaluationFrame;
//use crate::generation::outputs::GenerationOutputs;
//use crate::generation::{generate_traces, GenerationInputs};
use crate::generation::{generate_traces, GenerationInputs};
//use crate::get_challenges::observe_public_values;
use crate::lookup::{lookup_helper_columns, Lookup, LookupCheckVars};
use crate::proof::{AllProof, PublicValues, StarkOpeningSet, StarkProof, StarkProofWithMetadata};
use crate::stark::Stark;
use crate::vanishing_poly::eval_vanishing_poly;

/*
/// Generate traces, then create all STARK proofs.
pub fn prove<F, C, const D: usize>(
all_stark: &AllStark<F, D>,
Expand Down Expand Up @@ -73,7 +72,6 @@ where
let proof = prove_with_traces(all_stark, config, traces, public_values, timing)?;
Ok((proof, outputs))
}
*/

/// Compute all STARK proofs.
pub(crate) fn prove_with_traces<F, C, const D: usize>(
Expand Down

0 comments on commit 77799fd

Please sign in to comment.