Merge pull request #1208 from topos-protocol/blockhash_opcode

Add blockhash opcode
This commit is contained in:
Linda Guiga 2023-09-07 23:21:37 +01:00 committed by GitHub
commit 180c20942b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 526 additions and 58 deletions

View File

@ -1,14 +1,6 @@
// Labels for unimplemented syscalls to make the kernel assemble. // Labels for unimplemented syscalls to make the kernel assemble.
// Each label should be removed from this file once it is implemented. // Each label should be removed from this file once it is implemented.
// This is a temporary version that returns 0 on all inputs.
// TODO: Fix this.
global sys_blockhash:
// stack: kexit_info, block_number
%charge_gas_const(@GAS_BLOCKHASH)
%stack (kexit_info, block_number) -> (kexit_info, 0)
EXIT_KERNEL
// This is a temporary version that returns the block difficulty (i.e. the old version of this opcode). // This is a temporary version that returns the block difficulty (i.e. the old version of this opcode).
// TODO: Fix this. // TODO: Fix this.
// TODO: What semantics will this have for Edge? // TODO: What semantics will this have for Edge?

View File

@ -235,6 +235,48 @@ global sys_basefee:
SWAP1 SWAP1
EXIT_KERNEL EXIT_KERNEL
global sys_blockhash:
// stack: kexit_info, block_number
%charge_gas_const(@GAS_BLOCKHASH)
SWAP1
// stack: block_number, kexit_info
%blockhash
EXIT_KERNEL
global blockhash:
// stack: block_number, retdest
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_NUMBER)
// stack: cur_block_number, block_number, retdest
// Check for an overflow, since we're incrementing `block_number` afterwards.
DUP2 %eq_const(@U256_MAX) %jumpi(zero_hash)
// stack: cur_block_number, block_number, retdest
DUP1 DUP3 %increment GT %jumpi(zero_hash) // if block_number >= cur_block_number
// stack: cur_block_number, block_number, retdest
DUP2 PUSH 256 ADD
// stack: block_number+256, cur_block_number, block_number, retdest
DUP2 GT %jumpi(zero_hash) // if cur_block_number > block_number + 256
// If we are here, the provided block number is correct
SUB
// stack: cur_block_number - block_number, retdest
PUSH 256 SUB
// stack: block_hash_number, retdest
%mload_kernel(@SEGMENT_BLOCK_HASHES)
SWAP1 JUMP
JUMP
%macro blockhash
// stack: block_number
%stack (block_number) -> (block_number, %%after)
%jump(blockhash)
%%after:
%endmacro
zero_hash:
// stack: cur_block_number, block_number, retdest
%pop2
PUSH 0 SWAP1
JUMP
%macro update_mem_words %macro update_mem_words
// stack: num_words, kexit_info // stack: num_words, kexit_info
%mem_words %mem_words

View File

