Skip to content

Commit f55dbad

Browse files
committed
Refactor and tests.
1 parent f11d8da commit f55dbad

File tree

264 files changed

+12291
-9987
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

264 files changed

+12291
-9987
lines changed

noir-projects/mock-protocol-circuits/Nargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ members = [
88
"crates/mock-private-kernel-inner",
99
"crates/mock-private-kernel-reset",
1010
"crates/mock-private-kernel-tail",
11-
"crates/mock-rollup-base-private",
12-
"crates/mock-rollup-base-public",
13-
"crates/mock-rollup-merge",
11+
"crates/mock-rollup-tx-base-private",
12+
"crates/mock-rollup-tx-base-public",
13+
"crates/mock-rollup-tx-merge",
1414
"crates/mock-rollup-root",
1515
]

noir-projects/mock-protocol-circuits/crates/mock-rollup-merge/Nargo.toml renamed to noir-projects/mock-protocol-circuits/crates/mock-rollup-tx-base-private/Nargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
[package]
2-
name = "mock_rollup_merge"
2+
name = "mock_rollup_tx_base_private"
33
type = "bin"
44
authors = [""]
55
compiler_version = ">=0.32.0"
66

77
[dependencies]
8-
types = { path = "../../../noir-protocol-circuits/crates/types" }
98
mock_types = { path = "../mock-types" }

noir-projects/mock-protocol-circuits/crates/mock-rollup-base-private/src/main.nr renamed to noir-projects/mock-protocol-circuits/crates/mock-rollup-tx-base-private/src/main.nr

File renamed without changes.

noir-projects/mock-protocol-circuits/crates/mock-rollup-base-private/Nargo.toml renamed to noir-projects/mock-protocol-circuits/crates/mock-rollup-tx-base-public/Nargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
[package]
2-
name = "mock_rollup_base_private"
2+
name = "mock_rollup_tx_base_public"
33
type = "bin"
44
authors = [""]
55
compiler_version = ">=0.32.0"
66

77
[dependencies]
8-
types = { path = "../../../noir-protocol-circuits/crates/types" }
98
mock_types = { path = "../mock-types" }

noir-projects/mock-protocol-circuits/crates/mock-rollup-base-public/src/main.nr renamed to noir-projects/mock-protocol-circuits/crates/mock-rollup-tx-base-public/src/main.nr

File renamed without changes.

noir-projects/mock-protocol-circuits/crates/mock-rollup-base-public/Nargo.toml renamed to noir-projects/mock-protocol-circuits/crates/mock-rollup-tx-merge/Nargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "mock_rollup_base_public"
2+
name = "mock_rollup_tx_merge"
33
type = "bin"
44
authors = [""]
55
compiler_version = ">=0.32.0"

noir-projects/mock-protocol-circuits/crates/mock-rollup-merge/src/main.nr renamed to noir-projects/mock-protocol-circuits/crates/mock-rollup-tx-merge/src/main.nr

File renamed without changes.

