Skip to content

Commit

Permalink
Write trie roots to memory before kernel bootstrapping (#1172)
Browse files Browse the repository at this point in the history
* Write trie roots

* Remove CPU trace length

* Update hash_initial/final_tries

* Fix tests

* Minor

* PR feedback
  • Loading branch information
wborgeaud authored Aug 9, 2023
1 parent c9eed2b commit df07ae0
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 228 deletions.
12 changes: 6 additions & 6 deletions evm/src/cpu/kernel/asm/main.asm
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ global main:
%jump(load_all_mpts)

global hash_initial_tries:
%mpt_hash_state_trie %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE)
%mpt_hash_txn_trie %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE)
%mpt_hash_receipt_trie %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE)
%mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq
%mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE) %assert_eq
%mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE) %assert_eq

global txn_loop:
// If the prover has no more txns for us to process, halt.
Expand All @@ -21,7 +21,7 @@ global txn_loop:
%jump(route_txn)

global hash_final_tries:
%mpt_hash_state_trie %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER)
%mpt_hash_txn_trie %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER)
%mpt_hash_receipt_trie %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER)
%mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) %assert_eq
%mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq
%mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER) %assert_eq
%jump(halt)
21 changes: 4 additions & 17 deletions evm/src/fixed_recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use crate::keccak_sponge::keccak_sponge_stark::KeccakSpongeStark;
use crate::logic::LogicStark;
use crate::memory::memory_stark::MemoryStark;
use crate::memory::segments::Segment;
use crate::memory::{NUM_CHANNELS, VALUE_LIMBS};
use crate::memory::VALUE_LIMBS;
use crate::permutation::{
get_grand_product_challenge_set_target, GrandProductChallenge, GrandProductChallengeSet,
};
Expand Down Expand Up @@ -647,7 +647,7 @@ where
prod = builder.mul(prod, combined);
});

// Add public values reads.
// Add trie roots writes.
let trie_fields = [
(
GlobalMetadata::StateTrieRootDigestBefore,
Expand Down Expand Up @@ -675,15 +675,10 @@ where
),
];

let mut timestamp_target = builder.mul_const(
F::from_canonical_usize(NUM_CHANNELS),
public_values.cpu_trace_len,
);
timestamp_target = builder.add_const(timestamp_target, F::ONE);
trie_fields.map(|(field, targets)| {
let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], one);
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// segment
Expand All @@ -696,7 +691,7 @@ where
builder.connect(row[4 + j], targets[j]);
}
// timestamp
builder.connect(row[12], timestamp_target);
builder.connect(row[12], one);

let combined = challenge.combine_base_circuit(builder, &row);
prod = builder.mul(prod, combined);
Expand Down Expand Up @@ -909,10 +904,6 @@ where
&public_values.block_metadata,
);

agg_inputs.set_target(
self.aggregation.public_values.cpu_trace_len,
F::from_canonical_usize(public_values.cpu_trace_len),
);
set_trie_roots_target(
&mut agg_inputs,
&self.aggregation.public_values.trie_roots_before,
Expand Down Expand Up @@ -977,10 +968,6 @@ where
&public_values.block_metadata,
);

block_inputs.set_target(
self.block.public_values.cpu_trace_len,
F::from_canonical_usize(public_values.cpu_trace_len),
);
set_trie_roots_target(
&mut block_inputs,
&self.block.public_values.trie_roots_before,
Expand Down
63 changes: 21 additions & 42 deletions evm/src/generation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;

use eth_trie_utils::partial_trie::HashedPartialTrie;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, BigEndianHash, H256, U256};
use plonky2::field::extension::Extendable;
use plonky2::field::polynomial::PolynomialValues;
Expand All @@ -22,7 +22,8 @@ use crate::generation::outputs::{get_outputs, GenerationOutputs};
use crate::generation::state::GenerationState;
use crate::memory::segments::Segment;
use crate::proof::{BlockMetadata, PublicValues, TrieRoots};
use crate::witness::memory::{MemoryAddress, MemoryChannel, MemoryOp, MemoryOpKind};
use crate::util::h2u;
use crate::witness::memory::{MemoryAddress, MemoryChannel};
use crate::witness::transition::transition;