@ -47,44 +47,47 @@ pub(crate) enum GlobalMetadata {
BlockGasUsedBefore = 22, BlockGasUsedBefore = 22,
/// After current transactions block values. /// After current transactions block values.
BlockGasUsedAfter = 23, BlockGasUsedAfter = 23,
/// Current block header hash
BlockCurrentHash = 24,
/// Gas to refund at the end of the transaction. /// Gas to refund at the end of the transaction.
RefundCounter = 24, RefundCounter = 25,
/// Length of the addresses access list. /// Length of the addresses access list.
AccessedAddressesLen = 25, AccessedAddressesLen = 26,
/// Length of the storage keys access list. /// Length of the storage keys access list.
AccessedStorageKeysLen = 26, AccessedStorageKeysLen = 27,
/// Length of the self-destruct list. /// Length of the self-destruct list.
SelfDestructListLen = 27, SelfDestructListLen = 28,
/// Length of the bloom entry buffer. /// Length of the bloom entry buffer.
BloomEntryLen = 28, BloomEntryLen = 29,
/// Length of the journal. /// Length of the journal.
JournalLen = 29, JournalLen = 30,
/// Length of the `JournalData` segment. /// Length of the `JournalData` segment.
JournalDataLen = 30, JournalDataLen = 31,
/// Current checkpoint. /// Current checkpoint.
CurrentCheckpoint = 31, CurrentCheckpoint = 32,
TouchedAddressesLen = 32, TouchedAddressesLen = 33,
// Gas cost for the access list in type-1 txns. See EIP-2930. // Gas cost for the access list in type-1 txns. See EIP-2930.
AccessListDataCost = 33, AccessListDataCost = 34,
// Start of the access list in the RLP for type-1 txns. // Start of the access list in the RLP for type-1 txns.
AccessListRlpStart = 34, AccessListRlpStart = 35,
// Length of the access list in the RLP for type-1 txns. // Length of the access list in the RLP for type-1 txns.
AccessListRlpLen = 35, AccessListRlpLen = 36,
// Boolean flag indicating if the txn is a contract creation txn. // Boolean flag indicating if the txn is a contract creation txn.
ContractCreation = 36, ContractCreation = 37,
IsPrecompileFromEoa = 37, IsPrecompileFromEoa = 38,
CallStackDepth = 38, CallStackDepth = 39,
/// Transaction logs list length. /// Transaction logs list length
LogsLen = 39, LogsLen = 40,
LogsDataLen = 40, LogsDataLen = 41,
LogsPayloadLen = 41, LogsPayloadLen = 42,
TxnNumberBefore = 42, TxnNumberBefore = 43,
TxnNumberAfter = 43, TxnNumberAfter = 44,
} }
impl GlobalMetadata { impl GlobalMetadata {
pub(crate) const COUNT: usize = 44; pub(crate) const COUNT: usize = 45;
pub(crate) fn all() -> [Self; Self::COUNT] { pub(crate) fn all() -> [Self; Self::COUNT] {
[ [
@ -130,6 +133,7 @@ impl GlobalMetadata {
Self::LogsLen, Self::LogsLen,
Self::LogsDataLen, Self::LogsDataLen,
Self::LogsPayloadLen, Self::LogsPayloadLen,
Self::BlockCurrentHash,
Self::TxnNumberBefore, Self::TxnNumberBefore,
Self::TxnNumberAfter, Self::TxnNumberAfter,
] ]
@ -162,6 +166,7 @@ impl GlobalMetadata {
Self::BlockGasUsed => "GLOBAL_METADATA_BLOCK_GAS_USED", Self::BlockGasUsed => "GLOBAL_METADATA_BLOCK_GAS_USED",
Self::BlockGasUsedBefore => "GLOBAL_METADATA_BLOCK_GAS_USED_BEFORE", Self::BlockGasUsedBefore => "GLOBAL_METADATA_BLOCK_GAS_USED_BEFORE",
Self::BlockGasUsedAfter => "GLOBAL_METADATA_BLOCK_GAS_USED_AFTER", Self::BlockGasUsedAfter => "GLOBAL_METADATA_BLOCK_GAS_USED_AFTER",
Self::BlockCurrentHash => "GLOBAL_METADATA_BLOCK_CURRENT_HASH",
Self::RefundCounter => "GLOBAL_METADATA_REFUND_COUNTER", Self::RefundCounter => "GLOBAL_METADATA_REFUND_COUNTER",
Self::AccessedAddressesLen => "GLOBAL_METADATA_ACCESSED_ADDRESSES_LEN", Self::AccessedAddressesLen => "GLOBAL_METADATA_ACCESSED_ADDRESSES_LEN",
Self::AccessedStorageKeysLen => "GLOBAL_METADATA_ACCESSED_STORAGE_KEYS_LEN", Self::AccessedStorageKeysLen => "GLOBAL_METADATA_ACCESSED_STORAGE_KEYS_LEN",

View File

@ -0,0 +1,125 @@
use anyhow::Result;
use ethereum_types::{H256, U256};
use rand::{thread_rng, Rng};
use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::cpu::kernel::interpreter::Interpreter;
use crate::memory::segments::Segment;
#[test]
fn test_correct_block_hash() -> Result<()> {
let mut rng = rand::thread_rng();
let blockhash_label = KERNEL.global_labels["blockhash"];
let retdest = 0xDEADBEEFu32.into();
let block_number: u8 = rng.gen();
let initial_stack = vec![retdest, block_number.into()];
let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];
let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, 256.into());
interpreter.run()?;
let result = interpreter.stack();
assert_eq!(
result[0], hashes[block_number as usize],
"Resulting block hash {:?} different from expected hash {:?}",
result[0], hashes[block_number as usize]
);
Ok(())
}
#[test]
fn test_big_index_block_hash() -> Result<()> {
let mut rng = rand::thread_rng();
let blockhash_label = KERNEL.global_labels["blockhash"];
let retdest = 0xDEADBEEFu32.into();
let cur_block_number = 3;
let block_number: usize = rng.gen::<u8>() as usize;
let actual_block_number = block_number + cur_block_number;
let initial_stack = vec![retdest, actual_block_number.into()];
let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];
let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, cur_block_number.into());
interpreter.run()?;
let result = interpreter.stack();
assert_eq!(
result[0],
0.into(),
"Resulting block hash {:?} different from expected hash {:?}",
result[0],
0
);
Ok(())
}
#[test]
fn test_small_index_block_hash() -> Result<()> {
let mut rng = rand::thread_rng();
let blockhash_label = KERNEL.global_labels["blockhash"];
let retdest = 0xDEADBEEFu32.into();
let cur_block_number = 512;
let block_number = rng.gen::<u8>() as usize;
let initial_stack = vec![retdest, block_number.into()];
let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];
let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, cur_block_number.into());
interpreter.run()?;
let result = interpreter.stack();
assert_eq!(
result[0],
0.into(),
"Resulting block hash {:?} different from expected hash {:?}",
result[0],
0
);
Ok(())
}
#[test]
fn test_block_hash_with_overflow() -> Result<()> {
let blockhash_label = KERNEL.global_labels["blockhash"];
let retdest = 0xDEADBEEFu32.into();
let cur_block_number = 1;
let block_number = U256::MAX;
let initial_stack = vec![retdest, block_number];
let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];
let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, cur_block_number.into());
interpreter.run()?;
let result = interpreter.stack();
assert_eq!(
result[0],
0.into(),
"Resulting block hash {:?} different from expected hash {:?}",
result[0],
0
);
Ok(())
}

View File

@ -2,6 +2,7 @@ mod account_code;
mod balance; mod balance;
mod bignum; mod bignum;
mod blake2_f; mod blake2_f;
mod block_hash;
mod bls381; mod bls381;
mod bn254; mod bn254;
mod core; mod core;

View File