noir-projects/noir-protocol-circuits/Nargo.template.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ members = [
2222
"crates/hiding-kernel-to-public",
2323
"crates/tube-public",
2424
"crates/rollup-lib",
25-
"crates/rollup-merge",
26-
"crates/rollup-base-private",
27-
"crates/rollup-base-private-simulated",
28-
"crates/rollup-base-public",
29-
"crates/rollup-base-public-simulated",
30-
"crates/rollup-block-merge",
25+
"crates/rollup-tx-base-private",
26+
"crates/rollup-tx-base-private-simulated",
27+
"crates/rollup-tx-base-public",
28+
"crates/rollup-tx-base-public-simulated",
29+
"crates/rollup-tx-merge",
3130
"crates/rollup-block-root",
3231
"crates/rollup-block-root-simulated",
3332
"crates/rollup-block-root-first",
@@ -37,6 +36,7 @@ members = [
3736
"crates/rollup-block-root-first-single-tx",
3837
"crates/rollup-block-root-first-single-tx-simulated",
3938
"crates/rollup-block-root-first-empty-tx",
39+
"crates/rollup-block-merge",
4040
"crates/rollup-checkpoint-root",
4141
"crates/rollup-checkpoint-root-simulated",
4242
"crates/rollup-checkpoint-root-single-block",

noir-projects/noir-protocol-circuits/bootstrap.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ function test_cmds {
195195
private-kernel-reset
196196
private-kernel-tail-to-public
197197
private-kernel-tail
198-
rollup-base-private
199-
rollup-base-public
200-
rollup-merge
198+
rollup-tx-base-private
199+
rollup-tx-base-public
200+
rollup-tx-merge
201201
rollup-block-root-first
202202
rollup-block-root-first-single-tx
203203
rollup-block-root-first-empty-tx

noir-projects/noir-protocol-circuits/crates/blob/src/blob_batching.nr

Lines changed: 43 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{
77
};
88
use bigint::{BigNum, BLS12_381_Fr as F};
99
use types::{
10-
abis::sponge_blob::SpongeBlob, constants::FIELDS_PER_BLOB, hash::poseidon2_hash_subarray,
11-
traits::Empty, utils::arrays::array_splice,
10+
constants::FIELDS_PER_BLOB, hash::poseidon2_hash_subarray, traits::Empty,
11+
utils::arrays::array_splice,
1212
};
1313

1414
// Evaluates a single blob:
@@ -40,23 +40,24 @@ fn compute_blob_challenge(hashed_blobs_fields: Field, kzg_commitment: [Field; 2]
4040

4141
// Evaluates each blob required for a block:
4242
// - Hashes all fields in the block's blobs (to use for the challenges z_i)
43+
// - Checks that any fields above num_fields are empty (inside poseidon2_hash_subarray()).
4344
// - Compresses each of the blob's injected commitments (")
4445
// - Evaluates each blob individually to find its challenge z_i & evaluation y_i
4546
// - Updates the batched blob accumulator
4647
pub fn evaluate_blobs_and_batch<let NumBlobs: u32>(
4748
blobs_as_fields: [Field; FIELDS_PER_BLOB * NumBlobs],
49+
num_fields: u32,
4850
kzg_commitments_points: [BLSPoint; NumBlobs],
49-
mut sponge_blob: SpongeBlob,
5051
final_blob_challenges: FinalBlobBatchingChallenges,
5152
start_accumulator: BlobAccumulatorPublicInputs,
52-
) -> BlobAccumulatorPublicInputs {
53+
) -> (BlobAccumulatorPublicInputs, Field) {
5354
// See components.nr out_sponge definition as to why we copy here:
5455
let mut end_accumulator = start_accumulator;
5556
// Note that with multiple blobs per block, each blob uses the same hashed_blobs_fields in:
5657
// z_i = H(hashed_blobs_fields, kzg_commitment[0], kzg_commitment[1])
5758
// This is ok, because each commitment is unique to the blob, and we need hashed_blobs_fields to encompass
5859
// all fields in the blob, which it does.
59-
let hashed_blobs_fields = check_block_blob_sponge(blobs_as_fields, sponge_blob);
60+
let hashed_blobs_fields = poseidon2_hash_subarray(blobs_as_fields, num_fields);
6061
for i in 0..NumBlobs {
6162
let single_blob_fields = array_splice(blobs_as_fields, i * FIELDS_PER_BLOB);
6263
let c_i = compress_to_blob_commitment(kzg_commitments_points[i]);
@@ -69,7 +70,7 @@ pub fn evaluate_blobs_and_batch<let NumBlobs: u32>(
6970
// TODO(#14646): If the evaluation being zero is sufficient to say the blob i is empty, remove the range check.
7071
// The range check exists because we cannot use c_i (it's injected and L1 relies on this circuit to check whether the blob is
7172
// empty for c_i = O) or z_i (z_i relies on the hashed_blobs_fields, which is the hash of the items in ALL block blobs, not just i).
72-
let is_empty_blob = sponge_blob.fields <= i * FIELDS_PER_BLOB;
73+
let is_empty_blob = num_fields <= i * FIELDS_PER_BLOB;
7374
if (!y_i.is_zero()) & (!is_empty_blob) {
7475
// Only accumulate if the blob is non empty
7576
if (end_accumulator.is_empty()) & (i == 0) {
@@ -90,38 +91,15 @@ pub fn evaluate_blobs_and_batch<let NumBlobs: u32>(
9091
}
9192
}
9293
}
93-
end_accumulator
94-
}
95-
96-
// Validates this block's injected blob fields against the validated sponge propagated from the previous circuits:
97-
// - Checks that we haven't accumulated too many fields over the rollup
98-
// - Checks that we have absorbed the exact number of fields we claim to have accumulated
99-
// - Checks that the injected fields match the tx effects absorbed over the rollup
100-
// - Checks that any fields above expected_fields are empty (inside poseidon2_hash_subarray())
101-
fn check_block_blob_sponge<let N: u32>(
102-
blobs_as_fields: [Field; N],
103-
mut sponge_blob: SpongeBlob,
104-
) -> Field {
105-
// Check that we haven't overfilled the blobs
106-
assert(sponge_blob.expected_fields <= N, "Attempted to overfill blobs");
107-
// Check that the blob is full
108-
assert(
109-
sponge_blob.expected_fields == sponge_blob.fields,
110-
"Incorrect number of tx effects added to blob",
111-
);
112-
let sponge_hash = sponge_blob.squeeze();
113-
let hash = poseidon2_hash_subarray(blobs_as_fields, sponge_blob.fields);
114-
assert(hash == sponge_hash, "Mismatched hashed tx effects");
115-
116-
sponge_hash
94+
(end_accumulator, hashed_blobs_fields)
11795
}
11896

11997
mod tests {
12098
use crate::blob_batching_public_inputs::{
12199
BatchingBlobCommitment, BlobAccumulatorPublicInputs, compress_to_blob_commitment,
122100
FinalBlobBatchingChallenges,
123101
};
124-
use super::{check_block_blob_sponge, evaluate_blobs_and_batch};
102+
use super::evaluate_blobs_and_batch;
125103
use bigcurve::{BigCurve, curves::bls12_381::BLS12_381 as BLSPoint};
126104
use bigint::{BigNum, BLS12_381_Fr as F};
127105
use types::{
@@ -134,7 +112,7 @@ mod tests {
134112

135113
// All hardcoded values in this test are taken from yarn-project/foundation/src/blob/blob_batching.test.ts -> 'should construct and verify a batched blob of 400 items'
136114
#[test]
137-
unconstrained fn test_400_batched() {
115+
unconstrained fn test_1_blob_batched() {
138116
// We evaluate 1 blob of 400 items using the batch methods.
139117
// This ensures a block with a single blob will work:
140118
let mut blob: [Field; FIELDS_PER_BLOB] = [0; FIELDS_PER_BLOB];
@@ -143,6 +121,7 @@ mod tests {
143121
}
144122
let mut sponge_blob = SpongeBlob::new(400);
145123
sponge_blob.absorb(blob, 400);
124+
146125
let kzg_commitment_in = BatchingBlobCommitment::from_limbs(
147126
[
148127
0xa971c7e8d8292be943d05bccebcfea,
@@ -172,13 +151,16 @@ mod tests {
172151
]),
173152
};
174153
// Evaluation
175-
let res = evaluate_blobs_and_batch(
176-
pad_end(blob, 0),
154+
let (res, hashed_blobs_fields) = evaluate_blobs_and_batch(
155+
pad_end(blob),
156+
400,
177157
kzg_commitments_in,
178-
sponge_blob,
179158
final_challenges,
180159
BlobAccumulatorPublicInputs::empty(),
181160
);
161+
162+
assert_eq(hashed_blobs_fields, sponge_blob.squeeze());
163+
182164
let final_acc = res.finalize_and_validate(final_challenges);
183165

184166
assert_eq(final_acc.z, final_challenges.z);
@@ -207,16 +189,17 @@ mod tests {
207189
#[test]
208190
unconstrained fn test_full_blobs_batched() {
209191
// Fill three blobs completely with different values (to avoid a constant polynomial)
210-
let mut blob: [Field; FIELDS_PER_BLOB * BLOBS_PER_BLOCK] =
192+
let mut blob_fields: [Field; FIELDS_PER_BLOB * BLOBS_PER_BLOCK] =
211193
[0; FIELDS_PER_BLOB * BLOBS_PER_BLOCK];
212194
for j in 0..BLOBS_PER_BLOCK {
213195
for i in 0..FIELDS_PER_BLOB {
214-
blob[j * FIELDS_PER_BLOB + i] = ((j + 3) * (i + 1)) as Field;
196+
blob_fields[j * FIELDS_PER_BLOB + i] = ((j + 3) * (i + 1)) as Field;
215197
}
216198
}
217199
// Absorb the values into a sponge
218200
let mut sponge_blob = SpongeBlob::new(FIELDS_PER_BLOB * BLOBS_PER_BLOCK);
219-
sponge_blob.absorb(blob, FIELDS_PER_BLOB * BLOBS_PER_BLOCK);
201+
sponge_blob.absorb(blob_fields, FIELDS_PER_BLOB * BLOBS_PER_BLOCK);
202+
220203
// Init. injected values:
221204
// - Commitments are injected and checked for correctness on L1 via acc.v
222205
let kzg_commitments_in = [
@@ -280,13 +263,16 @@ mod tests {
280263
// Init. the accumulator
281264
let start_acc = BlobAccumulatorPublicInputs::empty();
282265
// Evaluate all three blobs and iteratively accumulate the results
283-
let output = evaluate_blobs_and_batch(
284-
blob,
266+
let (output, hashed_blobs_fields) = evaluate_blobs_and_batch(
267+
blob_fields,
268+
blob_fields.len(),
285269
kzg_commitments_in,
286-
sponge_blob,
287270
final_challenges,
288271
start_acc,
289272
);
273+
274+
assert_eq(hashed_blobs_fields, sponge_blob.squeeze());
275+
290276
// Finalize the output (actually done in the root circuit)
291277
let final_acc = output.finalize_and_validate(final_challenges);
292278

@@ -338,33 +324,28 @@ mod tests {
338324
blob[i] = 3;
339325
}
340326
// ...but the rollup's sponge is only expecting 45...
341-
let mut sponge_blob = SpongeBlob::new(45);
342-
sponge_blob.absorb(blob, 45);
327+
let num_fields = 45;
343328

344329
// ...so the below should fail as it detects we are adding effects which did not come from the rollup.
345-
let _ = super::check_block_blob_sponge(blob, sponge_blob);
346-
}
347-
348-
#[test(should_fail_with = "Incorrect number of tx effects added to blob")]
349-
unconstrained fn test_absorbed_too_few_blob_fields() {
350-
let mut blob = [0; FIELDS_PER_BLOB];
351-
// Fill fields with 50 inputs...
352-
for i in 0..50 {
353-
blob[i] = 3;
354-
}
355-
// ...but the rollup's sponge is expecting 100...
356-
let mut sponge_blob = SpongeBlob::new(100);
357-
sponge_blob.absorb(blob, 50);
358-
359-
// ...so the below should fail as it detects we have not added all the tx effects.
360-
let _ = check_block_blob_sponge(blob, sponge_blob);
330+
let _ = evaluate_blobs_and_batch(
331+
blob,
332+
num_fields,
333+
[BLSPoint::point_at_infinity()],
334+
FinalBlobBatchingChallenges::empty(),
335+
BlobAccumulatorPublicInputs::empty(),
336+
);
361337
}
362338

363339
#[test]
364340
unconstrained fn test_empty_blob() {
365-
let mut blob = [0; FIELDS_PER_BLOB];
366-
let mut sponge_blob = SpongeBlob::new(0);
341+
let blob = [0; FIELDS_PER_BLOB];
367342
// The below should not throw
368-
let _ = check_block_blob_sponge(blob, sponge_blob);
343+
let _ = evaluate_blobs_and_batch(
344+
blob,
345+
0,
346+
[BLSPoint::point_at_infinity()],
347+
FinalBlobBatchingChallenges::empty(),
348+
BlobAccumulatorPublicInputs::empty(),
349+
);
369350
}
370351
}

0 commit comments

Comments
 (0)