pub mod mpt;
Expand All @@ -39,6 +40,8 @@ use crate::witness::util::mem_write_log;
pub struct GenerationInputs {
pub signed_txns: Vec<Vec<u8>>,
pub tries: TrieInputs,
/// Expected trie roots after the transactions are executed.
pub trie_roots_after: TrieRoots,

/// Mapping between smart contract code hashes and the contract byte code.
/// All account smart contracts that are invoked will have an entry present.
Expand Down Expand Up @@ -73,10 +76,13 @@ pub struct TrieInputs {
pub storage_tries: Vec<(H256, HashedPartialTrie)>,
}

fn apply_metadata_memops<F: RichField + Extendable<D>, const D: usize>(
fn apply_metadata_and_tries_memops<F: RichField + Extendable<D>, const D: usize>(
state: &mut GenerationState<F>,
metadata: &BlockMetadata,
inputs: &GenerationInputs,
) {
let metadata = &inputs.block_metadata;
let tries = &inputs.tries;
let trie_roots_after = &inputs.trie_roots_after;
let fields = [
(
GlobalMetadata::BlockBeneficiary,
Expand All @@ -88,67 +94,43 @@ fn apply_metadata_memops<F: RichField + Extendable<D>, const D: usize>(
(GlobalMetadata::BlockGasLimit, metadata.block_gaslimit),
(GlobalMetadata::BlockChainId, metadata.block_chain_id),
(GlobalMetadata::BlockBaseFee, metadata.block_base_fee),
];

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

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

fn apply_trie_memops<F: RichField + Extendable<D>, const D: usize>(
state: &mut GenerationState<F>,
trie_roots_before: &TrieRoots,
trie_roots_after: &TrieRoots,
) {
let fields = [
(
GlobalMetadata::StateTrieRootDigestBefore,
trie_roots_before.state_root,
h2u(tries.state_trie.hash()),
),
(
GlobalMetadata::TransactionTrieRootDigestBefore,
trie_roots_before.transactions_root,
h2u(tries.transactions_trie.hash()),
),
(
GlobalMetadata::ReceiptTrieRootDigestBefore,
trie_roots_before.receipts_root,
h2u(tries.receipts_trie.hash()),
),
(
GlobalMetadata::StateTrieRootDigestAfter,
trie_roots_after.state_root,
h2u(trie_roots_after.state_root),
),
(
GlobalMetadata::TransactionTrieRootDigestAfter,
trie_roots_after.transactions_root,
h2u(trie_roots_after.transactions_root),
),
(
GlobalMetadata::ReceiptTrieRootDigestAfter,
trie_roots_after.receipts_root,
h2u(trie_roots_after.receipts_root),
),
];

let channel = MemoryChannel::GeneralPurpose(0);

let ops = fields.map(|(field, hash)| {
let val = hash.into_uint();
MemoryOp::new(
let ops = fields.map(|(field, val)| {
mem_write_log(
channel,
state.traces.cpu.len(),
MemoryAddress::new(0, Segment::GlobalMetadata, field as usize),
MemoryOpKind::Read,
state,
val,
)
});

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

Expand All @@ -164,7 +146,7 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
)> {
let mut state = GenerationState::<F>::new(inputs.clone(), &KERNEL.code);

apply_metadata_memops(&mut state, &inputs.block_metadata);
apply_metadata_and_tries_memops(&mut state, &inputs);

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

Expand Down Expand Up @@ -194,13 +176,10 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
receipts_root: H256::from_uint(&read_metadata(ReceiptTrieRootDigestAfter)),
};

apply_trie_memops(&mut state, &trie_roots_before, &trie_roots_after);

let public_values = PublicValues {
trie_roots_before,
trie_roots_after,
block_metadata: inputs.block_metadata,
cpu_trace_len: state.traces.clock(),
};

let tables = timed!(
Expand Down
11 changes: 1 addition & 10 deletions evm/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ pub struct PublicValues {
pub trie_roots_before: TrieRoots,
pub trie_roots_after: TrieRoots,
pub block_metadata: BlockMetadata,
pub cpu_trace_len: usize,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
Expand Down Expand Up @@ -81,7 +80,6 @@ pub struct PublicValuesTarget {
pub trie_roots_before: TrieRootsTarget,
pub trie_roots_after: TrieRootsTarget,
pub block_metadata: BlockMetadataTarget,
pub cpu_trace_len: Target,
}

impl PublicValuesTarget {
Expand Down Expand Up @@ -124,8 +122,6 @@ impl PublicValuesTarget {
buffer.write_target(block_chain_id)?;
buffer.write_target(block_base_fee)?;

buffer.write_target(self.cpu_trace_len)?;

Ok(())
}

Expand All @@ -152,18 +148,15 @@ impl PublicValuesTarget {
block_base_fee: buffer.read_target()?,
};

let cpu_trace_len = buffer.read_target()?;

Ok(Self {
trie_roots_before,
trie_roots_after,
block_metadata,
cpu_trace_len,
})
}

pub fn from_public_inputs(pis: &[Target]) -> Self {
assert!(pis.len() > TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE);
assert!(pis.len() > TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE - 1);
Self {
trie_roots_before: TrieRootsTarget::from_public_inputs(&pis[0..TrieRootsTarget::SIZE]),
trie_roots_after: TrieRootsTarget::from_public_inputs(
Expand All @@ -173,7 +166,6 @@ impl PublicValuesTarget {
&pis[TrieRootsTarget::SIZE * 2
..TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE],
),
cpu_trace_len: pis[TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE],
}
}

Expand Down Expand Up @@ -202,7 +194,6 @@ impl PublicValuesTarget {
pv0.block_metadata,
pv1.block_metadata,
),
cpu_trace_len: builder.select(condition, pv0.cpu_trace_len, pv1.cpu_trace_len),
}
}
}
Expand Down
6 changes: 0 additions & 6 deletions evm/src/recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,10 @@ pub(crate) fn add_virtual_public_values<F: RichField + Extendable<D>, const D: u
let trie_roots_before = add_virtual_trie_roots(builder);
let trie_roots_after = add_virtual_trie_roots(builder);
let block_metadata = add_virtual_block_metadata(builder);
let cpu_trace_len = builder.add_virtual_public_input();
PublicValuesTarget {
trie_roots_before,
trie_roots_after,
block_metadata,
cpu_trace_len,
}
}

Expand Down Expand Up @@ -659,10 +657,6 @@ pub(crate) fn set_public_value_targets<F, W, const D: usize>(
&public_values_target.block_metadata,
&public_values.block_metadata,
);
witness.set_target(
public_values_target.cpu_trace_len,
F::from_canonical_usize(public_values.cpu_trace_len),
);
}

pub(crate) fn set_trie_roots_target<F, W, const D: usize>(
Expand Down
4 changes: 4 additions & 0 deletions evm/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,7 @@ pub(crate) fn biguint_to_mem_vec(x: BigUint) -> Vec<U256> {
}
mem_vec
}

pub(crate) fn h2u(h: H256) -> U256 {
U256::from_big_endian(&h.0)
}
Loading

0 comments on commit df07ae0

Please sign in to comment.