@ -40,15 +40,15 @@ use crate::logic::LogicStark;
use crate::memory::memory_stark::MemoryStark; use crate::memory::memory_stark::MemoryStark;
use crate::permutation::{get_grand_product_challenge_set_target, GrandProductChallengeSet}; use crate::permutation::{get_grand_product_challenge_set_target, GrandProductChallengeSet};
use crate::proof::{ use crate::proof::{
BlockMetadataTarget, ExtraBlockDataTarget, PublicValues, PublicValuesTarget, BlockHashesTarget, BlockMetadataTarget, ExtraBlockDataTarget, PublicValues, PublicValuesTarget,
StarkProofWithMetadata, TrieRootsTarget, StarkProofWithMetadata, TrieRootsTarget,
}; };
use crate::prover::prove; use crate::prover::prove;
use crate::recursive_verifier::{ use crate::recursive_verifier::{
add_common_recursion_gates, add_virtual_public_values, add_common_recursion_gates, add_virtual_public_values,
get_memory_extra_looking_products_circuit, recursive_stark_circuit, set_block_metadata_target, get_memory_extra_looking_products_circuit, recursive_stark_circuit, set_block_hashes_target,
set_extra_public_values_target, set_public_value_targets, set_trie_roots_target, set_block_metadata_target, set_extra_public_values_target, set_public_value_targets,
PlonkWrapperCircuit, PublicInputs, StarkWrapperCircuit, set_trie_roots_target, PlonkWrapperCircuit, PublicInputs, StarkWrapperCircuit,
}; };
use crate::stark::Stark; use crate::stark::Stark;
use crate::util::h256_limbs; use crate::util::h256_limbs;
@ -571,6 +571,17 @@ where
let lhs_public_values = lhs.public_values(&mut builder); let lhs_public_values = lhs.public_values(&mut builder);
let rhs_public_values = rhs.public_values(&mut builder); let rhs_public_values = rhs.public_values(&mut builder);
// Connect all block hash values
BlockHashesTarget::connect(
&mut builder,
public_values.block_hashes,
lhs_public_values.block_hashes,
);
BlockHashesTarget::connect(
&mut builder,
public_values.block_hashes,
rhs_public_values.block_hashes,
);
// Connect all block metadata values. // Connect all block metadata values.
BlockMetadataTarget::connect( BlockMetadataTarget::connect(
&mut builder, &mut builder,
@ -694,6 +705,9 @@ where
let parent_block_proof = builder.add_virtual_proof_with_pis(&expected_common_data); let parent_block_proof = builder.add_virtual_proof_with_pis(&expected_common_data);
let agg_root_proof = builder.add_virtual_proof_with_pis(&agg.circuit.common); let agg_root_proof = builder.add_virtual_proof_with_pis(&agg.circuit.common);
// Connect block hashes
Self::connect_block_hashes(&mut builder, &parent_block_proof, &agg_root_proof);
let parent_pv = PublicValuesTarget::from_public_inputs(&parent_block_proof.public_inputs); let parent_pv = PublicValuesTarget::from_public_inputs(&parent_block_proof.public_inputs);
let agg_pv = PublicValuesTarget::from_public_inputs(&agg_root_proof.public_inputs); let agg_pv = PublicValuesTarget::from_public_inputs(&agg_root_proof.public_inputs);
@ -723,6 +737,29 @@ where
} }
} }
/// Connect the 256 block hashes between two blocks
pub fn connect_block_hashes(
builder: &mut CircuitBuilder<F, D>,
lhs: &ProofWithPublicInputsTarget<D>,
rhs: &ProofWithPublicInputsTarget<D>,
) {
let lhs_public_values = PublicValuesTarget::from_public_inputs(&lhs.public_inputs);
let rhs_public_values = PublicValuesTarget::from_public_inputs(&rhs.public_inputs);
for i in 0..255 {
for j in 0..8 {
builder.connect(
lhs_public_values.block_hashes.prev_hashes[8 * (i + 1) + j],
rhs_public_values.block_hashes.prev_hashes[8 * i + j],
);
}
}
let expected_hash = lhs_public_values.block_hashes.cur_hash;
let prev_block_hash = &rhs_public_values.block_hashes.prev_hashes[255 * 8..256 * 8];
for i in 0..expected_hash.len() {
builder.connect(expected_hash[i], prev_block_hash[i]);
}
}
fn connect_block_proof( fn connect_block_proof(
builder: &mut CircuitBuilder<F, D>, builder: &mut CircuitBuilder<F, D>,
has_parent_block: BoolTarget, has_parent_block: BoolTarget,
@ -886,6 +923,11 @@ where
&self.aggregation.circuit.verifier_only, &self.aggregation.circuit.verifier_only,
); );
set_block_hashes_target(
&mut agg_inputs,
&self.aggregation.public_values.block_hashes,
&public_values.block_hashes,
);
set_block_metadata_target( set_block_metadata_target(
&mut agg_inputs, &mut agg_inputs,
&self.aggregation.public_values.block_metadata, &self.aggregation.public_values.block_metadata,
@ -964,6 +1006,11 @@ where
block_inputs block_inputs
.set_verifier_data_target(&self.block.cyclic_vk, &self.block.circuit.verifier_only); .set_verifier_data_target(&self.block.cyclic_vk, &self.block.circuit.verifier_only);
set_block_hashes_target(
&mut block_inputs,
&self.block.public_values.block_hashes,
&public_values.block_hashes,
);
set_extra_public_values_target( set_extra_public_values_target(
&mut block_inputs, &mut block_inputs,
&self.block.public_values.extra_block_data, &self.block.public_values.extra_block_data,

View File

@ -21,7 +21,7 @@ use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::generation::outputs::{get_outputs, GenerationOutputs}; use crate::generation::outputs::{get_outputs, GenerationOutputs};
use crate::generation::state::GenerationState; use crate::generation::state::GenerationState;
use crate::memory::segments::Segment; use crate::memory::segments::Segment;
use crate::proof::{BlockMetadata, ExtraBlockData, PublicValues, TrieRoots}; use crate::proof::{BlockHashes, BlockMetadata, ExtraBlockData, PublicValues, TrieRoots};
use crate::util::h2u; use crate::util::h2u;
use crate::witness::memory::{MemoryAddress, MemoryChannel}; use crate::witness::memory::{MemoryAddress, MemoryChannel};
use crate::witness::transition::transition; use crate::witness::transition::transition;
@ -55,6 +55,8 @@ pub struct GenerationInputs {
pub block_metadata: BlockMetadata, pub block_metadata: BlockMetadata,
pub block_hashes: BlockHashes,
/// A list of known addresses in the input state trie (which itself doesn't hold addresses, /// 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 /// 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 /// post-state rather than state keys. (See `GenerationOutputs`, and in particular
@ -100,6 +102,10 @@ fn apply_metadata_and_tries_memops<F: RichField + Extendable<D>, const D: usize>
(GlobalMetadata::BlockGasLimit, metadata.block_gaslimit), (GlobalMetadata::BlockGasLimit, metadata.block_gaslimit),
(GlobalMetadata::BlockChainId, metadata.block_chain_id), (GlobalMetadata::BlockChainId, metadata.block_chain_id),
(GlobalMetadata::BlockBaseFee, metadata.block_base_fee), (GlobalMetadata::BlockBaseFee, metadata.block_base_fee),
(
GlobalMetadata::BlockCurrentHash,
h2u(inputs.block_hashes.cur_hash),
),
(GlobalMetadata::BlockGasUsed, metadata.block_gas_used), (GlobalMetadata::BlockGasUsed, metadata.block_gas_used),
(GlobalMetadata::BlockGasUsedBefore, inputs.gas_used_before), (GlobalMetadata::BlockGasUsedBefore, inputs.gas_used_before),
(GlobalMetadata::BlockGasUsedAfter, inputs.gas_used_after), (GlobalMetadata::BlockGasUsedAfter, inputs.gas_used_after),
@ -181,6 +187,19 @@ fn apply_metadata_and_tries_memops<F: RichField + Extendable<D>, const D: usize>
}) })
.collect::<Vec<_>>(), .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.memory.apply_ops(&ops);
state.traces.memory_ops.extend(ops); state.traces.memory_ops.extend(ops);
@ -244,6 +263,7 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
trie_roots_before, trie_roots_before,
trie_roots_after, trie_roots_after,
block_metadata: inputs.block_metadata, block_metadata: inputs.block_metadata,
block_hashes: inputs.block_hashes,
extra_block_data, extra_block_data,
}; };

