mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-05 23:33:07 +00:00
Merge pull request #1208 from topos-protocol/blockhash_opcode
Add blockhash opcode
This commit is contained in:
commit
180c20942b
@ -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?
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
125
evm/src/cpu/kernel/tests/block_hash.rs
Normal file
125
evm/src/cpu/kernel/tests/block_hash.rs
Normal 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(())
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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>,
|
||||||
|
|||||||
@ -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![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user