Skip to content

Commit

Permalink
feat: add miscellaneous block to handle structure trace overflow (#9733)
Browse files Browse the repository at this point in the history
Adds an `overflow` block to the set of execution trace blocks which can
store arbitrary gate types that have "overflowed" the capacity of their
corresponding designated gate type block. This allows for accumulation
of app circuits which do not fit into a given structured trace
configuration.

It works as follows: when constructing a circuit, there is no bound on
the size of each gate block. When a proving key is constructed, we check
the capacity of each block and move any overflow into the overflow
block. In all cases, the polynomials have the prescribed trace structure
at the beginning plus a possible overflow block at the end.

---------

Co-authored-by: iakovenkos <sergey.s.yakovenko@gmail.com>
  • Loading branch information
ledwards2225 and iakovenkos authored Nov 11, 2024
1 parent f961c26 commit 80f9cc4
Show file tree
Hide file tree
Showing 26 changed files with 453 additions and 122 deletions.
6 changes: 3 additions & 3 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ void client_ivc_prove_output_all_msgpack(const std::string& bytecodePath,
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): remove use of auto_verify_mode
ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::E2E_FULL_TEST;
ivc.trace_settings.structure = TraceStructure::E2E_FULL_TEST;

// Accumulate the entire program stack into the IVC
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1116): remove manual setting of is_kernel once databus
Expand Down Expand Up @@ -448,7 +448,7 @@ bool foldAndVerifyProgram(const std::string& bytecodePath, const std::string& wi

ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

auto program_stack = acir_format::get_acir_program_stack(
bytecodePath, witnessPath, false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013): this
Expand Down Expand Up @@ -501,7 +501,7 @@ void client_ivc_prove_output_all(const std::string& bytecodePath,
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): remove use of auto_verify_mode
ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::E2E_FULL_TEST;
ivc.trace_settings.structure = TraceStructure::E2E_FULL_TEST;

auto program_stack = acir_format::get_acir_program_stack(
bytecodePath, witnessPath, false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013): this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ClientIVCBench : public benchmark::Fixture {
BENCHMARK_DEFINE_F(ClientIVCBench, Full)(benchmark::State& state)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;
auto total_num_circuits = 2 * static_cast<size_t>(state.range(0)); // 2x accounts for kernel circuits
auto mocked_vkeys = mock_verification_keys(total_num_circuits);

Expand Down
10 changes: 5 additions & 5 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,11 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<Verific
// Construct the proving key for circuit
std::shared_ptr<DeciderProvingKey> proving_key;
if (!initialized) {
proving_key = std::make_shared<DeciderProvingKey>(circuit, trace_structure);
trace_usage_tracker = ExecutionTraceUsageTracker(trace_structure);
proving_key = std::make_shared<DeciderProvingKey>(circuit, trace_settings);
trace_usage_tracker = ExecutionTraceUsageTracker(trace_settings);
} else {
proving_key = std::make_shared<DeciderProvingKey>(
circuit, trace_structure, fold_output.accumulator->proving_key.commitment_key);
circuit, trace_settings, fold_output.accumulator->proving_key.commitment_key);
}

vinfo("getting honk vk... precomputed?: ", precomputed_vk);
Expand Down Expand Up @@ -382,10 +382,10 @@ std::vector<std::shared_ptr<ClientIVC::VerificationKey>> ClientIVC::precompute_f
}

// Reset the scheme so it can be reused for actual accumulation, maintaining the trace structure setting as is
TraceStructure structure = trace_structure;
TraceSettings settings = trace_settings;
bool auto_verify = auto_verify_mode;
*this = ClientIVC();
this->trace_structure = structure;
this->trace_settings = settings;
this->auto_verify_mode = auto_verify;

return vkeys;
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class ClientIVC {
// Management of linking databus commitments between circuits in the IVC
DataBusDepot bus_depot;

// A flag indicating whether or not to construct a structured trace in the DeciderProvingKey
TraceStructure trace_structure = TraceStructure::NONE;
// Settings related to the use of fixed block sizes for each gate in the execution trace
TraceSettings trace_settings;

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): eventually do away with this.
// Setting auto_verify_mode = true will cause kernel completion logic to be added to kernels automatically
Expand Down
57 changes: 43 additions & 14 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ class ClientIVCTests : public ::testing::Test {
}