View File

@ -39,6 +39,7 @@ impl<F: Field> GenerationState<F> {
"ffe" => self.run_ffe(input_fn), "ffe" => self.run_ffe(input_fn),
"mpt" => self.run_mpt(), "mpt" => self.run_mpt(),
"rlp" => self.run_rlp(), "rlp" => self.run_rlp(),
"current_hash" => self.run_current_hash(),
"account_code" => self.run_account_code(input_fn), "account_code" => self.run_account_code(input_fn),
"bignum_modmul" => self.run_bignum_modmul(), "bignum_modmul" => self.run_bignum_modmul(),
_ => panic!("Unrecognized prover input function."), _ => panic!("Unrecognized prover input function."),
@ -118,6 +119,10 @@ impl<F: Field> GenerationState<F> {
.unwrap_or_else(|| panic!("Out of RLP data")) .unwrap_or_else(|| panic!("Out of RLP data"))
} }
fn run_current_hash(&mut self) -> U256 {
U256::from_big_endian(&self.inputs.block_hashes.cur_hash.0)
}
/// Account code. /// Account code.
fn run_account_code(&mut self, input_fn: &ProverInputFn) -> U256 { fn run_account_code(&mut self, input_fn: &ProverInputFn) -> U256 {
match input_fn.0[1].as_str() { match input_fn.0[1].as_str() {

View File

@ -13,7 +13,7 @@ use crate::permutation::{
get_n_grand_product_challenge_sets_target, get_n_grand_product_challenge_sets_target,
}; };
use crate::proof::*; use crate::proof::*;
use crate::util::u256_limbs; use crate::util::{h256_limbs, u256_limbs};
fn observe_root<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>( fn observe_root<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
challenger: &mut Challenger<F, C::Hasher>, challenger: &mut Challenger<F, C::Hasher>,
@ -146,6 +146,34 @@ fn observe_extra_block_data_target<
challenger.observe_elements(&extra_data.block_bloom_after); challenger.observe_elements(&extra_data.block_bloom_after);
} }
fn observe_block_hashes<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut Challenger<F, C::Hasher>,
block_hashes: &BlockHashes,
) {
for i in 0..256 {
challenger.observe_elements(&h256_limbs::<F>(block_hashes.prev_hashes[i]));
}
challenger.observe_elements(&h256_limbs::<F>(block_hashes.cur_hash));
}
fn observe_block_hashes_target<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
block_hashes: &BlockHashesTarget,
) where
C::Hasher: AlgebraicHasher<F>,
{
challenger.observe_elements(&block_hashes.prev_hashes);
challenger.observe_elements(&block_hashes.cur_hash);
}
pub(crate) fn observe_public_values< pub(crate) fn observe_public_values<
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>, C: GenericConfig<D, F = F>,
@ -157,6 +185,7 @@ pub(crate) fn observe_public_values<
observe_trie_roots::<F, C, D>(challenger, &public_values.trie_roots_before); observe_trie_roots::<F, C, D>(challenger, &public_values.trie_roots_before);
observe_trie_roots::<F, C, D>(challenger, &public_values.trie_roots_after); observe_trie_roots::<F, C, D>(challenger, &public_values.trie_roots_after);
observe_block_metadata::<F, C, D>(challenger, &public_values.block_metadata); observe_block_metadata::<F, C, D>(challenger, &public_values.block_metadata);
observe_block_hashes::<F, C, D>(challenger, &public_values.block_hashes);
observe_extra_block_data::<F, C, D>(challenger, &public_values.extra_block_data); observe_extra_block_data::<F, C, D>(challenger, &public_values.extra_block_data);
} }
@ -173,6 +202,7 @@ pub(crate) fn observe_public_values_target<
observe_trie_roots_target::<F, C, D>(challenger, &public_values.trie_roots_before); observe_trie_roots_target::<F, C, D>(challenger, &public_values.trie_roots_before);
observe_trie_roots_target::<F, C, D>(challenger, &public_values.trie_roots_after); observe_trie_roots_target::<F, C, D>(challenger, &public_values.trie_roots_after);
observe_block_metadata_target::<F, C, D>(challenger, &public_values.block_metadata); observe_block_metadata_target::<F, C, D>(challenger, &public_values.block_metadata);
observe_block_hashes_target::<F, C, D>(challenger, &public_values.block_hashes);
observe_extra_block_data_target::<F, C, D>(challenger, &public_values.extra_block_data); observe_extra_block_data_target::<F, C, D>(challenger, &public_values.extra_block_data);
} }

View File

