mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-02 22:03:07 +00:00
Add Checkpoint heights (#1418)
This commit is contained in:
parent
5607faf36b
commit
bfcfcdb498
@ -37,7 +37,7 @@ use crate::generation::GenerationInputs;
|
||||
use crate::get_challenges::observe_public_values_target;
|
||||
use crate::proof::{
|
||||
BlockHashesTarget, BlockMetadataTarget, ExtraBlockData, ExtraBlockDataTarget, PublicValues,
|
||||
PublicValuesTarget, StarkProofWithMetadata, TrieRootsTarget,
|
||||
PublicValuesTarget, StarkProofWithMetadata, TrieRoots, TrieRootsTarget,
|
||||
};
|
||||
use crate::prover::prove;
|
||||
use crate::recursive_verifier::{
|
||||
@ -715,18 +715,18 @@ where
|
||||
lhs: &ExtraBlockDataTarget,
|
||||
rhs: &ExtraBlockDataTarget,
|
||||
) {
|
||||
// Connect genesis state root values.
|
||||
// Connect checkpoint state root values.
|
||||
for (&limb0, &limb1) in pvs
|
||||
.genesis_state_trie_root
|
||||
.checkpoint_state_trie_root
|
||||
.iter()
|
||||
.zip(&rhs.genesis_state_trie_root)
|
||||
.zip(&rhs.checkpoint_state_trie_root)
|
||||
{
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
for (&limb0, &limb1) in pvs
|
||||
.genesis_state_trie_root
|
||||
.checkpoint_state_trie_root
|
||||
.iter()
|
||||
.zip(&lhs.genesis_state_trie_root)
|
||||
.zip(&lhs.checkpoint_state_trie_root)
|
||||
{
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
@ -790,6 +790,34 @@ where
|
||||
let parent_pv = PublicValuesTarget::from_public_inputs(&parent_block_proof.public_inputs);
|
||||
let agg_pv = PublicValuesTarget::from_public_inputs(&agg_root_proof.public_inputs);
|
||||
|
||||
// Connect block `trie_roots_before` with parent_pv `trie_roots_before`.
|
||||
TrieRootsTarget::connect(
|
||||
&mut builder,
|
||||
public_values.trie_roots_before,
|
||||
parent_pv.trie_roots_before,
|
||||
);
|
||||
// Connect the rest of block `public_values` with agg_pv.
|
||||
TrieRootsTarget::connect(
|
||||
&mut builder,
|
||||
public_values.trie_roots_after,
|
||||
agg_pv.trie_roots_after,
|
||||
);
|
||||
BlockMetadataTarget::connect(
|
||||
&mut builder,
|
||||
public_values.block_metadata,
|
||||
agg_pv.block_metadata,
|
||||
);
|
||||
BlockHashesTarget::connect(
|
||||
&mut builder,
|
||||
public_values.block_hashes,
|
||||
agg_pv.block_hashes,
|
||||
);
|
||||
ExtraBlockDataTarget::connect(
|
||||
&mut builder,
|
||||
public_values.extra_block_data,
|
||||
agg_pv.extra_block_data,
|
||||
);
|
||||
|
||||
// Make connections between block proofs, and check initial and final block values.
|
||||
Self::connect_block_proof(&mut builder, has_parent_block, &parent_pv, &agg_pv);
|
||||
|
||||
@ -855,12 +883,12 @@ where
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
|
||||
// Between blocks, the genesis state trie remains unchanged.
|
||||
// Between blocks, the checkpoint state trie remains unchanged.
|
||||
for (&limb0, limb1) in lhs
|
||||
.extra_block_data
|
||||
.genesis_state_trie_root
|
||||
.checkpoint_state_trie_root
|
||||
.iter()
|
||||
.zip(rhs.extra_block_data.genesis_state_trie_root)
|
||||
.zip(rhs.extra_block_data.checkpoint_state_trie_root)
|
||||
{
|
||||
builder.connect(limb0, limb1);
|
||||
}
|
||||
@ -878,15 +906,11 @@ where
|
||||
|
||||
let has_not_parent_block = builder.sub(one, has_parent_block.target);
|
||||
|
||||
// Check that the genesis block number is 0.
|
||||
let gen_block_constr = builder.mul(has_not_parent_block, lhs.block_metadata.block_number);
|
||||
builder.assert_zero(gen_block_constr);
|
||||
|
||||
// Check that the genesis block has the predetermined state trie root in `ExtraBlockData`.
|
||||
Self::connect_genesis_block(builder, rhs, has_not_parent_block);
|
||||
// Check that the checkpoint block has the predetermined state trie root in `ExtraBlockData`.
|
||||
Self::connect_checkpoint_block(builder, rhs, has_not_parent_block);
|
||||
}
|
||||
|
||||
fn connect_genesis_block(
|
||||
fn connect_checkpoint_block(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
x: &PublicValuesTarget,
|
||||
has_not_parent_block: Target,
|
||||
@ -897,7 +921,7 @@ where
|
||||
.trie_roots_before
|
||||
.state_root
|
||||
.iter()
|
||||
.zip(x.extra_block_data.genesis_state_trie_root)
|
||||
.zip(x.extra_block_data.checkpoint_state_trie_root)
|
||||
{
|
||||
let mut constr = builder.sub(limb0, limb1);
|
||||
constr = builder.mul(has_not_parent_block, constr);
|
||||
@ -1026,7 +1050,9 @@ where
|
||||
trie_roots_before: lhs_public_values.trie_roots_before,
|
||||
trie_roots_after: rhs_public_values.trie_roots_after,
|
||||
extra_block_data: ExtraBlockData {
|
||||
genesis_state_trie_root: lhs_public_values.extra_block_data.genesis_state_trie_root,
|
||||
checkpoint_state_trie_root: lhs_public_values
|
||||
.extra_block_data
|
||||
.checkpoint_state_trie_root,
|
||||
txn_number_before: lhs_public_values.extra_block_data.txn_number_before,
|
||||
txn_number_after: rhs_public_values.extra_block_data.txn_number_after,
|
||||
gas_used_before: lhs_public_values.extra_block_data.gas_used_before,
|
||||
@ -1077,42 +1103,66 @@ where
|
||||
block_inputs
|
||||
.set_proof_with_pis_target(&self.block.parent_block_proof, parent_block_proof);
|
||||
} else {
|
||||
// Initialize genesis_state_trie, state_root_after, and the previous block hashes for correct connection between blocks.
|
||||
// Block number does not need to be initialized as genesis block is constrained to have number 0.
|
||||
|
||||
if public_values.trie_roots_before.state_root
|
||||
!= public_values.extra_block_data.genesis_state_trie_root
|
||||
!= public_values.extra_block_data.checkpoint_state_trie_root
|
||||
{
|
||||
return Err(anyhow::Error::msg(format!(
|
||||
"Inconsistent pre-state for first block {:?} with genesis state {:?}.",
|
||||
"Inconsistent pre-state for first block {:?} with checkpoint state {:?}.",
|
||||
public_values.trie_roots_before.state_root,
|
||||
public_values.extra_block_data.genesis_state_trie_root,
|
||||
public_values.extra_block_data.checkpoint_state_trie_root,
|
||||
)));
|
||||
}
|
||||
// Initialize `state_root_after`.
|
||||
|
||||
// Initialize some public inputs for correct connection between the checkpoint block and the current one.
|
||||
let mut nonzero_pis = HashMap::new();
|
||||
|
||||
// Initialize the checkpoint block roots before, and state root after.
|
||||
let state_trie_root_before_keys = 0..TrieRootsTarget::HASH_SIZE;
|
||||
for (key, &value) in state_trie_root_before_keys
|
||||
.zip_eq(&h256_limbs::<F>(public_values.trie_roots_before.state_root))
|
||||
{
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
let txn_trie_root_before_keys =
|
||||
TrieRootsTarget::HASH_SIZE..TrieRootsTarget::HASH_SIZE * 2;
|
||||
for (key, &value) in txn_trie_root_before_keys.clone().zip_eq(&h256_limbs::<F>(
|
||||
public_values.trie_roots_before.transactions_root,
|
||||
)) {
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
let receipts_trie_root_before_keys =
|
||||
TrieRootsTarget::HASH_SIZE * 2..TrieRootsTarget::HASH_SIZE * 3;
|
||||
for (key, &value) in receipts_trie_root_before_keys
|
||||
.clone()
|
||||
.zip_eq(&h256_limbs::<F>(
|
||||
public_values.trie_roots_before.receipts_root,
|
||||
))
|
||||
{
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
let state_trie_root_after_keys =
|
||||
TrieRootsTarget::SIZE..TrieRootsTarget::SIZE + TrieRootsTarget::HASH_SIZE;
|
||||
let mut nonzero_pis = HashMap::new();
|
||||
for (key, &value) in state_trie_root_after_keys
|
||||
.zip_eq(&h256_limbs::<F>(public_values.trie_roots_before.state_root))
|
||||
{
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
|
||||
// Initialize the genesis state trie digest.
|
||||
let genesis_state_trie_keys =
|
||||
// Initialize the checkpoint state root extra data.
|
||||
let checkpoint_state_trie_keys =
|
||||
TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE + BlockHashesTarget::SIZE
|
||||
..TrieRootsTarget::SIZE * 2
|
||||
+ BlockMetadataTarget::SIZE
|
||||
+ BlockHashesTarget::SIZE
|
||||
+ 8;
|
||||
for (key, &value) in genesis_state_trie_keys.zip_eq(&h256_limbs::<F>(
|
||||
public_values.extra_block_data.genesis_state_trie_root,
|
||||
for (key, &value) in checkpoint_state_trie_keys.zip_eq(&h256_limbs::<F>(
|
||||
public_values.extra_block_data.checkpoint_state_trie_root,
|
||||
)) {
|
||||
nonzero_pis.insert(key, value);
|
||||
}
|
||||
|
||||
// Initialize block hashes.
|
||||
// Initialize checkpoint block hashes.
|
||||
// These will be all zeros the initial genesis checkpoint.
|
||||
let block_hashes_keys = TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE
|
||||
..TrieRootsTarget::SIZE * 2 + BlockMetadataTarget::SIZE + BlockHashesTarget::SIZE
|
||||
- 8;
|
||||
@ -1130,6 +1180,14 @@ where
|
||||
nonzero_pis.insert(block_hashes_current_start + i, cur_targets[i]);
|
||||
}
|
||||
|
||||
// Initialize the checkpoint block number.
|
||||
// Subtraction would result in an invalid proof for genesis, but we shouldn't try proving this block anyway.
|
||||
let block_number_key = TrieRootsTarget::SIZE * 2 + 6;
|
||||
nonzero_pis.insert(
|
||||
block_number_key,
|
||||
F::from_canonical_u64(public_values.block_metadata.block_number.low_u64() - 1),
|
||||
);
|
||||
|
||||
block_inputs.set_proof_with_pis_target(
|
||||
&self.block.parent_block_proof,
|
||||
&cyclic_base_proof(
|
||||
@ -1145,13 +1203,26 @@ where
|
||||
block_inputs
|
||||
.set_verifier_data_target(&self.block.cyclic_vk, &self.block.circuit.verifier_only);
|
||||
|
||||
set_public_value_targets(&mut block_inputs, &self.block.public_values, &public_values)
|
||||
.map_err(|_| {
|
||||
anyhow::Error::msg("Invalid conversion when setting public values targets.")
|
||||
})?;
|
||||
// This is basically identical to this block public values, apart from the `trie_roots_before`
|
||||
// that may come from the previous proof, if any.
|
||||
let block_public_values = PublicValues {
|
||||
trie_roots_before: opt_parent_block_proof
|
||||
.map(|p| TrieRoots::from_public_inputs(&p.public_inputs[0..TrieRootsTarget::SIZE]))
|
||||
.unwrap_or(public_values.trie_roots_before),
|
||||
..public_values
|
||||
};
|
||||
|
||||
set_public_value_targets(
|
||||
&mut block_inputs,
|
||||
&self.block.public_values,
|
||||
&block_public_values,
|
||||
)
|
||||
.map_err(|_| {
|
||||
anyhow::Error::msg("Invalid conversion when setting public values targets.")
|
||||
})?;
|
||||
|
||||
let block_proof = self.block.circuit.prove(block_inputs)?;
|
||||
Ok((block_proof, public_values))
|
||||
Ok((block_proof, block_public_values))
|
||||
}
|
||||
|
||||
pub fn verify_block(&self, block_proof: &ProofWithPublicInputs<F, C, D>) -> anyhow::Result<()> {
|
||||
|
||||
@ -50,8 +50,11 @@ pub struct GenerationInputs {
|
||||
pub tries: TrieInputs,
|
||||
/// Expected trie roots after the transactions are executed.
|
||||
pub trie_roots_after: TrieRoots,
|
||||
/// State trie root of the genesis block.
|
||||
pub genesis_state_trie_root: H256,
|
||||
|
||||
/// State trie root of the checkpoint block.
|
||||
/// This could always be the genesis block of the chain, but it allows a prover to continue proving blocks
|
||||
/// from certain checkpoint heights without requiring proofs for blocks past this checkpoint.
|
||||
pub checkpoint_state_trie_root: H256,
|
||||
|
||||
/// Mapping between smart contract code hashes and the contract byte code.
|
||||
/// All account smart contracts that are invoked will have an entry present.
|
||||
@ -218,7 +221,7 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
|
||||
|
||||
let trie_root_ptrs = state.trie_root_ptrs;
|
||||
let extra_block_data = ExtraBlockData {
|
||||
genesis_state_trie_root: inputs.genesis_state_trie_root,
|
||||
checkpoint_state_trie_root: inputs.checkpoint_state_trie_root,
|
||||
txn_number_before: inputs.txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before: inputs.gas_used_before,
|
||||
|
||||
@ -104,7 +104,7 @@ fn observe_extra_block_data<
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
extra_data: &ExtraBlockData,
|
||||
) -> Result<(), ProgramError> {
|
||||
challenger.observe_elements(&h256_limbs(extra_data.genesis_state_trie_root));
|
||||
challenger.observe_elements(&h256_limbs(extra_data.checkpoint_state_trie_root));
|
||||
challenger.observe_element(u256_to_u32(extra_data.txn_number_before)?);
|
||||
challenger.observe_element(u256_to_u32(extra_data.txn_number_after)?);
|
||||
challenger.observe_element(u256_to_u32(extra_data.gas_used_before)?);
|
||||
@ -123,7 +123,7 @@ fn observe_extra_block_data_target<
|
||||
) where
|
||||
C::Hasher: AlgebraicHasher<F>,
|
||||
{
|
||||
challenger.observe_elements(&extra_data.genesis_state_trie_root);
|
||||
challenger.observe_elements(&extra_data.checkpoint_state_trie_root);
|
||||
challenger.observe_element(extra_data.txn_number_before);
|
||||
challenger.observe_element(extra_data.txn_number_after);
|
||||
challenger.observe_element(extra_data.gas_used_before);
|
||||
|
||||
@ -232,8 +232,8 @@ impl BlockMetadata {
|
||||
/// unlike `BlockMetadata`.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct ExtraBlockData {
|
||||
/// The state trie digest of the genesis block.
|
||||
pub genesis_state_trie_root: H256,
|
||||
/// The state trie digest of the checkpoint block.
|
||||
pub checkpoint_state_trie_root: H256,
|
||||
/// The transaction count prior execution of the local state transition, starting
|
||||
/// at 0 for the initial transaction of a block.
|
||||
pub txn_number_before: U256,
|
||||
@ -251,14 +251,14 @@ impl ExtraBlockData {
|
||||
pub fn from_public_inputs<F: RichField>(pis: &[F]) -> Self {
|
||||
assert!(pis.len() == ExtraBlockDataTarget::SIZE);
|
||||
|
||||
let genesis_state_trie_root = get_h256(&pis[0..8]);
|
||||
let checkpoint_state_trie_root = get_h256(&pis[0..8]);
|
||||
let txn_number_before = pis[8].to_canonical_u64().into();
|
||||
let txn_number_after = pis[9].to_canonical_u64().into();
|
||||
let gas_used_before = pis[10].to_canonical_u64().into();
|
||||
let gas_used_after = pis[11].to_canonical_u64().into();
|
||||
|
||||
Self {
|
||||
genesis_state_trie_root,
|
||||
checkpoint_state_trie_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
@ -338,13 +338,13 @@ impl PublicValuesTarget {
|
||||
buffer.write_target_array(&cur_hash)?;
|
||||
|
||||
let ExtraBlockDataTarget {
|
||||
genesis_state_trie_root: genesis_state_root,
|
||||
checkpoint_state_trie_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
gas_used_after,
|
||||
} = self.extra_block_data;
|
||||
buffer.write_target_array(&genesis_state_root)?;
|
||||
buffer.write_target_array(&checkpoint_state_trie_root)?;
|
||||
buffer.write_target(txn_number_before)?;
|
||||
buffer.write_target(txn_number_after)?;
|
||||
buffer.write_target(gas_used_before)?;
|
||||
@ -386,7 +386,7 @@ impl PublicValuesTarget {
|
||||
};
|
||||
|
||||
let extra_block_data = ExtraBlockDataTarget {
|
||||
genesis_state_trie_root: buffer.read_target_array()?,
|
||||
checkpoint_state_trie_root: buffer.read_target_array()?,
|
||||
txn_number_before: buffer.read_target()?,
|
||||
txn_number_after: buffer.read_target()?,
|
||||
gas_used_before: buffer.read_target()?,
|
||||
@ -740,8 +740,8 @@ impl BlockHashesTarget {
|
||||
/// unlike `BlockMetadata`.
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
||||
pub(crate) struct ExtraBlockDataTarget {
|
||||
/// `Target`s for the state trie digest of the genesis block.
|
||||
pub genesis_state_trie_root: [Target; 8],
|
||||
/// `Target`s for the state trie digest of the checkpoint block.
|
||||
pub checkpoint_state_trie_root: [Target; 8],
|
||||
/// `Target` for the transaction count prior execution of the local state transition, starting
|
||||
/// at 0 for the initial trnasaction of a block.
|
||||
pub txn_number_before: Target,
|
||||
@ -762,14 +762,14 @@ impl ExtraBlockDataTarget {
|
||||
/// Extracts the extra block data `Target`s from the public input `Target`s.
|
||||
/// The provided `pis` should start with the extra vblock data.
|
||||
pub(crate) fn from_public_inputs(pis: &[Target]) -> Self {
|
||||
let genesis_state_trie_root = pis[0..8].try_into().unwrap();
|
||||
let checkpoint_state_trie_root = pis[0..8].try_into().unwrap();
|
||||
let txn_number_before = pis[8];
|
||||
let txn_number_after = pis[9];
|
||||
let gas_used_before = pis[10];
|
||||
let gas_used_after = pis[11];
|
||||
|
||||
Self {
|
||||
genesis_state_trie_root,
|
||||
checkpoint_state_trie_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
@ -786,11 +786,11 @@ impl ExtraBlockDataTarget {
|
||||
ed1: Self,
|
||||
) -> Self {
|
||||
Self {
|
||||
genesis_state_trie_root: core::array::from_fn(|i| {
|
||||
checkpoint_state_trie_root: core::array::from_fn(|i| {
|
||||
builder.select(
|
||||
condition,
|
||||
ed0.genesis_state_trie_root[i],
|
||||
ed1.genesis_state_trie_root[i],
|
||||
ed0.checkpoint_state_trie_root[i],
|
||||
ed1.checkpoint_state_trie_root[i],
|
||||
)
|
||||
}),
|
||||
txn_number_before: builder.select(
|
||||
@ -812,8 +812,8 @@ impl ExtraBlockDataTarget {
|
||||
) {
|
||||
for i in 0..8 {
|
||||
builder.connect(
|
||||
ed0.genesis_state_trie_root[i],
|
||||
ed1.genesis_state_trie_root[i],
|
||||
ed0.checkpoint_state_trie_root[i],
|
||||
ed1.checkpoint_state_trie_root[i],
|
||||
);
|
||||
}
|
||||
builder.connect(ed0.txn_number_before, ed1.txn_number_before);
|
||||
|
||||
@ -712,13 +712,13 @@ pub(crate) fn add_virtual_block_hashes<F: RichField + Extendable<D>, const D: us
|
||||
pub(crate) fn add_virtual_extra_block_data<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtraBlockDataTarget {
|
||||
let genesis_state_trie_root = builder.add_virtual_public_input_arr();
|
||||
let checkpoint_state_trie_root = builder.add_virtual_public_input_arr();
|
||||
let txn_number_before = builder.add_virtual_public_input();
|
||||
let txn_number_after = builder.add_virtual_public_input();
|
||||
let gas_used_before = builder.add_virtual_public_input();
|
||||
let gas_used_after = builder.add_virtual_public_input();
|
||||
ExtraBlockDataTarget {
|
||||
genesis_state_trie_root,
|
||||
checkpoint_state_trie_root,
|
||||
txn_number_before,
|
||||
txn_number_after,
|
||||
gas_used_before,
|
||||
@ -979,8 +979,8 @@ where
|
||||
W: Witness<F>,
|
||||
{
|
||||
witness.set_target_arr(
|
||||
&ed_target.genesis_state_trie_root,
|
||||
&h256_limbs::<F>(ed.genesis_state_trie_root),
|
||||
&ed_target.checkpoint_state_trie_root,
|
||||
&h256_limbs::<F>(ed.checkpoint_state_trie_root),
|
||||
);
|
||||
witness.set_target(
|
||||
ed_target.txn_number_before,
|
||||
|
||||
@ -157,7 +157,7 @@ fn add11_yml() -> anyhow::Result<()> {
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
block_metadata,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
gas_used_after: 0xa868u64.into(),
|
||||
|
||||
@ -188,7 +188,7 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -63,7 +63,7 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
},
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -164,7 +164,7 @@ fn test_erc20() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -221,7 +221,7 @@ fn test_log_opcodes() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
@ -324,7 +324,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
to_second_nibbles,
|
||||
rlp::encode(&to_account_second_before).to_vec(),
|
||||
);
|
||||
let genesis_state_trie_root = state_trie_before.hash();
|
||||
let checkpoint_state_trie_root = state_trie_before.hash();
|
||||
|
||||
let tries_before = TrieInputs {
|
||||
state_trie: state_trie_before,
|
||||
@ -335,7 +335,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
|
||||
let txn = hex!("f85f800a82520894095e7baea6a6c7c4c2dfeb977efac326af552d870a8026a0122f370ed4023a6c253350c6bfb87d7d7eb2cd86447befee99e0a26b70baec20a07100ab1b3977f2b4571202b9f4b68850858caf5469222794600b5ce1cfb348ad");
|
||||
|
||||
let block_metadata = BlockMetadata {
|
||||
let block_1_metadata = BlockMetadata {
|
||||
block_beneficiary: Address::from(beneficiary),
|
||||
block_timestamp: 0x03e8.into(),
|
||||
block_number: 1.into(),
|
||||
@ -420,27 +420,31 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
receipts_root: receipts_trie.clone().hash(),
|
||||
};
|
||||
|
||||
let block_1_hash =
|
||||
H256::from_str("0x0101010101010101010101010101010101010101010101010101010101010101")?;
|
||||
let mut block_hashes = vec![H256::default(); 256];
|
||||
|
||||
let inputs_first = GenerationInputs {
|
||||
signed_txn: Some(txn.to_vec()),
|
||||
withdrawals: vec![],
|
||||
tries: tries_before,
|
||||
trie_roots_after: tries_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root,
|
||||
block_metadata: block_metadata.clone(),
|
||||
checkpoint_state_trie_root,
|
||||
block_metadata: block_1_metadata.clone(),
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
gas_used_after: 21000u64.into(),
|
||||
block_hashes: BlockHashes {
|
||||
prev_hashes: vec![H256::default(); 256],
|
||||
cur_hash: H256::default(),
|
||||
prev_hashes: block_hashes.clone(),
|
||||
cur_hash: block_1_hash,
|
||||
},
|
||||
};
|
||||
|
||||
// Preprocess all circuits.
|
||||
let all_circuits = AllRecursiveCircuits::<F, C, D>::new(
|
||||
&all_stark,
|
||||
&[16..17, 14..16, 16..18, 14..15, 9..10, 12..13, 19..20],
|
||||
&[16..17, 13..16, 15..18, 14..15, 9..10, 12..13, 17..20],
|
||||
&config,
|
||||
);
|
||||
|
||||
@ -539,8 +543,10 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
|
||||
transactions_trie.insert(Nibbles::from_str("0x01").unwrap(), txn_2.to_vec());
|
||||
|
||||
let block_1_state_root = expected_state_trie_after.hash();
|
||||
|
||||
let trie_roots_after = TrieRoots {
|
||||
state_root: expected_state_trie_after.hash(),
|
||||
state_root: block_1_state_root,
|
||||
transactions_root: transactions_trie.hash(),
|
||||
receipts_root: receipts_trie.hash(),
|
||||
};
|
||||
@ -549,16 +555,16 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
signed_txn: Some(txn_2.to_vec()),
|
||||
withdrawals: vec![],
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
trie_roots_after: trie_roots_after.clone(),
|
||||
contract_code,
|
||||
genesis_state_trie_root,
|
||||
block_metadata,
|
||||
checkpoint_state_trie_root,
|
||||
block_metadata: block_1_metadata,
|
||||
txn_number_before: 1.into(),
|
||||
gas_used_before: gas_used_second,
|
||||
gas_used_after: receipt.cum_gas_used,
|
||||
block_hashes: BlockHashes {
|
||||
prev_hashes: vec![H256::default(); 256],
|
||||
cur_hash: H256::default(),
|
||||
prev_hashes: block_hashes.clone(),
|
||||
cur_hash: block_1_hash,
|
||||
},
|
||||
};
|
||||
|
||||
@ -578,9 +584,77 @@ fn test_log_with_aggreg() -> anyhow::Result<()> {
|
||||
public_values_second,
|
||||
)?;
|
||||
all_circuits.verify_aggregation(&agg_proof)?;
|
||||
let (block_proof, _block_public_values) =
|
||||
let (first_block_proof, _block_public_values) =
|
||||
all_circuits.prove_block(None, &agg_proof, updated_agg_public_values)?;
|
||||
all_circuits.verify_block(&block_proof)
|
||||
all_circuits.verify_block(&first_block_proof)?;
|
||||
|
||||
// Prove the next, empty block.
|
||||
|
||||
let block_2_hash =
|
||||
H256::from_str("0x0123456789101112131415161718192021222324252627282930313233343536")?;
|
||||
block_hashes[255] = block_1_hash;
|
||||
|
||||
let block_2_metadata = BlockMetadata {
|
||||
block_beneficiary: Address::from(beneficiary),
|
||||
block_timestamp: 0x03e8.into(),
|
||||
block_number: 2.into(),
|
||||
block_difficulty: 0x020000.into(),
|
||||
block_gaslimit: 0x445566u32.into(),
|
||||
block_chain_id: 1.into(),
|
||||
block_base_fee: 0xa.into(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut contract_code = HashMap::new();
|
||||
contract_code.insert(keccak(vec![]), vec![]);
|
||||
|
||||
let inputs = GenerationInputs {
|
||||
signed_txn: None,
|
||||
withdrawals: vec![],
|
||||
tries: TrieInputs {
|
||||
state_trie: expected_state_trie_after,
|
||||
transactions_trie: Node::Empty.into(),
|
||||
receipts_trie: Node::Empty.into(),
|
||||
storage_tries: vec![],
|
||||
},
|
||||
trie_roots_after: TrieRoots {
|
||||
state_root: trie_roots_after.state_root,
|
||||
transactions_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
receipts_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
},
|
||||
contract_code,
|
||||
checkpoint_state_trie_root: block_1_state_root, // We use block 1 as new checkpoint.
|
||||
block_metadata: block_2_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
gas_used_after: 0.into(),
|
||||
block_hashes: BlockHashes {
|
||||
prev_hashes: block_hashes,
|
||||
cur_hash: block_2_hash,
|
||||
},
|
||||
};
|
||||
|
||||
let (root_proof, public_values) =
|
||||
all_circuits.prove_root(&all_stark, &config, inputs, &mut timing)?;
|
||||
all_circuits.verify_root(root_proof.clone())?;
|
||||
|
||||
// We can just duplicate the initial proof as the state didn't change.
|
||||
let (agg_proof, updated_agg_public_values) = all_circuits.prove_aggregation(
|
||||
false,
|
||||
&root_proof,
|
||||
public_values.clone(),
|
||||
false,
|
||||
&root_proof,
|
||||
public_values,
|
||||
)?;
|
||||
all_circuits.verify_aggregation(&agg_proof)?;
|
||||
|
||||
let (second_block_proof, _block_public_values) = all_circuits.prove_block(
|
||||
None, // We don't specify a previous proof, considering block 1 as the new checkpoint.
|
||||
&agg_proof,
|
||||
updated_agg_public_values,
|
||||
)?;
|
||||
all_circuits.verify_block(&second_block_proof)
|
||||
}
|
||||
|
||||
/// Values taken from the block 1000000 of Goerli: https://goerli.etherscan.io/txs?block=1000000
|
||||
|
||||
@ -175,7 +175,7 @@ fn self_balance_gas_cost() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -127,7 +127,7 @@ fn test_selfdestruct() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -143,7 +143,7 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
tries: tries_before,
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
@ -73,7 +73,7 @@ fn test_withdrawals() -> anyhow::Result<()> {
|
||||
},
|
||||
trie_roots_after,
|
||||
contract_code,
|
||||
genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(),
|
||||
block_metadata,
|
||||
txn_number_before: 0.into(),
|
||||
gas_used_before: 0.into(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user