-
Notifications
You must be signed in to change notification settings - Fork 595
feat: Goblin flush #22142
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
Open
federicobarbacovi
wants to merge
48
commits into
merge-train/barretenberg
Choose a base branch
from
fb/goblin_flush_impl
base: merge-train/barretenberg
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: Goblin flush #22142
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
ffb6e9a
IPA claim in IO
federicobarbacovi b394ec1
Goblin flush circuit
federicobarbacovi d9f1a0c
Implement ULTRA_GOBLIN opcode
federicobarbacovi fc54f89
Implement Goblin Kernel logic
federicobarbacovi 8ce7913
Goblin flush does not perform merge
federicobarbacovi 7691941
Use merged tables instead of T_prev and t
federicobarbacovi be0d7f4
Correct chonk logic (use GOBLIN type for entry corresponding to Gobli…
federicobarbacovi 282391d
Add mocking state for goblin flush
federicobarbacovi e9e6cc8
Reset op queue before merging goblin flush app ops
federicobarbacovi fa2cea8
Accumulate values match - ECCVM fails
federicobarbacovi f6d7a46
Trace checker
federicobarbacovi e0953f9
Goblin test for table layout
federicobarbacovi c6ca05b
Changes to make merge easier
federicobarbacovi 5fc4a2d
fix: debug goblin reset logic (#22164)
iakovenkos b4034da
End to end test working
federicobarbacovi 5f4a112
Accumulation of IPA claims in Chonk verifier
federicobarbacovi abde191
Update proof compression + fix some tests
federicobarbacovi 84da78e
Mock IVC integration test (native only)
federicobarbacovi aeb1b95
Test for 19 circuits
federicobarbacovi d7ec82c
WASM test passes
federicobarbacovi 9ea14dd
Bring stack size back to 2MB; push stack breakdown md file
federicobarbacovi a55a0f2
Design doc
federicobarbacovi 73a9228
Multiple flushes
federicobarbacovi 11841d4
Clean up
federicobarbacovi ad96ba0
GoblinAVM -> GoblinWithoutMerge name changes
federicobarbacovi a9d21a6
New constructor for flush case + code simplification
federicobarbacovi 42742d5
goblin_avm -> goblin_without_merge + move flush circuit
federicobarbacovi 04161dd
Some more cleanup
federicobarbacovi ef9794c
Some more cleanup
federicobarbacovi 4c05167
Native verification returns 2 claims
federicobarbacovi 7498b07
Clean up
federicobarbacovi 5e076b9
Fixes + update vks
federicobarbacovi 4be6dba
Fix
federicobarbacovi 26c3c64
Fix tests
federicobarbacovi 22e39ff
Update gate count and vks
federicobarbacovi 3211b39
Benchmark file
federicobarbacovi ced4790
Scope metadata for ts integration
federicobarbacovi 2ce553d
Async generation of ipa claim
federicobarbacovi b34ed3d
Merge remote-tracking branch 'origin/merge-train/barretenberg' into f…
federicobarbacovi f3b2c53
Update gate count constants and vk
federicobarbacovi dd742c0
Format
federicobarbacovi 15fad98
Format
federicobarbacovi f73fae1
Remove info statement + add gate count constant for goblin flush
federicobarbacovi 8c8138f
Conditional async IPA
federicobarbacovi 1c8f638
Revert IPA async + benches for goblin flush + more tests
federicobarbacovi 952e9be
Minor changes
federicobarbacovi 2d38f74
Better benchmarks
federicobarbacovi fc14d86
Update md and Cmake
federicobarbacovi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # Chonk Remote Benchmarks | ||
|
|
||
| ## Summary | ||
|
|
||
| | # | Flow | Circuits | Total (s) | Accumulate (s) | Prove (s) | Load (ms) | Peak mem (MiB) | | ||
| |---|---|---|---|---|---|---|---| | ||
| | 1 | deploy_ecdsar1+sponsored_fpc | 13 | 7.68 | 5.14 | 2.36 | 158 | 310.87 | | ||
| | 2 | deploy_schnorr+sponsored_fpc | 13 | 7.37 | 4.81 | 2.37 | 160 | 311.40 | | ||
| | 3 | ecdsar1+amm_add_liquidity_1_recursions+sponsored_fpc | 19 | 12.61 | 9.59 | 2.62 | 342 | 523.71 | | ||
| | 4 | ecdsar1+deploy_tokenContract_with_registration+sponsored_fpc | 11 | 8.16 | 5.66 | 2.27 | 194 | 459.11 | | ||
| | 5 | ecdsar1+token_bridge_claim_private+sponsored_fpc | 11 | 7.06 | 4.60 | 2.27 | 158 | 313.44 | | ||
| | 6 | ecdsar1+transfer_0_recursions+private_fpc | 15 | 9.96 | 7.23 | 2.44 | 259 | 433.19 | | ||
| | 7 | ecdsar1+transfer_0_recursions+sponsored_fpc | 9 | 6.11 | 3.79 | 2.17 | 114 | 294.02 | | ||
| | 8 | ecdsar1+transfer_1_recursions+private_fpc | 17 | 11.26 | 8.36 | 2.55 | 301 | 509.51 | | ||
| | 9 | ecdsar1+transfer_1_recursions+sponsored_fpc | 11 | 7.11 | 4.67 | 2.26 | 156 | 308.41 | | ||
| | 10 | schnorr+deploy_tokenContract_with_registration+sponsored_fpc | 11 | 7.87 | 5.36 | 2.28 | 196 | 462.34 | | ||
|
|
||
| ## Baseline | ||
|
|
||
| | # | Flow | Circuits | Total (s) | Accumulate (s) | Prove (s) | Load (ms) | Peak mem (MiB) | | ||
| |---|---|---|---|---|---|---|---| | ||
| | 1 | deploy_ecdsar1+sponsored_fpc | 13 | 7.63 | 4.99 | 2.46 | 155 | 311.31 | | ||
| | 2 | deploy_schnorr+sponsored_fpc | 13 | 7.31 | 4.66 | 2.47 | 156 | 312.44 | | ||
| | 3 | ecdsar1+amm_add_liquidity_1_recursions+sponsored_fpc | 19 | 12.82 | 9.76 | 2.67 | 343 | 513.35 | | ||
| | 4 | ecdsar1+deploy_tokenContract_with_registration+sponsored_fpc | 11 | 8.07 | 5.57 | 2.28 | 192 | 458.79 | | ||
| | 5 | ecdsar1+token_bridge_claim_private+sponsored_fpc | 11 | 6.97 | 4.41 | 2.38 | 160 | 316.43 | | ||
| | 6 | ecdsar1+transfer_0_recursions+private_fpc | 15 | 10.03 | 7.27 | 2.47 | 258 | 427.96 | | ||
| | 7 | ecdsar1+transfer_0_recursions+sponsored_fpc | 9 | 5.92 | 3.52 | 2.26 | 112 | 294.53 | | ||
| | 8 | ecdsar1+transfer_1_recursions+private_fpc | 17 | 11.32 | 8.42 | 2.57 | 301 | 500.86 | | ||
| | 9 | ecdsar1+transfer_1_recursions+sponsored_fpc | 11 | 7.02 | 4.49 | 2.36 | 153 | 309.69 | | ||
| | 10 | schnorr+deploy_tokenContract_with_registration+sponsored_fpc | 11 | 7.81 | 5.30 | 2.28 | 195 | 458.34 | | ||
|
|
||
| ## Branch vs Baseline (Total time) | ||
|
|
||
| | # | Flow | Branch Total (s) | Baseline Total (s) | Δ (s) | Δ (%) | | ||
| |---|---|---|---|---|---| | ||
| | 1 | deploy_ecdsar1+sponsored_fpc | 7.68 | 7.63 | +0.05 | +0.66% | | ||
| | 2 | deploy_schnorr+sponsored_fpc | 7.37 | 7.31 | +0.06 | +0.82% | | ||
| | 3 | ecdsar1+amm_add_liquidity_1_recursions+sponsored_fpc | 12.61 | 12.82 | −0.21 | −1.64% | | ||
| | 4 | ecdsar1+deploy_tokenContract_with_registration+sponsored_fpc | 8.16 | 8.07 | +0.09 | +1.12% | | ||
| | 5 | ecdsar1+token_bridge_claim_private+sponsored_fpc | 7.06 | 6.97 | +0.09 | +1.29% | | ||
| | 6 | ecdsar1+transfer_0_recursions+private_fpc | 9.96 | 10.03 | −0.07 | −0.70% | | ||
| | 7 | ecdsar1+transfer_0_recursions+sponsored_fpc | 6.11 | 5.92 | +0.19 | +3.21% | | ||
| | 8 | ecdsar1+transfer_1_recursions+private_fpc | 11.26 | 11.32 | −0.06 | −0.53% | | ||
| | 9 | ecdsar1+transfer_1_recursions+sponsored_fpc | 7.11 | 7.02 | +0.09 | +1.28% | | ||
| | 10 | schnorr+deploy_tokenContract_with_registration+sponsored_fpc | 7.87 | 7.81 | +0.06 | +0.77% | | ||
|
|
||
| Mean Δ: +0.029 s (+0.63%). Within the ±5% noise caveat. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # WASM Findings: Goblin Flush in IVC Integration | ||
|
|
||
| ## Summary | ||
|
|
||
| The goblin flush test (`generateTestingIVCStack(1, 0, true)`) was crashing in WASM but working correctly with NativeUnixSocket. Root cause: WASM stack overflow due to large recursive verifier types on the stack. Fixed by increasing the WASM stack from 1 MB to 2 MB. | ||
|
|
||
| ## Root Cause: WASM Stack Overflow | ||
|
|
||
| The crash was **not** a heap memory issue — WASM heap usage was only 338 MiB at crash time, well below the 4 GiB maximum. The problem was the 1 MB WASM stack being exhausted by the ECCVM recursive verifier's large stack-allocated types. | ||
|
|
||
| ### Why recursive types are so large | ||
|
|
||
| The ECCVM recursive verifier operates on `bigfield` elements (`stdlib::bigfield<UltraCircuitBuilder, Bn254FqParams>`) instead of native field elements. Each `bigfield` contains 4 limbs (each a `field_t` + `uint256_t` max value) plus a `prime_basis_limb`, making it ~492 bytes in WASM release vs 32 bytes for a native field element — a **15x** blowup. | ||
|
|
||
| ### Stack size breakdown (native debug build, measured via sizeof) | ||
|
|
||
| | Type | sizeof | Notes | | ||
| |------|--------|-------| | ||
| | `bigfield` (recursive FF) | 1,280 B | 4 limbs × (field_t + uint256_t) + prime_basis_limb | | ||
| | `field_t<Builder>` | 224 B | ptr + 2×fr + witness_index + OriginTag (debug only) | | ||
| | `ECCVMSumcheckVerifier` | **343,200 B** (335 KB) | Dominates the stack | | ||
| | `ECCVMSumcheckRound` | 172,896 B (169 KB) | Contains `TupleOfArraysOfValues relation_evaluations` | | ||
| | `AllValues` (118 × FF) | 151,040 B (147 KB) | 118 entities × 1,280 bytes each | | ||
| | `TranslatorSumcheckVerifier` | 66,400 B (65 KB) | Smaller but still significant | | ||
| | `TranslatorSumcheckRound` | 33,408 B (33 KB) | | | ||
| | `ECCVMRecursiveVerifier` | 31,616 B (31 KB) | | | ||
| | `TranslatorRecursiveVerifier` | 23,680 B (23 KB) | | | ||
| | `Builder` | 4,864 B | | | ||
|
|
||
| In WASM release builds (no OriginTag, 4-byte pointers), sizes are roughly **2.6x smaller** than native debug. Estimated peak stack usage during ECCVM recursive verification: **~300-500 KB**. | ||
|
|
||
| ### Why the stack overflows | ||
|
|
||
| The main culprits are value-type members allocated on the stack: | ||
|
|
||
| 1. **`SumcheckVerifierRound::relation_evaluations`** (`TupleOfArraysOfValues`) — a flat tuple of arrays of `bigfield`, one per subrelation across ~134 ECCVM subrelations. This is a **member** of `SumcheckVerifierRound`, which is a **member** of `SumcheckVerifier`, which is a **local** in `reduce_to_ipa_opening()`. | ||
|
|
||
| 2. **`SumcheckVerifier::alphas`** (`std::array<FF, NUM_SUBRELATIONS - 1>`) — another large array of `bigfield` elements. | ||
|
|
||
| 3. **`ClaimedEvaluations`** (`AllEntities<FF>`) — 118 `bigfield` elements, allocated as a local in `SumcheckVerifier::verify()`. | ||
|
|
||
| These all live on the stack simultaneously during ECCVM sumcheck verification. | ||
|
|
||
| ### Call stack during peak usage | ||
|
|
||
| ``` | ||
| build_goblin_flush_circuit ~15 KB (builder, verifiers, proof) | ||
| └─ reduce_to_ipa_opening ~130 KB (SumcheckVerifier as local) | ||
| └─ verify() ~70 KB (ClaimedEvaluations, gate separators) | ||
| ``` | ||
|
|
||
| The Translator verification runs sequentially after ECCVM, so their frames don't overlap. | ||
|
|
||
| ## Fix Applied | ||
|
|
||
| 1. **`barretenberg/cpp/src/CMakeLists.txt`**: WASM stack size 1 MB → **2 MB** (2097152) | ||
| 2. **`barretenberg/ts/src/barretenberg_wasm/barretenberg_wasm_main/index.ts`**: initial memory pages 35 → **49** (to match WASM module's declared minimum with larger stack) | ||
| 3. **`yarn-project/ivc-integration/src/chonk_integration.test.ts`**: goblin flush test now runs on both WASM and NativeUnixSocket | ||
|
|
||
| Note: WASM test binaries already use 8 MB stack (`barretenberg/cpp/cmake/module.cmake`), which is why C++ tests never hit this issue. | ||
|
|
||
| ## Potential Future Optimization | ||
|
|
||
| The `relation_evaluations` tuple in `SumcheckVerifierRound` could be heap-allocated (e.g. via `std::unique_ptr`) to reduce stack pressure. This would allow reverting the stack size increase, but 2 MB is a reasonable default with ~4-6x headroom over estimated peak usage. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
barretenberg/cpp/src/barretenberg/benchmark/goblin_flush_bench/CMakeLists.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| barretenberg_module(goblin_flush_bench vm2_stub dsl chonk goblin_without_merge stdlib_honk_verifier stdlib_sha256 stdlib_primitives) |
88 changes: 88 additions & 0 deletions
88
barretenberg/cpp/src/barretenberg/benchmark/goblin_flush_bench/goblin_flush.bench.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| /** | ||
| * @brief Benchmarks for the Goblin flush pipeline. | ||
| * | ||
| * Measures the individual phases of a Goblin flush: | ||
| * 1. Prove Goblin (ECCVM + Translator, non-ZK) | ||
| * 2. Build + prove the flush verification circuit (Circuit C, Ultra Honk) | ||
| * 3. Accumulate the Goblin app (which recursively verifies C's proof) | ||
| * 4. Accumulate the Goblin kernel | ||
| */ | ||
|
|
||
| #include <benchmark/benchmark.h> | ||
|
|
||
| #include "barretenberg/chonk/chonk.hpp" | ||
| #include "barretenberg/chonk/mock_circuit_producer.hpp" | ||
| #include "barretenberg/common/bb_bench.hpp" | ||
| #include "barretenberg/dsl/acir_format/goblin_flush_recursion_constraint.hpp" | ||
| #include "barretenberg/goblin/mock_circuits.hpp" | ||
| #include "barretenberg/goblin_without_merge/goblin_flush_circuit.hpp" | ||
| #include "barretenberg/goblin_without_merge/goblin_without_merge.hpp" | ||
| #include "barretenberg/srs/global_crs.hpp" | ||
| #include "barretenberg/ultra_honk/ultra_prover.hpp" | ||
|
|
||
| using namespace benchmark; | ||
| using namespace bb; | ||
|
|
||
| namespace { | ||
|
|
||
| /** | ||
| * @brief Populate an op queue to near-Translator capacity, mimicking a real flush scenario. | ||
| * @details The tighter constraint is the Translator's op queue table (2^CONST_OP_QUEUE_LOG_SIZE = 4096 entries), | ||
| * not the ECCVM (2^CONST_ECCVM_LOG_N = 32768 rows). Fills until near the Translator limit. | ||
| */ | ||
| void create_populated_op_queue(std::shared_ptr<ECCOpQueue>& op_queue) | ||
| { | ||
| static constexpr size_t OP_QUEUE_TABLE_CAPACITY = 1UL << CONST_OP_QUEUE_LOG_SIZE; | ||
| // Leave headroom for structural ops (eq_and_reset, no-ops) that chonk adds per circuit | ||
| static constexpr size_t TARGET_OPS = OP_QUEUE_TABLE_CAPACITY - 128; | ||
|
|
||
| // Structural ops required by the chonk flush table structure | ||
| op_queue->no_op_ultra_only(); | ||
| op_queue->no_op_ultra_only(); | ||
| op_queue->no_op_ultra_only(); | ||
| op_queue->no_op_ultra_only(); | ||
| op_queue->eq_and_reset(); | ||
|
|
||
| // Fill the op queue to near capacity with add_accumulate operations | ||
| auto point = bb::g1::affine_element::one(); | ||
| while (op_queue->get_current_subtable_size() < TARGET_OPS - 1) { | ||
| op_queue->add_accumulate(point); | ||
| } | ||
| op_queue->eq_and_reset(); | ||
|
|
||
| op_queue->merge(); | ||
| } | ||
|
|
||
| class GoblinFlushBench : public benchmark::Fixture { | ||
| public: | ||
| void SetUp([[maybe_unused]] const ::benchmark::State& state) override | ||
| { | ||
| bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Benchmark Phase 2: Build and prove the flush verification circuit (Circuit C) with Ultra Honk | ||
| */ | ||
| BENCHMARK_DEFINE_F(GoblinFlushBench, ProveFlushCircuit)(benchmark::State& state) | ||
| { | ||
| // Pre-compute the Goblin proof and table commitments outside the timed region | ||
| auto ivc = std::make_shared<Chonk>(/*num_circuits=*/4); | ||
| create_populated_op_queue(ivc->get_goblin().op_queue); | ||
| acir_format::RecursionConstraint recursion_constraint = { | ||
| {}, {}, {}, 0, acir_format::ULTRA_GOBLIN, acir_format::WitnessOrConstant<bb::fr>::from_constant(0) | ||
| }; | ||
|
|
||
| for (auto _ : state) { | ||
| auto op_queue_copy = std::make_shared<ECCOpQueue>(*ivc->get_goblin().op_queue); | ||
| MegaCircuitBuilder builder(op_queue_copy); | ||
| benchmark::DoNotOptimize( | ||
| acir_format::create_goblin_flush_recursion_constraints(builder, recursion_constraint, ivc)); | ||
| } | ||
| } | ||
|
|
||
| BENCHMARK_REGISTER_F(GoblinFlushBench, ProveFlushCircuit)->Unit(benchmark::kMillisecond)->Iterations(1); | ||
|
|
||
| } // namespace | ||
|
|
||
| BENCHMARK_MAIN(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh tuples of tuples of tuples on bigfield