@ -68,10 +68,12 @@ pub enum Segment {
TouchedAddresses = 34, TouchedAddresses = 34,
/// List of checkpoints for the current context. Length in `ContextMetadata`. /// List of checkpoints for the current context. Length in `ContextMetadata`.
ContextCheckpoints = 35, ContextCheckpoints = 35,
/// List of 256 previous block hashes.
BlockHashes = 36,
} }
impl Segment { impl Segment {
pub(crate) const COUNT: usize = 36; pub(crate) const COUNT: usize = 37;
pub(crate) fn all() -> [Self; Self::COUNT] { pub(crate) fn all() -> [Self; Self::COUNT] {
[ [
@ -111,6 +113,7 @@ impl Segment {
Self::JournalCheckpoints, Self::JournalCheckpoints,
Self::TouchedAddresses, Self::TouchedAddresses,
Self::ContextCheckpoints, Self::ContextCheckpoints,
Self::BlockHashes,
] ]
} }
@ -153,6 +156,7 @@ impl Segment {
Segment::JournalCheckpoints => "SEGMENT_JOURNAL_CHECKPOINTS", Segment::JournalCheckpoints => "SEGMENT_JOURNAL_CHECKPOINTS",
Segment::TouchedAddresses => "SEGMENT_TOUCHED_ADDRESSES", Segment::TouchedAddresses => "SEGMENT_TOUCHED_ADDRESSES",
Segment::ContextCheckpoints => "SEGMENT_CONTEXT_CHECKPOINTS", Segment::ContextCheckpoints => "SEGMENT_CONTEXT_CHECKPOINTS",
Segment::BlockHashes => "SEGMENT_BLOCK_HASHES",
} }
} }
@ -195,6 +199,7 @@ impl Segment {
Segment::JournalCheckpoints => 256, Segment::JournalCheckpoints => 256,
Segment::TouchedAddresses => 256, Segment::TouchedAddresses => 256,
Segment::ContextCheckpoints => 256, Segment::ContextCheckpoints => 256,
Segment::BlockHashes => 256,
} }
} }
} }

View File

@ -53,6 +53,7 @@ pub struct PublicValues {
pub trie_roots_before: TrieRoots, pub trie_roots_before: TrieRoots,
pub trie_roots_after: TrieRoots, pub trie_roots_after: TrieRoots,
pub block_metadata: BlockMetadata, pub block_metadata: BlockMetadata,
pub block_hashes: BlockHashes,
pub extra_block_data: ExtraBlockData, pub extra_block_data: ExtraBlockData,
} }
@ -63,6 +64,22 @@ pub struct TrieRoots {
pub receipts_root: H256, pub receipts_root: H256,
} }
// There should be 256 previous hashes stored, so the default should also contain 256 values.
impl Default for BlockHashes {
fn default() -> Self {
Self {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BlockHashes {
pub prev_hashes: Vec<H256>,
pub cur_hash: H256,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)] #[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct BlockMetadata { pub struct BlockMetadata {
pub block_beneficiary: Address, pub block_beneficiary: Address,
@ -93,6 +110,7 @@ pub struct PublicValuesTarget {
pub trie_roots_before: TrieRootsTarget, pub trie_roots_before: TrieRootsTarget,
pub trie_roots_after: TrieRootsTarget, pub trie_roots_after: TrieRootsTarget,
pub block_metadata: BlockMetadataTarget, pub block_metadata: BlockMetadataTarget,
pub block_hashes: BlockHashesTarget,
pub extra_block_data: ExtraBlockDataTarget, pub extra_block_data: ExtraBlockDataTarget,
} }
@ -140,6 +158,13 @@ impl PublicValuesTarget {
buffer.write_target(block_gas_used)?; buffer.write_target(block_gas_used)?;
buffer.write_target_array(&block_bloom)?; buffer.write_target_array(&block_bloom)?;
let BlockHashesTarget {
prev_hashes,
cur_hash,
} = self.block_hashes;
buffer.write_target_array(&prev_hashes)?;
buffer.write_target_array(&cur_hash)?;
let ExtraBlockDataTarget { let ExtraBlockDataTarget {
txn_number_before, txn_number_before,
txn_number_after, txn_number_after,
@ -183,6 +208,11 @@ impl PublicValuesTarget {
block_bloom: buffer.read_target_array()?, block_bloom: buffer.read_target_array()?,
}; };
let block_hashes = BlockHashesTarget {
prev_hashes: buffer.read_target_array()?,
cur_hash: buffer.read_target_array()?,
};
let extra_block_data = ExtraBlockDataTarget { let extra_block_data = ExtraBlockDataTarget {
txn_number_before: buffer.read_target()?, txn_number_before: buffer.read_target()?,
txn_number_after: buffer.read_target()?, txn_number_after: buffer.read_target()?,
@ -196,6 +226,7 @@ impl PublicValuesTarget {
trie_roots_before, trie_roots_before,
trie_roots_after, trie_roots_after,
block_metadata, block_metadata,
block_hashes,
extra_block_data, extra_block_data,
}) })
} }
@ -205,6 +236,7 @@ impl PublicValuesTarget {
pis.len() pis.len()
> TrieRootsTarget::SIZE * 2 > TrieRootsTarget::SIZE * 2
+ BlockMetadataTarget::SIZE + BlockMetadataTarget::SIZE
+ BlockHashesTarget::BLOCK_HASHES_SIZE
+ ExtraBlockDataTarget::SIZE + ExtraBlockDataTarget::SIZE
- 1 - 1
); );
@ -218,10 +250,19 @@ impl PublicValuesTarget {
&pis[TrieRootsTarget::SIZE * 2 &pis[TrieRootsTarget::SIZE * 2
..TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE], ..TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE],
), ),
extra_block_data: ExtraBlockDataTarget::from_public_inputs( block_hashes: BlockHashesTarget::from_public_inputs(
&pis[TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE &pis[TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE
..TrieRootsTarget::SIZE * 2 ..TrieRootsTarget::SIZE * 2
+ BlockMetadataTarget::SIZE + BlockMetadataTarget::SIZE
+ BlockHashesTarget::BLOCK_HASHES_SIZE],
),
extra_block_data: ExtraBlockDataTarget::from_public_inputs(
&pis[TrieRootsTarget::SIZE * 2
+ BlockMetadataTarget::SIZE
+ BlockHashesTarget::BLOCK_HASHES_SIZE
..TrieRootsTarget::SIZE * 2
+ BlockMetadataTarget::SIZE
+ BlockHashesTarget::BLOCK_HASHES_SIZE
+ ExtraBlockDataTarget::SIZE], + ExtraBlockDataTarget::SIZE],
), ),
} }
@ -252,6 +293,12 @@ impl PublicValuesTarget {
pv0.block_metadata, pv0.block_metadata,
pv1.block_metadata, pv1.block_metadata,
), ),
block_hashes: BlockHashesTarget::select(
builder,
condition,
pv0.block_hashes,
pv1.block_hashes,
),
extra_block_data: ExtraBlockDataTarget::select( extra_block_data: ExtraBlockDataTarget::select(
builder, builder,
condition, condition,
@ -411,6 +458,51 @@ impl BlockMetadataTarget {
} }
} }
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub struct BlockHashesTarget {
pub prev_hashes: [Target; 2048],
pub cur_hash: [Target; 8],
}
impl BlockHashesTarget {
const BLOCK_HASHES_SIZE: usize = 2056;
pub fn from_public_inputs(pis: &[Target]) -> Self {
Self {
prev_hashes: pis[0..2048].try_into().unwrap(),
cur_hash: pis[2048..2056].try_into().unwrap(),
}
}
pub fn select<F: RichField + Extendable<D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>,
condition: BoolTarget,
bm0: Self,
bm1: Self,
) -> Self {
Self {
prev_hashes: core::array::from_fn(|i| {
builder.select(condition, bm0.prev_hashes[i], bm1.prev_hashes[i])
}),
cur_hash: core::array::from_fn(|i| {
builder.select(condition, bm0.cur_hash[i], bm1.cur_hash[i])
}),
}
}
pub fn connect<F: RichField + Extendable<D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>,
bm0: Self,
bm1: Self,
) {
for i in 0..2048 {
builder.connect(bm0.prev_hashes[i], bm1.prev_hashes[i]);
}
for i in 0..8 {
builder.connect(bm0.cur_hash[i], bm1.cur_hash[i]);
}
}
}
#[derive(Eq, PartialEq, Debug, Copy, Clone)] #[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub struct ExtraBlockDataTarget { pub struct ExtraBlockDataTarget {
pub txn_number_before: Target, pub txn_number_before: Target,

