From 20a0a9e55f37c6b4892724fbd952db5e241578f7 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 25 Sep 2024 19:34:19 -0300 Subject: [PATCH] feat: Empty block root circuit Introduces a new circuit that outputs the same as block root but representing an empty block. To be used for padding epochs with only zero or one blocks. --- .../Nargo.template.toml | 1 + .../crates/rollup-block-root-empty/Nargo.toml | 9 +++++ .../rollup-block-root-empty/src/main.nr | 6 +++ ...block_root_or_block_merge_public_inputs.nr | 6 +++ .../empty_block_root_rollup_inputs.nr | 31 +++++++++++++++ .../crates/rollup-lib/src/block_root/mod.nr | 2 + .../crates/rollup-lib/src/components.nr | 38 +++++++++++++------ 7 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/Nargo.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/src/main.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr diff --git a/noir-projects/noir-protocol-circuits/Nargo.template.toml b/noir-projects/noir-protocol-circuits/Nargo.template.toml index 4aa888cb7e7d..9db35a94c9e2 100644 --- a/noir-projects/noir-protocol-circuits/Nargo.template.toml +++ b/noir-projects/noir-protocol-circuits/Nargo.template.toml @@ -34,6 +34,7 @@ members = [ "crates/rollup-base-simulated", "crates/rollup-block-merge", "crates/rollup-block-root", + "crates/rollup-block-root-empty", "crates/rollup-block-root-final", "crates/rollup-root", ] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/Nargo.toml new file mode 100644 index 000000000000..bef9a433e84a --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rollup_block_root_empty" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +rollup_lib = { path = "../rollup-lib" } +types = { path = "../types" } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/src/main.nr b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/src/main.nr new file mode 100644 index 000000000000..e2f80bb0ad2e --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-empty/src/main.nr @@ -0,0 +1,6 @@ +use rollup_lib::block_root::{EmptyBlockRootRollupInputs, BlockRootOrBlockMergePublicInputs}; + +#[recursive] +fn main(inputs: EmptyBlockRootRollupInputs) -> pub BlockRootOrBlockMergePublicInputs { + inputs.empty_block_root_rollup_circuit() +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr index 7fede7a1c1bc..707f674ae1c1 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr @@ -49,6 +49,12 @@ pub struct BlockRootOrBlockMergePublicInputs { prover_id: Field, // TODO(#7346): Temporarily added prover_id while we verify block-root proofs on L1 } +impl BlockRootOrBlockMergePublicInputs { + fn is_padding(self) -> bool { + self.previous_archive == self.new_archive + } +} + impl Empty for BlockRootOrBlockMergePublicInputs { fn empty() -> Self { BlockRootOrBlockMergePublicInputs { diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr new file mode 100644 index 000000000000..3ca5cb691a06 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr @@ -0,0 +1,31 @@ +use crate::abis::block_root_or_block_merge_public_inputs::BlockRootOrBlockMergePublicInputs; +use types::{abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot, global_variables::GlobalVariables}}; +use crate::abis::block_root_or_block_merge_public_inputs::FeeRecipient; + +pub struct EmptyBlockRootRollupInputs { + archive: AppendOnlyTreeSnapshot, + block_hash: Field, + global_variables: GlobalVariables, + out_hash: Field, + vk_tree_root: Field, + // TODO(#7346): Temporarily added prover_id while we verify block-root proofs on L1 + prover_id: Field, +} + +impl EmptyBlockRootRollupInputs { + pub fn empty_block_root_rollup_circuit(self) -> BlockRootOrBlockMergePublicInputs { + BlockRootOrBlockMergePublicInputs { + previous_archive: self.archive, + new_archive: self.archive, + previous_block_hash: self.block_hash, + end_block_hash: self.block_hash, + start_global_variables: self.global_variables, + end_global_variables: self.global_variables, + out_hash: self.out_hash, + fees: [FeeRecipient::empty(); 32], + vk_tree_root: self.vk_tree_root, + prover_id: self.prover_id + } + } +} + diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr index 71538bcb1f77..2c66ed17d6a3 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr @@ -1,7 +1,9 @@ mod block_root_rollup_inputs; +mod empty_block_root_rollup_inputs; // Re-exports pub use block_root_rollup_inputs::BlockRootRollupInputs; +pub use empty_block_root_rollup_inputs::EmptyBlockRootRollupInputs; pub use crate::abis::block_root_or_block_merge_public_inputs::BlockRootOrBlockMergePublicInputs; mod tests { diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr index d787969abd20..85e3debb8d10 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr @@ -92,12 +92,22 @@ pub fn assert_prev_block_rollups_follow_on_from_each_other( assert( left.end_global_variables.version == right.start_global_variables.version, "input blocks have different chain version" ); - assert( - left.end_global_variables.block_number + 1 == right.start_global_variables.block_number, "input block numbers do not follow on from each other" - ); - assert( - left.end_global_variables.timestamp < right.start_global_variables.timestamp, "input block timestamps do not follow on from each other" - ); + + if right.is_padding() { + assert( + left.end_global_variables.block_number == right.start_global_variables.block_number, "input block numbers do not match" + ); + assert( + left.end_global_variables.timestamp == right.start_global_variables.timestamp, "input block timestamps do not match" + ); + } else { + assert( + left.end_global_variables.block_number + 1 == right.start_global_variables.block_number, "input block numbers do not follow on from each other" + ); + assert( + left.end_global_variables.timestamp < right.start_global_variables.timestamp, "input block timestamps do not follow on from each other" + ); + } } pub fn accumulate_fees(left: BaseOrMergeRollupPublicInputs, right: BaseOrMergeRollupPublicInputs) -> Field { @@ -134,12 +144,16 @@ pub fn compute_out_hash(previous_rollup_data: [PreviousRollupData; 2]) -> Field } // TODO(Miranda): combine fns? pub fn compute_blocks_out_hash(previous_rollup_data: [PreviousRollupBlockData; 2]) -> Field { - accumulate_sha256( - [ - previous_rollup_data[0].block_root_or_block_merge_public_inputs.out_hash, - previous_rollup_data[1].block_root_or_block_merge_public_inputs.out_hash - ] - ) + if previous_rollup_data[1].block_root_or_block_merge_public_inputs.is_padding() { + previous_rollup_data[0].block_root_or_block_merge_public_inputs.out_hash + } else { + accumulate_sha256( + [ + previous_rollup_data[0].block_root_or_block_merge_public_inputs.out_hash, + previous_rollup_data[1].block_root_or_block_merge_public_inputs.out_hash + ] + ) + } } pub fn compute_kernel_out_hash(l2_to_l1_msgs: [Field; MAX_L2_TO_L1_MSGS_PER_TX]) -> Field {