Add Checkpoint heights (#1418)

This commit is contained in:
Robin Salen 2023-12-09 06:26:55 +01:00 committed by GitHub
parent 5607faf36b
commit bfcfcdb498
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 233 additions and 85 deletions

View File

@ -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<()> {

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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(),

View File

@ -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(),

View File

@ -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(),

View File

@ -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(),

View File

@ -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

View File

@ -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(),

View File

@ -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(),

View File

@ -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(),

View File

@ -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(),