View File

@ -37,12 +37,13 @@ use crate::permutation::{
PermutationCheckDataTarget, PermutationCheckDataTarget,
}; };
use crate::proof::{ use crate::proof::{
BlockMetadata, BlockMetadataTarget, ExtraBlockData, ExtraBlockDataTarget, PublicValues, BlockHashes, BlockHashesTarget, BlockMetadata, BlockMetadataTarget, ExtraBlockData,
PublicValuesTarget, StarkOpeningSetTarget, StarkProof, StarkProofChallengesTarget, ExtraBlockDataTarget, PublicValues, PublicValuesTarget, StarkOpeningSetTarget, StarkProof,
StarkProofTarget, StarkProofWithMetadata, TrieRoots, TrieRootsTarget, StarkProofChallengesTarget, StarkProofTarget, StarkProofWithMetadata, TrieRoots,
TrieRootsTarget,
}; };
use crate::stark::Stark; use crate::stark::Stark;
use crate::util::u256_limbs; use crate::util::{h256_limbs, u256_limbs};
use crate::vanishing_poly::eval_vanishing_poly_circuit; use crate::vanishing_poly::eval_vanishing_poly_circuit;
use crate::vars::StarkEvaluationTargets; use crate::vars::StarkEvaluationTargets;
@ -509,7 +510,7 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
let mut product = builder.one(); let mut product = builder.one();
// Add metadata writes. // Add metadata writes.
let block_fields_without_beneficiary_and_basefee_and_bloom = [ let block_fields_scalars = [
( (
GlobalMetadata::BlockTimestamp as usize, GlobalMetadata::BlockTimestamp as usize,
public_values.block_metadata.block_timestamp, public_values.block_metadata.block_timestamp,
@ -552,7 +553,7 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
), ),
]; ];
let beneficiary_base_fee_fields: [(usize, &[Target]); 2] = [ let beneficiary_base_fee_cur_hash_fields: [(usize, &[Target]); 3] = [
( (
GlobalMetadata::BlockBeneficiary as usize, GlobalMetadata::BlockBeneficiary as usize,
&public_values.block_metadata.block_beneficiary, &public_values.block_metadata.block_beneficiary,
@ -561,10 +562,14 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
GlobalMetadata::BlockBaseFee as usize, GlobalMetadata::BlockBaseFee as usize,
&public_values.block_metadata.block_base_fee, &public_values.block_metadata.block_base_fee,
), ),
(
GlobalMetadata::BlockCurrentHash as usize,
&public_values.block_hashes.cur_hash,
),
]; ];
let metadata_segment = builder.constant(F::from_canonical_u32(Segment::GlobalMetadata as u32)); let metadata_segment = builder.constant(F::from_canonical_u32(Segment::GlobalMetadata as u32));
block_fields_without_beneficiary_and_basefee_and_bloom.map(|(field, target)| { block_fields_scalars.map(|(field, target)| {
// Each of those fields fit in 32 bits, hence in a single Target. // Each of those fields fit in 32 bits, hence in a single Target.
product = add_data_write( product = add_data_write(
builder, builder,
@ -576,7 +581,7 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
); );
}); });
beneficiary_base_fee_fields.map(|(field, targets)| { beneficiary_base_fee_cur_hash_fields.map(|(field, targets)| {
product = add_data_write( product = add_data_write(
builder, builder,
challenge, challenge,
@ -587,6 +592,19 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
); );
}); });
// Add block hashes writes.
let block_hashes_segment = builder.constant(F::from_canonical_u32(Segment::BlockHashes as u32));
for i in 0..256 {
product = add_data_write(
builder,
challenge,
product,
block_hashes_segment,
i,
&public_values.block_hashes.prev_hashes[8 * i..8 * (i + 1)],
);
}
// Add block bloom filters writes. // Add block bloom filters writes.
let bloom_segment = builder.constant(F::from_canonical_u32(Segment::GlobalBlockBloom as u32)); let bloom_segment = builder.constant(F::from_canonical_u32(Segment::GlobalBlockBloom as u32));
for i in 0..8 { for i in 0..8 {
@ -599,7 +617,6 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
&public_values.block_metadata.block_bloom[i * 8..(i + 1) * 8], &public_values.block_metadata.block_bloom[i * 8..(i + 1) * 8],
); );
} }
for i in 0..8 { for i in 0..8 {
product = add_data_write( product = add_data_write(
builder, builder,
@ -729,11 +746,13 @@ 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_before = add_virtual_trie_roots(builder);
let trie_roots_after = add_virtual_trie_roots(builder); let trie_roots_after = add_virtual_trie_roots(builder);
let block_metadata = add_virtual_block_metadata(builder); let block_metadata = add_virtual_block_metadata(builder);
let block_hashes = add_virtual_block_hashes(builder);
let extra_block_data = add_virtual_extra_block_data(builder); let extra_block_data = add_virtual_extra_block_data(builder);
PublicValuesTarget { PublicValuesTarget {
trie_roots_before, trie_roots_before,
trie_roots_after, trie_roots_after,
block_metadata, block_metadata,
block_hashes,
extra_block_data, extra_block_data,
} }
} }
@ -775,6 +794,17 @@ pub(crate) fn add_virtual_block_metadata<F: RichField + Extendable<D>, const D:
block_bloom, block_bloom,
} }
} }
pub(crate) fn add_virtual_block_hashes<F: RichField + Extendable<D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>,
) -> BlockHashesTarget {
let prev_hashes = builder.add_virtual_public_input_arr();
let cur_hash = builder.add_virtual_public_input_arr();
BlockHashesTarget {
prev_hashes,
cur_hash,
}
}
pub(crate) fn add_virtual_extra_block_data<F: RichField + Extendable<D>, const D: usize>( pub(crate) fn add_virtual_extra_block_data<F: RichField + Extendable<D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>, builder: &mut CircuitBuilder<F, D>,
) -> ExtraBlockDataTarget { ) -> ExtraBlockDataTarget {
@ -894,6 +924,11 @@ pub(crate) fn set_public_value_targets<F, W, const D: usize>(
&public_values_target.block_metadata, &public_values_target.block_metadata,
&public_values.block_metadata, &public_values.block_metadata,
); );
set_block_hashes_target(
witness,
&public_values_target.block_hashes,
&public_values.block_hashes,
);
set_extra_public_values_target( set_extra_public_values_target(
witness, witness,
&public_values_target.extra_block_data, &public_values_target.extra_block_data,
@ -1008,6 +1043,25 @@ pub(crate) fn set_block_metadata_target<F, W, const D: usize>(
witness.set_target_arr(&block_metadata_target.block_bloom, &block_bloom_limbs); witness.set_target_arr(&block_metadata_target.block_bloom, &block_bloom_limbs);
} }
pub(crate) fn set_block_hashes_target<F, W, const D: usize>(
witness: &mut W,
block_hashes_target: &BlockHashesTarget,
block_hashes: &BlockHashes,
) where
F: RichField + Extendable<D>,
W: Witness<F>,
{
for i in 0..256 {
let block_hash_limbs: [F; 8] = h256_limbs::<F>(block_hashes.prev_hashes[i]);
witness.set_target_arr(
&block_hashes_target.prev_hashes[8 * i..8 * (i + 1)],
&block_hash_limbs,
);
}
let cur_block_hash_limbs: [F; 8] = h256_limbs::<F>(block_hashes.cur_hash);
witness.set_target_arr(&block_hashes_target.cur_hash, &cur_block_hash_limbs);
}
pub(crate) fn set_extra_public_values_target<F, W, const D: usize>( pub(crate) fn set_extra_public_values_target<F, W, const D: usize>(
witness: &mut W, witness: &mut W,
ed_target: &ExtraBlockDataTarget, ed_target: &ExtraBlockDataTarget,

View File

@ -176,6 +176,10 @@ where
GlobalMetadata::BlockBaseFee, GlobalMetadata::BlockBaseFee,
public_values.block_metadata.block_base_fee, public_values.block_metadata.block_base_fee,
), ),
(
GlobalMetadata::BlockCurrentHash,
h2u(public_values.block_hashes.cur_hash),
),
( (
GlobalMetadata::BlockGasUsed, GlobalMetadata::BlockGasUsed,
public_values.block_metadata.block_gas_used, public_values.block_metadata.block_gas_used,
@ -242,6 +246,13 @@ where
prod = add_data_write(challenge, bloom_segment, prod, index + 16, val); prod = add_data_write(challenge, bloom_segment, prod, index + 16, val);
} }
// Add Blockhashes writes.
let block_hashes_segment = F::from_canonical_u32(Segment::BlockHashes as u32);
for index in 0..256 {
let val = h2u(public_values.block_hashes.prev_hashes[index]);
prod = add_data_write(challenge, block_hashes_segment, prod, index, val);
}
prod prod
} }
@ -267,6 +278,7 @@ where
row[12] = F::ONE; // timestamp row[12] = F::ONE; // timestamp
running_product * challenge.combine(row.iter()) running_product * challenge.combine(row.iter())
} }
pub(crate) fn verify_stark_proof_with_challenges< pub(crate) fn verify_stark_proof_with_challenges<
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>, C: GenericConfig<D, F = F>,