auto precompute_verification_keys(const size_t num_circuits,
TraceStructure trace_structure,
TraceSettings trace_settings,
size_t log2_num_gates = 16)
{
ClientIVC ivc; // temporary IVC instance needed to produce the complete kernel circuits
ivc.trace_structure = trace_structure;
ivc.trace_settings = trace_settings;

std::vector<std::shared_ptr<VerificationKey>> vkeys;

Expand Down Expand Up @@ -163,7 +163,7 @@ TEST_F(ClientIVCTests, BadProofFailure)
// Confirm that the IVC verifies if nothing is tampered with
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

MockCircuitProducer circuit_producer;

Expand All @@ -179,7 +179,7 @@ TEST_F(ClientIVCTests, BadProofFailure)
// The IVC throws an exception if the FIRST fold proof is tampered with
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

MockCircuitProducer circuit_producer;

Expand All @@ -204,7 +204,7 @@ TEST_F(ClientIVCTests, BadProofFailure)
// The IVC fails if the SECOND fold proof is tampered with
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

MockCircuitProducer circuit_producer;

Expand All @@ -229,7 +229,7 @@ TEST_F(ClientIVCTests, BadProofFailure)
// The IVC fails if the 3rd/FINAL fold proof is tampered with
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

MockCircuitProducer circuit_producer;

Expand Down Expand Up @@ -278,7 +278,7 @@ TEST_F(ClientIVCTests, BasicLarge)
TEST_F(ClientIVCTests, BasicStructured)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

MockCircuitProducer circuit_producer;

Expand Down Expand Up @@ -307,7 +307,7 @@ TEST_F(ClientIVCTests, PrecomputedVerificationKeys)

MockCircuitProducer circuit_producer;

auto precomputed_vks = circuit_producer.precompute_verification_keys(NUM_CIRCUITS, TraceStructure::NONE);
auto precomputed_vks = circuit_producer.precompute_verification_keys(NUM_CIRCUITS, TraceSettings{});

// Construct and accumulate set of circuits using the precomputed vkeys
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
Expand All @@ -325,15 +325,15 @@ TEST_F(ClientIVCTests, PrecomputedVerificationKeys)
TEST_F(ClientIVCTests, StructuredPrecomputedVKs)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

size_t NUM_CIRCUITS = 4;
size_t log2_num_gates = 5; // number of gates in baseline mocked circuit

MockCircuitProducer circuit_producer;

auto precomputed_vks =
circuit_producer.precompute_verification_keys(NUM_CIRCUITS, ivc.trace_structure, log2_num_gates);
circuit_producer.precompute_verification_keys(NUM_CIRCUITS, ivc.trace_settings, log2_num_gates);

// Construct and accumulate set of circuits using the precomputed vkeys
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
Expand All @@ -357,10 +357,10 @@ TEST(ClientIVCBenchValidation, Full6)
bb::srs::init_grumpkin_crs_factory("../srs_db/grumpkin");

ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;
size_t total_num_circuits{ 12 };
PrivateFunctionExecutionMockCircuitProducer circuit_producer;
auto precomputed_vkeys = circuit_producer.precompute_verification_keys(total_num_circuits, ivc.trace_structure);
auto precomputed_vkeys = circuit_producer.precompute_verification_keys(total_num_circuits, ivc.trace_settings);
perform_ivc_accumulation_rounds(total_num_circuits, ivc, precomputed_vkeys);
auto proof = ivc.prove();
bool verified = verify_ivc(proof, ivc);
Expand All @@ -377,7 +377,7 @@ TEST(ClientIVCBenchValidation, Full6MockedVKs)
bb::srs::init_grumpkin_crs_factory("../srs_db/grumpkin");

ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;
size_t total_num_circuits{ 12 };
PrivateFunctionExecutionMockCircuitProducer circuit_producer;
auto mocked_vkeys = mock_verification_keys(total_num_circuits);
Expand All @@ -386,4 +386,33 @@ TEST(ClientIVCBenchValidation, Full6MockedVKs)
verify_ivc(proof, ivc);
};
ASSERT_NO_FATAL_FAILURE(run_test());
}
}

/**
* @brief Test use of structured trace overflow block mechanism
* @details Accumulate 4 circuits which have progressively more arithmetic gates. The final two overflow the prescribed
* arithmetic block size and make use of the overflow block which has sufficient capacity.
*
*/
TEST_F(ClientIVCTests, StructuredTraceOverflow)
{
ClientIVC ivc;

// Define trace settings with sufficient overflow capacity to accommodate each of the circuits to be accumulated
uint32_t overflow_capacity = 1 << 17;
ivc.trace_settings = { TraceStructure::SMALL_TEST, overflow_capacity };

MockCircuitProducer circuit_producer;

size_t NUM_CIRCUITS = 4;

// Construct and accumulate some circuits of varying size
size_t log2_num_gates = 14;
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
auto circuit = circuit_producer.create_next_circuit(ivc, log2_num_gates);
ivc.accumulate(circuit);
log2_num_gates += 1;
}

