mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-02-24 07:43:11 +00:00
Write trie roots to memory before kernel bootstrapping (#1172)
* Write trie roots * Remove CPU trace length * Update hash_initial/final_tries * Fix tests * Minor * PR feedback
This commit is contained in:
parent
c9eed2bbf9
commit
df07ae093a
@ -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.
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
};
|
||||
@ -647,7 +647,7 @@ where
|
||||
prod = builder.mul(prod, combined);
|
||||
});
|
||||
|
||||
// Add public values reads.
|
||||
// Add trie roots writes.
|
||||
let trie_fields = [
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestBefore,
|
||||
@ -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
|
||||
@ -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);
|
||||
@ -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,
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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.
|
||||
@ -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,
|
||||
@ -88,6 +94,30 @@ 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),
|
||||
(
|
||||
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);
|
||||
@ -104,54 +134,6 @@ fn apply_metadata_memops<F: RichField + Extendable<D>, const D: usize>(
|
||||
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,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestBefore,
|
||||
trie_roots_before.transactions_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestBefore,
|
||||
trie_roots_before.receipts_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestAfter,
|
||||
trie_roots_after.state_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestAfter,
|
||||
trie_roots_after.transactions_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestAfter,
|
||||
trie_roots_after.receipts_root,
|
||||
),
|
||||
];
|
||||
|
||||
let channel = MemoryChannel::GeneralPurpose(0);
|
||||
|
||||
let ops = fields.map(|(field, hash)| {
|
||||
let val = hash.into_uint();
|
||||
MemoryOp::new(
|
||||
channel,
|
||||
state.traces.cpu.len(),
|
||||
MemoryAddress::new(0, Segment::GlobalMetadata, field as usize),
|
||||
MemoryOpKind::Read,
|
||||
val,
|
||||
)
|
||||
});
|
||||
|
||||
state.traces.memory_ops.extend(ops);
|
||||
}
|
||||
|
||||
pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
|
||||
all_stark: &AllStark<F, D>,
|
||||
inputs: GenerationInputs,
|
||||
@ -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);
|
||||
|
||||
@ -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!(
|
||||
|
||||
@ -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)]
|
||||
@ -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 {
|
||||
@ -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(())
|
||||
}
|
||||
|
||||
@ -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(
|
||||
@ -173,7 +166,6 @@ impl PublicValuesTarget {
|
||||
&pis[TrieRootsTarget::SIZE * 2
|
||||
..TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE],
|
||||
),
|
||||
cpu_trace_len: pis[TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE],
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>(
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::any::type_name;
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
use ethereum_types::{BigEndianHash, U256};
|
||||
use ethereum_types::U256;
|
||||
use plonky2::field::extension::{Extendable, FieldExtension};
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::fri::verifier::verify_fri_proof;
|
||||
@ -21,12 +21,13 @@ 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::{GrandProductChallenge, PermutationCheckVars};
|
||||
use crate::proof::{
|
||||
AllProof, AllProofChallenges, PublicValues, StarkOpeningSet, StarkProof, StarkProofChallenges,
|
||||
};
|
||||
use crate::stark::Stark;
|
||||
use crate::util::h2u;
|
||||
use crate::vanishing_poly::eval_vanishing_poly;
|
||||
use crate::vars::StarkEvaluationVars;
|
||||
|
||||
@ -118,11 +119,9 @@ where
|
||||
|
||||
// Memory
|
||||
extra_looking_products.push(Vec::new());
|
||||
let cpu_trace_len = 1 << all_proof.stark_proofs[1].proof.recover_degree_bits(config);
|
||||
for c in 0..config.num_challenges {
|
||||
extra_looking_products[Table::Memory as usize].push(get_memory_extra_looking_products(
|
||||
&public_values,
|
||||
cpu_trace_len,
|
||||
ctl_challenges.challenges[c],
|
||||
));
|
||||
}
|
||||
@ -137,10 +136,9 @@ where
|
||||
|
||||
/// Computes the extra product to multiply to the looked value. It contains memory operations not in the CPU trace:
|
||||
/// - block metadata writes before kernel bootstrapping,
|
||||
/// - public values reads at the end of the execution.
|
||||
/// - trie roots writes before kernel bootstrapping.
|
||||
pub(crate) fn get_memory_extra_looking_products<F, const D: usize>(
|
||||
public_values: &PublicValues,
|
||||
cpu_trace_len: usize,
|
||||
challenge: GrandProductChallenge<F>,
|
||||
) -> F
|
||||
where
|
||||
@ -148,8 +146,8 @@ where
|
||||
{
|
||||
let mut prod = F::ONE;
|
||||
|
||||
// Add metadata writes.
|
||||
let block_fields = [
|
||||
// Add metadata and tries writes.
|
||||
let fields = [
|
||||
(
|
||||
GlobalMetadata::BlockBeneficiary,
|
||||
U256::from_big_endian(&public_values.block_metadata.block_beneficiary.0),
|
||||
@ -178,13 +176,37 @@ where
|
||||
GlobalMetadata::BlockBaseFee,
|
||||
public_values.block_metadata.block_base_fee,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestBefore,
|
||||
h2u(public_values.trie_roots_before.state_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestBefore,
|
||||
h2u(public_values.trie_roots_before.transactions_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestBefore,
|
||||
h2u(public_values.trie_roots_before.receipts_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestAfter,
|
||||
h2u(public_values.trie_roots_after.state_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestAfter,
|
||||
h2u(public_values.trie_roots_after.transactions_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestAfter,
|
||||
h2u(public_values.trie_roots_after.receipts_root),
|
||||
),
|
||||
];
|
||||
let is_read = F::ZERO;
|
||||
let context = F::ZERO;
|
||||
let segment = F::from_canonical_u32(Segment::GlobalMetadata as u32);
|
||||
let timestamp = F::ONE;
|
||||
|
||||
block_fields.map(|(field, val)| {
|
||||
fields.map(|(field, val)| {
|
||||
let mut row = vec![F::ZERO; 13];
|
||||
row[0] = is_read;
|
||||
row[1] = context;
|
||||
@ -198,51 +220,6 @@ where
|
||||
prod *= challenge.combine(row.iter());
|
||||
});
|
||||
|
||||
// Add public values reads.
|
||||
let trie_fields = [
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestBefore,
|
||||
public_values.trie_roots_before.state_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestBefore,
|
||||
public_values.trie_roots_before.transactions_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestBefore,
|
||||
public_values.trie_roots_before.receipts_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestAfter,
|
||||
public_values.trie_roots_after.state_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestAfter,
|
||||
public_values.trie_roots_after.transactions_root,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestAfter,
|
||||
public_values.trie_roots_after.receipts_root,
|
||||
),
|
||||
];
|
||||
let is_read = F::ONE;
|
||||
let timestamp = F::from_canonical_usize(cpu_trace_len * NUM_CHANNELS + 1);
|
||||
|
||||
trie_fields.map(|(field, hash)| {
|
||||
let mut row = vec![F::ZERO; 13];
|
||||
row[0] = is_read;
|
||||
row[1] = context;
|
||||
row[2] = segment;
|
||||
row[3] = F::from_canonical_usize(field as usize);
|
||||
|
||||
let val = hash.into_uint();
|
||||
|
||||
for j in 0..VALUE_LIMBS {
|
||||
row[j + 4] = F::from_canonical_u32((val >> (j * 32)).low_u32());
|
||||
}
|
||||
row[12] = timestamp;
|
||||
prod *= challenge.combine(row.iter());
|
||||
});
|
||||
prod
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ use plonky2_evm::all_stark::AllStark;
|
||||
use plonky2_evm::config::StarkConfig;
|
||||
use plonky2_evm::generation::mpt::AccountRlp;
|
||||
use plonky2_evm::generation::{GenerationInputs, TrieInputs};
|
||||
use plonky2_evm::proof::BlockMetadata;
|
||||
use plonky2_evm::proof::{BlockMetadata, TrieRoots};
|
||||
use plonky2_evm::prover::prove;
|
||||
use plonky2_evm::verifier::verify_proof;
|
||||
use plonky2_evm::Node;
|
||||
@ -91,9 +91,47 @@ fn add11_yml() -> anyhow::Result<()> {
|
||||
contract_code.insert(keccak(vec![]), vec![]);
|
||||
contract_code.insert(code_hash, code.to_vec());
|
||||
|
||||
let expected_state_trie_after = {
|
||||
let beneficiary_account_after = AccountRlp {
|
||||
nonce: 1.into(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
let sender_account_after = AccountRlp {
|
||||
balance: 0xde0b6b3a75be550u64.into(),
|
||||
nonce: 1.into(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
let to_account_after = AccountRlp {
|
||||
balance: 0xde0b6b3a76586a0u64.into(),
|
||||
code_hash,
|
||||
// Storage map: { 0 => 2 }
|
||||
storage_root: HashedPartialTrie::from(Node::Leaf {
|
||||
nibbles: Nibbles::from_h256_be(keccak([0u8; 32])),
|
||||
value: vec![2],
|
||||
})
|
||||
.hash(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
|
||||
let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty);
|
||||
expected_state_trie_after.insert(
|
||||
beneficiary_nibbles,
|
||||
rlp::encode(&beneficiary_account_after).to_vec(),
|
||||
);
|
||||
expected_state_trie_after
|
||||
.insert(sender_nibbles, rlp::encode(&sender_account_after).to_vec());
|
||||
expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec());
|
||||
expected_state_trie_after
|
||||
};
|
||||
let trie_roots_after = TrieRoots {
|
||||
state_root: expected_state_trie_after.hash(),
|
||||
transactions_root: tries_before.transactions_trie.hash(), // TODO: Fix this when we have transactions trie.
|
||||
receipts_root: tries_before.receipts_trie.hash(), // TODO: Fix this when we have receipts trie.
|
||||
};
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
@ -103,40 +141,6 @@ fn add11_yml() -> anyhow::Result<()> {
|
||||
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
|
||||
timing.filter(Duration::from_millis(100)).print();
|
||||
|
||||
let beneficiary_account_after = AccountRlp {
|
||||
nonce: 1.into(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
let sender_account_after = AccountRlp {
|
||||
balance: 0xde0b6b3a75be550u64.into(),
|
||||
nonce: 1.into(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
let to_account_after = AccountRlp {
|
||||
balance: 0xde0b6b3a76586a0u64.into(),
|
||||
code_hash,
|
||||
// Storage map: { 0 => 2 }
|
||||
storage_root: HashedPartialTrie::from(Node::Leaf {
|
||||
nibbles: Nibbles::from_h256_be(keccak([0u8; 32])),
|
||||
value: vec![2],
|
||||
})
|
||||
.hash(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
|
||||
let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty);
|
||||
expected_state_trie_after.insert(
|
||||
beneficiary_nibbles,
|
||||
rlp::encode(&beneficiary_account_after).to_vec(),
|
||||
);
|
||||
expected_state_trie_after.insert(sender_nibbles, rlp::encode(&sender_account_after).to_vec());
|
||||
expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec());
|
||||
|
||||
assert_eq!(
|
||||
proof.public_values.trie_roots_after.state_root,
|
||||
expected_state_trie_after.hash()
|
||||
);
|
||||
|
||||
verify_proof(&all_stark, proof, &config)
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ use plonky2_evm::config::StarkConfig;
|
||||
use plonky2_evm::cpu::kernel::opcodes::{get_opcode, get_push_opcode};
|
||||
use plonky2_evm::generation::mpt::AccountRlp;
|
||||
use plonky2_evm::generation::{GenerationInputs, TrieInputs};
|
||||
use plonky2_evm::proof::BlockMetadata;
|
||||
use plonky2_evm::proof::{BlockMetadata, TrieRoots};
|
||||
use plonky2_evm::prover::prove;
|
||||
use plonky2_evm::verifier::verify_proof;
|
||||
use plonky2_evm::Node;
|
||||
@ -102,18 +102,6 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
contract_code.insert(keccak(vec![]), vec![]);
|
||||
contract_code.insert(code_hash, code.to_vec());
|
||||
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
tries: tries_before,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
};
|
||||
|
||||
let mut timing = TimingTree::new("prove", log::Level::Debug);
|
||||
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
|
||||
timing.filter(Duration::from_millis(100)).print();
|
||||
|
||||
let expected_state_trie_after: HashedPartialTrie = {
|
||||
let txdata_gas = 2 * 16;
|
||||
let gas_used = 21_000 + code_gas + txdata_gas;
|
||||
@ -154,11 +142,23 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
.into();
|
||||
let trie_roots_after = TrieRoots {
|
||||
state_root: expected_state_trie_after.hash(),
|
||||
transactions_root: tries_before.transactions_trie.hash(), // TODO: Fix this when we have transactions trie.
|
||||
receipts_root: tries_before.receipts_trie.hash(), // TODO: Fix this when we have receipts trie.
|
||||
};
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
proof.public_values.trie_roots_after.state_root,
|
||||
expected_state_trie_after.hash()
|
||||
);
|
||||
let mut timing = TimingTree::new("prove", log::Level::Debug);
|
||||
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
|
||||
timing.filter(Duration::from_millis(100)).print();
|
||||
|
||||
verify_proof(&all_stark, proof, &config)
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::marker::PhantomData;
|
||||
use std::time::Duration;
|
||||
|
||||
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
|
||||
use eth_trie_utils::partial_trie::HashedPartialTrie;
|
||||
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
|
||||
use keccak_hash::keccak;
|
||||
use log::info;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
@ -14,7 +14,7 @@ use plonky2_evm::all_stark::AllStark;
|
||||
use plonky2_evm::config::StarkConfig;
|
||||
use plonky2_evm::fixed_recursive_verifier::AllRecursiveCircuits;
|
||||
use plonky2_evm::generation::{GenerationInputs, TrieInputs};
|
||||
use plonky2_evm::proof::BlockMetadata;
|
||||
use plonky2_evm::proof::{BlockMetadata, TrieRoots};
|
||||
use plonky2_evm::Node;
|
||||
|
||||
type F = GoldilocksField;
|
||||
@ -40,6 +40,12 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
let mut contract_code = HashMap::new();
|
||||
contract_code.insert(keccak(vec![]), vec![]);
|
||||
|
||||
// No transactions, so no trie roots change.
|
||||
let trie_roots_after = TrieRoots {
|
||||
state_root: state_trie.hash(),
|
||||
transactions_root: transactions_trie.hash(),
|
||||
receipts_root: receipts_trie.hash(),
|
||||
};
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![],
|
||||
tries: TrieInputs {
|
||||
@ -48,6 +54,7 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
receipts_trie,
|
||||
storage_tries,
|
||||
},
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
|
||||
@ -15,7 +15,7 @@ use plonky2_evm::all_stark::AllStark;
|
||||
use plonky2_evm::config::StarkConfig;
|
||||
use plonky2_evm::generation::mpt::AccountRlp;
|
||||
use plonky2_evm::generation::{GenerationInputs, TrieInputs};
|
||||
use plonky2_evm::proof::BlockMetadata;
|
||||
use plonky2_evm::proof::{BlockMetadata, TrieRoots};
|
||||
use plonky2_evm::prover::prove;
|
||||
use plonky2_evm::verifier::verify_proof;
|
||||
use plonky2_evm::Node;
|
||||
@ -87,9 +87,48 @@ fn self_balance_gas_cost() -> anyhow::Result<()> {
|
||||
contract_code.insert(keccak(vec![]), vec![]);
|
||||
contract_code.insert(code_hash, code.to_vec());
|
||||
|
||||
let expected_state_trie_after = {
|
||||
let beneficiary_account_after = AccountRlp::default();
|
||||
let sender_account_after = AccountRlp {
|
||||
balance: 999999999999999568680u128.into(),
|
||||
nonce: 1.into(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
let to_account_after = AccountRlp {
|
||||
code_hash,
|
||||
// Storage map: { 1 => 5 }
|
||||
storage_root: HashedPartialTrie::from(Node::Leaf {
|
||||
// TODO: Could do keccak(pad32(1))
|
||||
nibbles: Nibbles::from_str(
|
||||
"0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6",
|
||||
)
|
||||
.unwrap(),
|
||||
value: vec![5],
|
||||
})
|
||||
.hash(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
|
||||
let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty);
|
||||
expected_state_trie_after.insert(
|
||||
beneficiary_nibbles,
|
||||
rlp::encode(&beneficiary_account_after).to_vec(),
|
||||
);
|
||||
expected_state_trie_after
|
||||
.insert(sender_nibbles, rlp::encode(&sender_account_after).to_vec());
|
||||
expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec());
|
||||
expected_state_trie_after
|
||||
};
|
||||
|
||||
let trie_roots_after = TrieRoots {
|
||||
state_root: expected_state_trie_after.hash(),
|
||||
transactions_root: tries_before.transactions_trie.hash(), // TODO: Fix this when we have transactions trie.
|
||||
receipts_root: tries_before.receipts_trie.hash(), // TODO: Fix this when we have receipts trie.
|
||||
};
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
@ -99,40 +138,6 @@ fn self_balance_gas_cost() -> anyhow::Result<()> {
|
||||
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
|
||||
timing.filter(Duration::from_millis(100)).print();
|
||||
|
||||
let beneficiary_account_after = AccountRlp::default();
|
||||
let sender_account_after = AccountRlp {
|
||||
balance: 999999999999999568680u128.into(),
|
||||
nonce: 1.into(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
let to_account_after = AccountRlp {
|
||||
code_hash,
|
||||
// Storage map: { 1 => 5 }
|
||||
storage_root: HashedPartialTrie::from(Node::Leaf {
|
||||
// TODO: Could do keccak(pad32(1))
|
||||
nibbles: Nibbles::from_str(
|
||||
"0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6",
|
||||
)
|
||||
.unwrap(),
|
||||
value: vec![5],
|
||||
})
|
||||
.hash(),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
|
||||
let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty);
|
||||
expected_state_trie_after.insert(
|
||||
beneficiary_nibbles,
|
||||
rlp::encode(&beneficiary_account_after).to_vec(),
|
||||
);
|
||||
expected_state_trie_after.insert(sender_nibbles, rlp::encode(&sender_account_after).to_vec());
|
||||
expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec());
|
||||
|
||||
assert_eq!(
|
||||
proof.public_values.trie_roots_after.state_root,
|
||||
expected_state_trie_after.hash()
|
||||
);
|
||||
|
||||
verify_proof(&all_stark, proof, &config)
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ use plonky2_evm::all_stark::AllStark;
|
||||
use plonky2_evm::config::StarkConfig;
|
||||
use plonky2_evm::generation::mpt::AccountRlp;
|
||||
use plonky2_evm::generation::{GenerationInputs, TrieInputs};
|
||||
use plonky2_evm::proof::BlockMetadata;
|
||||
use plonky2_evm::proof::{BlockMetadata, TrieRoots};
|
||||
use plonky2_evm::prover::prove;
|
||||
use plonky2_evm::verifier::verify_proof;
|
||||
use plonky2_evm::Node;
|
||||
@ -78,18 +78,6 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
let mut contract_code = HashMap::new();
|
||||
contract_code.insert(keccak(vec![]), vec![]);
|
||||
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
tries: tries_before,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
};
|
||||
|
||||
let mut timing = TimingTree::new("prove", log::Level::Debug);
|
||||
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
|
||||
timing.filter(Duration::from_millis(100)).print();
|
||||
|
||||
let expected_state_trie_after: HashedPartialTrie = {
|
||||
let txdata_gas = 2 * 16;
|
||||
let gas_used = 21_000 + txdata_gas;
|
||||
@ -121,11 +109,23 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
}
|
||||
.into()
|
||||
};
|
||||
let trie_roots_after = TrieRoots {
|
||||
state_root: expected_state_trie_after.hash(),
|
||||
transactions_root: tries_before.transactions_trie.hash(), // TODO: Fix this when we have transactions trie.
|
||||
receipts_root: tries_before.receipts_trie.hash(), // TODO: Fix this when we have receipts trie.
|
||||
};
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
addresses: vec![],
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
proof.public_values.trie_roots_after.state_root,
|
||||
expected_state_trie_after.hash()
|
||||
);
|
||||
let mut timing = TimingTree::new("prove", log::Level::Debug);
|
||||
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
|
||||
timing.filter(Duration::from_millis(100)).print();
|
||||
|
||||
verify_proof(&all_stark, proof, &config)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user