View File

@ -5,7 +5,7 @@ use std::time::Duration;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles; use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::Address; use ethereum_types::{Address, H256};
use hex_literal::hex; use hex_literal::hex;
use keccak_hash::keccak; use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::goldilocks_field::GoldilocksField;
@ -15,7 +15,7 @@ use plonky2_evm::all_stark::AllStark;
use plonky2_evm::config::StarkConfig; use plonky2_evm::config::StarkConfig;
use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp};
use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::generation::{GenerationInputs, TrieInputs};
use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::proof::{BlockHashes, BlockMetadata, TrieRoots};
use plonky2_evm::prover::prove; use plonky2_evm::prover::prove;
use plonky2_evm::verifier::verify_proof; use plonky2_evm::verifier::verify_proof;
use plonky2_evm::Node; use plonky2_evm::Node;
@ -154,6 +154,10 @@ fn add11_yml() -> anyhow::Result<()> {
gas_used_after: 0xa868u64.into(), gas_used_after: 0xa868u64.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };

View File

@ -5,7 +5,7 @@ use std::time::Duration;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles; use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, U256}; use ethereum_types::{Address, H256, U256};
use hex_literal::hex; use hex_literal::hex;
use keccak_hash::keccak; use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::goldilocks_field::GoldilocksField;
@ -16,7 +16,7 @@ use plonky2_evm::config::StarkConfig;
use plonky2_evm::cpu::kernel::opcodes::{get_opcode, get_push_opcode}; use plonky2_evm::cpu::kernel::opcodes::{get_opcode, get_push_opcode};
use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp};
use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::generation::{GenerationInputs, TrieInputs};
use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::proof::{BlockHashes, BlockMetadata, TrieRoots};
use plonky2_evm::prover::prove; use plonky2_evm::prover::prove;
use plonky2_evm::verifier::verify_proof; use plonky2_evm::verifier::verify_proof;
use plonky2_evm::Node; use plonky2_evm::Node;
@ -171,6 +171,10 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
gas_used_after: gas_used.into(), gas_used_after: gas_used.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };

View File

@ -4,6 +4,7 @@ use std::time::Duration;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::H256;
use keccak_hash::keccak; use keccak_hash::keccak;
use log::info; use log::info;
use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::goldilocks_field::GoldilocksField;
@ -14,7 +15,7 @@ use plonky2_evm::all_stark::AllStark;
use plonky2_evm::config::StarkConfig; use plonky2_evm::config::StarkConfig;
use plonky2_evm::fixed_recursive_verifier::AllRecursiveCircuits; use plonky2_evm::fixed_recursive_verifier::AllRecursiveCircuits;
use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::generation::{GenerationInputs, TrieInputs};
use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::proof::{BlockHashes, BlockMetadata, TrieRoots};
use plonky2_evm::Node; use plonky2_evm::Node;
type F = GoldilocksField; type F = GoldilocksField;
@ -62,6 +63,10 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
gas_used_after: 0.into(), gas_used_after: 0.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };

View File

@ -8,7 +8,7 @@ use bytes::Bytes;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles; use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, U256}; use ethereum_types::{Address, H256, U256};
use hex_literal::hex; use hex_literal::hex;
use keccak_hash::keccak; use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::goldilocks_field::GoldilocksField;
@ -19,7 +19,7 @@ use plonky2_evm::config::StarkConfig;
use plonky2_evm::fixed_recursive_verifier::AllRecursiveCircuits; use plonky2_evm::fixed_recursive_verifier::AllRecursiveCircuits;
use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp, LegacyTransactionRlp, LogRlp}; use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp, LegacyTransactionRlp, LogRlp};
use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::generation::{GenerationInputs, TrieInputs};
use plonky2_evm::proof::{BlockMetadata, ExtraBlockData, PublicValues, TrieRoots}; use plonky2_evm::proof::{BlockHashes, BlockMetadata, ExtraBlockData, PublicValues, TrieRoots};
use plonky2_evm::prover::prove; use plonky2_evm::prover::prove;
use plonky2_evm::verifier::verify_proof; use plonky2_evm::verifier::verify_proof;
use plonky2_evm::Node; use plonky2_evm::Node;
@ -232,6 +232,10 @@ fn test_log_opcodes() -> anyhow::Result<()> {
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after, block_bloom_after,
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };
@ -425,6 +429,10 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
gas_used_after: 21000u64.into(), gas_used_after: 21000u64.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };
@ -562,6 +570,10 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
gas_used_after: receipt.cum_gas_used, gas_used_after: receipt.cum_gas_used,
block_bloom_before: block_bloom_second, block_bloom_before: block_bloom_second,
block_bloom_after: block_bloom_final, block_bloom_after: block_bloom_final,
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };
@ -585,6 +597,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
block_bloom_after: public_values.extra_block_data.block_bloom_after, block_bloom_after: public_values.extra_block_data.block_bloom_after,
}, },
block_metadata: public_values.block_metadata, block_metadata: public_values.block_metadata,
block_hashes: public_values.block_hashes,
}; };
// We can duplicate the proofs here because the state hasn't mutated. // We can duplicate the proofs here because the state hasn't mutated.
@ -857,6 +870,10 @@ fn test_two_txn() -> anyhow::Result<()> {
gas_used_after: 42000u64.into(), gas_used_after: 42000u64.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };

View File

@ -5,7 +5,7 @@ use std::time::Duration;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles; use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::Address; use ethereum_types::{Address, H256};
use hex_literal::hex; use hex_literal::hex;
use keccak_hash::keccak; use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::goldilocks_field::GoldilocksField;
@ -15,7 +15,7 @@ use plonky2_evm::all_stark::AllStark;
use plonky2_evm::config::StarkConfig; use plonky2_evm::config::StarkConfig;
use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp};
use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::generation::{GenerationInputs, TrieInputs};
use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::proof::{BlockHashes, BlockMetadata, TrieRoots};
use plonky2_evm::prover::prove; use plonky2_evm::prover::prove;
use plonky2_evm::verifier::verify_proof; use plonky2_evm::verifier::verify_proof;
use plonky2_evm::Node; use plonky2_evm::Node;
@ -160,6 +160,10 @@ fn self_balance_gas_cost() -> anyhow::Result<()> {
gas_used_after: gas_used.into(), gas_used_after: gas_used.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };

View File

@ -5,7 +5,7 @@ use std::time::Duration;
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
use eth_trie_utils::nibbles::Nibbles; use eth_trie_utils::nibbles::Nibbles;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, U256}; use ethereum_types::{Address, H256, U256};
use hex_literal::hex; use hex_literal::hex;
use keccak_hash::keccak; use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::goldilocks_field::GoldilocksField;
@ -15,7 +15,7 @@ use plonky2_evm::all_stark::AllStark;
use plonky2_evm::config::StarkConfig; use plonky2_evm::config::StarkConfig;
use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp};
use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::generation::{GenerationInputs, TrieInputs};
use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::proof::{BlockHashes, BlockMetadata, TrieRoots};
use plonky2_evm::prover::prove; use plonky2_evm::prover::prove;
use plonky2_evm::verifier::verify_proof; use plonky2_evm::verifier::verify_proof;
use plonky2_evm::Node; use plonky2_evm::Node;
@ -141,6 +141,10 @@ fn test_simple_transfer() -> anyhow::Result<()> {
gas_used_after: 21032.into(), gas_used_after: 21032.into(),
block_bloom_before: [0.into(); 8], block_bloom_before: [0.into(); 8],
block_bloom_after: [0.into(); 8], block_bloom_after: [0.into(); 8],
block_hashes: BlockHashes {
prev_hashes: vec![H256::default(); 256],
cur_hash: H256::default(),
},
addresses: vec![], addresses: vec![],
}; };