EXPECT_TRUE(ivc.prove_and_verify());
};
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ TEST_F(ClientIVCAutoVerifyTests, BasicStructured)
{
ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

// Construct some circuits of varying size
Builder circuit_0 = create_mock_circuit(ivc, /*is_kernel=*/false, /*log2_num_gates=*/5);
Expand Down Expand Up @@ -185,7 +185,7 @@ TEST_F(ClientIVCAutoVerifyTests, StructuredPrecomputedVKs)
{
ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

// Construct a set of arbitrary circuits
size_t NUM_CIRCUITS = 4;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ClientIVCIntegrationTests : public ::testing::Test {
TEST_F(ClientIVCIntegrationTests, BenchmarkCaseSimple)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;

MockCircuitProducer circuit_producer;

Expand All @@ -61,7 +61,7 @@ TEST_F(ClientIVCIntegrationTests, BenchmarkCaseSimple)
TEST_F(ClientIVCIntegrationTests, ConsecutiveKernels)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;

MockCircuitProducer circuit_producer;

Expand Down Expand Up @@ -89,15 +89,15 @@ TEST_F(ClientIVCIntegrationTests, ConsecutiveKernels)
TEST_F(ClientIVCIntegrationTests, BenchmarkCasePrecomputedVKs)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;

size_t NUM_CIRCUITS = 6;

// Precompute the verification keys for each circuit in the IVC
std::vector<std::shared_ptr<VerificationKey>> precomputed_vks;
{
MockCircuitProducer circuit_producer;
precomputed_vks = circuit_producer.precompute_verification_keys(NUM_CIRCUITS, ivc.trace_structure);
precomputed_vks = circuit_producer.precompute_verification_keys(NUM_CIRCUITS, ivc.trace_settings);
}

MockCircuitProducer circuit_producer;
Expand All @@ -123,7 +123,7 @@ TEST_F(ClientIVCIntegrationTests, BenchmarkCasePrecomputedVKs)
TEST_F(ClientIVCIntegrationTests, DatabusFailure)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;

MockCircuitProducer circuit_producer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ class PrivateFunctionExecutionMockCircuitProducer {
* @param trace_structure Trace structuring must be known in advance because it effects the VKs
* @return set of num_circuits-many verification keys
*/
auto precompute_verification_keys(const size_t num_circuits, TraceStructure trace_structure)
auto precompute_verification_keys(const size_t num_circuits, TraceSettings trace_settings)
{
ClientIVC ivc; // temporary IVC instance needed to produce the complete kernel circuits
ivc.trace_structure = trace_structure;
ivc.trace_settings = trace_settings;

std::vector<std::shared_ptr<VerificationKey>> vkeys;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class MockKernelTest : public ::testing::Test {
TEST_F(MockKernelTest, PinFoldingKernelSizes)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::CLIENT_IVC_BENCH;
ivc.trace_settings.structure = TraceStructure::CLIENT_IVC_BENCH;

MockCircuitProducer circuit_producer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ TEST_P(AcirIntegrationFoldingTest, DISABLED_FoldAndVerifyProgramStack)

ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

while (!program_stack.empty()) {
auto program = program_stack.back();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class IvcRecursionConstraintTest : public ::testing::Test {
TEST_F(IvcRecursionConstraintTest, AccumulateTwo)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

// construct a mock app_circuit
Builder app_circuit = construct_mock_app_circuit(ivc);
Expand All @@ -185,7 +185,7 @@ TEST_F(IvcRecursionConstraintTest, AccumulateTwo)
TEST_F(IvcRecursionConstraintTest, AccumulateFour)
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

// construct a mock app_circuit
Builder app_circuit_0 = construct_mock_app_circuit(ivc);
Expand Down Expand Up @@ -232,7 +232,7 @@ TEST_F(IvcRecursionConstraintTest, AccumulateTwoFailure)
VerifierInputs alternative_verification_queue_entry;
{
ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

// construct and accumulate a mock app circuit with a single unique public input
Builder app_circuit = construct_mock_app_circuit(ivc);
Expand All @@ -254,7 +254,7 @@ TEST_F(IvcRecursionConstraintTest, AccumulateTwoFailure)
// valid) witnesses during constraint system construction VS recursive verifier construction.

ClientIVC ivc;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

// construct and accumulate a mock app circuit with a single unique public input
Builder app_circuit = construct_mock_app_circuit(ivc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ WASM_EXPORT void acir_fold_and_verify_program_stack(uint8_t const* acir_vec,

ClientIVC ivc;
ivc.auto_verify_mode = true;
ivc.trace_structure = TraceStructure::SMALL_TEST;
ivc.trace_settings.structure = TraceStructure::SMALL_TEST;

bool is_kernel = false;
while (!program_stack.empty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ TEST_F(join_split_tests, test_0_input_notes_and_detect_circuit_change)
// The below part detects any changes in the join-split circuit
constexpr size_t DYADIC_CIRCUIT_SIZE = 1 << 16;

constexpr uint256_t CIRCUIT_HASH("0x2b30566e4d921ea9b0c76802d86ea5b8381ffa78ef143af1b0d0e3045862cb6b");
constexpr uint256_t CIRCUIT_HASH("0xe833d0ffaa99f39ca31ef79ded0089b0ec614eb4a528c4e1c4af6221a003fa6e");

const uint256_t circuit_hash = circuit.hash_circuit();
// circuit is finalized now
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ template <typename T>
concept IsUltraPlonkFlavor = IsAnyOf<T, plonk::flavor::Ultra, UltraKeccakFlavor>;

template <typename T>
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, MegaFlavor>;
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, MegaFlavor, MegaZKFlavor>;

template <typename T>
concept IsHonkFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, MegaFlavor, MegaZKFlavor>;
Expand Down
Loading

0 comments on commit 80f9cc4

Please sign in to comment.