Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Prepare protocol circuits for batch rollup #7727

Merged
merged 31 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c49bd33
feat: first run at nr changes for batch rollup
MirandaWood Jul 30, 2024
358c7b3
feat: add ts types, structs, tests (not yet impl in orch)
MirandaWood Jul 31, 2024
9b288e3
feat: handle vks for block root and block merge circuits
MirandaWood Aug 1, 2024
c740c10
chore: small fixes, cleanup, inject prev block hash
MirandaWood Aug 1, 2024
8859550
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 2, 2024
c031a20
chore: fmt, cleanup after adding prover_id via merge
MirandaWood Aug 2, 2024
6b97c3a
chore: better comments, more root -> block_root renaming, add new cir…
MirandaWood Aug 2, 2024
56c01ac
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 5, 2024
df113ce
feat: clean fee throw, add prev_block_hash to root pub inputs
MirandaWood Aug 5, 2024
b064be0
chore: fix for tests, more root -> block root renaming, comments
MirandaWood Aug 7, 2024
951981f
feat: accumulate fees, test, add more clarity comments
MirandaWood Aug 8, 2024
d84984e
feat: verify block root proofs on L1, add prover id to PIs
MirandaWood Aug 9, 2024
381da05
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 9, 2024
930ebea
feat: add vk root to final root rollup inputs, fix typo
MirandaWood Aug 12, 2024
82aa39a
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 12, 2024
abfca2b
feat: L1 process stores block hash, remove unused code
MirandaWood Aug 12, 2024
b23e646
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 12, 2024
605e192
fix: update eth log handlers, revert fee acc, some comments
MirandaWood Aug 13, 2024
644173b
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 13, 2024
eb3e283
fix: add epoch to block root/merge methods post merge
MirandaWood Aug 13, 2024
bb4815d
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 13, 2024
1f114aa
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 13, 2024
6d37433
feat: fixes after merge, use blockroot artifact, add proving todos
MirandaWood Aug 19, 2024
117d9d3
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 19, 2024
ef2a883
fix: post merge fixes
MirandaWood Aug 19, 2024
3127243
chore: forge fmt
MirandaWood Aug 19, 2024
3e2f55f
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 19, 2024
a657e05
fix: post merge fixes to publisher
MirandaWood Aug 19, 2024
bc17e45
chore: cleanup opt chaining in orchestrator
MirandaWood Aug 22, 2024
99064a1
Merge remote-tracking branch 'origin' into mw/batch-rollup
MirandaWood Aug 22, 2024
388bce3
chore: fmt + fix post merge
MirandaWood Aug 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ library Constants {
uint256 internal constant ROOT_PARITY_INDEX = 19;
uint256 internal constant BASE_ROLLUP_INDEX = 20;
uint256 internal constant MERGE_ROLLUP_INDEX = 21;
uint256 internal constant ROOT_ROLLUP_INDEX = 22;
uint256 internal constant BLOCK_ROOT_ROLLUP_INDEX = 22;
uint256 internal constant BLOCK_MERGE_ROLLUP_INDEX = 23;
uint256 internal constant ROOT_ROLLUP_INDEX = 24;
uint256 internal constant FUNCTION_SELECTOR_NUM_BYTES = 4;
uint256 internal constant ARGS_HASH_CHUNK_LENGTH = 16;
uint256 internal constant ARGS_HASH_CHUNK_COUNT = 16;
Expand Down Expand Up @@ -193,6 +195,7 @@ library Constants {
uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 415;
uint256 internal constant CONSTANT_ROLLUP_DATA_LENGTH = 11;
uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 28;
uint256 internal constant BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH = 88;
uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674;
uint256 internal constant NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048;
uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048;
Expand Down
2 changes: 2 additions & 0 deletions noir-projects/noir-protocol-circuits/Nargo.template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ members = [
"crates/rollup-merge",
"crates/rollup-base",
"crates/rollup-base-simulated",
"crates/rollup-block-merge",
"crates/rollup-block-root",
"crates/rollup-root",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "rollup_block_merge"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
rollup_lib = { path = "../rollup-lib" }
types = { path = "../types" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use dep::rollup_lib::block_merge::{BlockMergeRollupInputs, BlockRootOrBlockMergePublicInputs};

fn main(inputs: BlockMergeRollupInputs) -> pub BlockRootOrBlockMergePublicInputs {
inputs.block_merge_rollup_circuit()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "rollup_block_root"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
rollup_lib = { path = "../rollup-lib" }
types = { path = "../types" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use dep::rollup_lib::block_root::{BlockRootRollupInputs, BlockRootOrBlockMergePublicInputs};

fn main(inputs: BlockRootRollupInputs) -> pub BlockRootOrBlockMergePublicInputs {
inputs.block_root_rollup_circuit()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use dep::types::{
abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot, global_variables::GlobalVariables},
constants::BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH,
partial_state_reference::PartialStateReference, traits::{Empty, Serialize, Deserialize},
utils::reader::Reader, address::EthAddress
};
use crate::abis::constant_rollup_data::ConstantRollupData;

struct FeeRecipient {
recipient: EthAddress,
value: Field,
}

impl Empty for FeeRecipient {
fn empty() -> Self {
FeeRecipient {
recipient: EthAddress::zero(),
value: 0,
}
}
}

impl Serialize<2> for FeeRecipient {
fn serialize(self) -> [Field; 2] {
[self.recipient.to_field(), self.value]
}
}

impl Deserialize<2> for FeeRecipient {
fn deserialize(values: [Field; 2]) -> Self {
Self {
recipient: EthAddress::from_field(values[0]),
value: values[1]
}
}
}

impl Eq for FeeRecipient {
fn eq(self, other: Self) -> bool {
(self.recipient.eq(other.recipient)) & (self.value == other.value)
}
}

// TODO: instead of archives + global vars, use ConstantRollupData x2? It also includes vk root
// may be confusing as new_constant.last_archive would actually be the new_archive
struct BlockRootOrBlockMergePublicInputs {
previous_archive: AppendOnlyTreeSnapshot, // Archive tree root immediately before this block range
new_archive: AppendOnlyTreeSnapshot, // Archive tree root after adding this block range
previous_block_hash: Field, // Identifier of the previous block before the range
end_block_hash: Field, // Identifier of the last block in the range
start_global_variables: GlobalVariables, // Global variables for the first block in the range
end_global_variables: GlobalVariables, // Global variables for the last block in the range
out_hash: Field, // Merkle node of the L2-to-L1 messages merkle roots in the block range
fees: [FeeRecipient; 32], // Concatenation of all coinbase and fees for the block range
vk_tree_root: Field, // Root of allowed vk tree
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not mentioned in engineering-designs doc - added the vk tree root to check for allowed circuits in future.

}

impl Empty for BlockRootOrBlockMergePublicInputs {
fn empty() -> Self {
BlockRootOrBlockMergePublicInputs {
previous_archive: AppendOnlyTreeSnapshot::zero(),
new_archive: AppendOnlyTreeSnapshot::zero(),
previous_block_hash: 0,
end_block_hash: 0,
start_global_variables: GlobalVariables::empty(),
end_global_variables: GlobalVariables::empty(),
out_hash: 0,
fees: [FeeRecipient::empty(); 32],
vk_tree_root: 0,
}
}
}

impl Eq for BlockRootOrBlockMergePublicInputs {
fn eq(self, other: Self) -> bool {
(self.previous_archive.eq(other.previous_archive)) &
(self.new_archive.eq(other.new_archive)) &
(self.previous_block_hash == other.previous_block_hash) &
(self.end_block_hash == other.end_block_hash) &
(self.start_global_variables.eq(other.start_global_variables)) &
(self.end_global_variables.eq(other.end_global_variables)) &
(self.out_hash == other.out_hash) &
(self.fees.eq(other.fees)) &
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know that Noir handled array equality, nice!

(self.vk_tree_root == other.vk_tree_root)
}
}

impl Serialize<BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH> for BlockRootOrBlockMergePublicInputs {
fn serialize(self) -> [Field; BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH] {
let mut fields: BoundedVec<Field, BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH> = BoundedVec::new();

fields.extend_from_array(self.previous_archive.serialize());
fields.extend_from_array(self.new_archive.serialize());
fields.push(self.previous_block_hash as Field);
fields.push(self.end_block_hash as Field);
fields.extend_from_array(self.start_global_variables.serialize());
fields.extend_from_array(self.end_global_variables.serialize());
fields.push(self.out_hash as Field);
for i in 0..32 {
fields.extend_from_array(self.fees[i].serialize());
}
fields.push(self.vk_tree_root as Field);
assert_eq(fields.len(), BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH);

fields.storage
}
}

impl Deserialize<BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH> for BlockRootOrBlockMergePublicInputs {
fn deserialize(fields: [Field; BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH]) -> BlockRootOrBlockMergePublicInputs {
let mut reader = Reader::new(fields);
let item = Self {
previous_archive: reader.read_struct(AppendOnlyTreeSnapshot::deserialize),
new_archive: reader.read_struct(AppendOnlyTreeSnapshot::deserialize),
previous_block_hash: reader.read(),
end_block_hash: reader.read(),
start_global_variables: reader.read_struct(GlobalVariables::deserialize),
end_global_variables: reader.read_struct(GlobalVariables::deserialize),
out_hash: reader.read(),
fees: reader.read_struct_array(FeeRecipient::deserialize, [FeeRecipient::empty(); 32]),
vk_tree_root: reader.read(),
};

reader.finish();
item
}
}

#[test]
fn serialization_of_empty() {
let item = BlockRootOrBlockMergePublicInputs::empty();
let serialized = item.serialize();
let deserialized = BlockRootOrBlockMergePublicInputs::deserialize(serialized);
assert(item.eq(deserialized));
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod constant_rollup_data;
mod base_or_merge_rollup_public_inputs;
mod block_root_or_block_merge_public_inputs;
mod previous_rollup_data;
mod previous_rollup_block_data;
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::abis::block_root_or_block_merge_public_inputs::BlockRootOrBlockMergePublicInputs;
use dep::types::{
constants::VK_TREE_HEIGHT,
recursion::{proof::NestedRecursiveProof, verification_key::VerificationKey, traits::Verifiable},
traits::Empty, merkle_tree::MembershipWitness, merkle_tree::membership::assert_check_membership,
utils::arrays::find_index_hint
};

struct PreviousRollupBlockData {
block_root_or_block_merge_public_inputs: BlockRootOrBlockMergePublicInputs,
proof: NestedRecursiveProof,
vk: VerificationKey,
vk_witness: MembershipWitness<VK_TREE_HEIGHT>,
}

impl Verifiable for PreviousRollupBlockData {
fn verify(self) {
let inputs = BlockRootOrBlockMergePublicInputs::serialize(self.block_root_or_block_merge_public_inputs);
std::verify_proof(
self.vk.key.as_slice(),
self.proof.fields.as_slice(),
inputs.as_slice(),
self.vk.hash
);
}
}

impl Empty for PreviousRollupBlockData {
fn empty() -> Self {
PreviousRollupBlockData {
block_root_or_block_merge_public_inputs: BlockRootOrBlockMergePublicInputs::empty(),
proof: NestedRecursiveProof::empty(),
vk: VerificationKey::empty(),
vk_witness: MembershipWitness::empty(),
}
}
}

impl PreviousRollupBlockData {
fn validate_in_vk_tree<N>(self, allowed_indices: [u32; N]) {
let index_hint = find_index_hint(allowed_indices, self.vk_witness.leaf_index as u32);
assert_eq(allowed_indices[index_hint], self.vk_witness.leaf_index as u32, "Invalid vk index");

assert_check_membership(
self.vk.hash,
self.vk_witness.leaf_index,
self.vk_witness.sibling_path,
self.block_root_or_block_merge_public_inputs.vk_tree_root
);
}
}
Loading