Skip to content

Commit 3092212

Browse files
authored
chore(avm): re-enable bb-prover tests in CI, change some to check-circuit-only, enable multi-enqueued call tests (#11180)
1 parent 9ab4cee commit 3092212

File tree

13 files changed

+325
-70
lines changed

13 files changed

+325
-70
lines changed

barretenberg/cpp/src/barretenberg/bb/main.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,27 @@ void print_avm_stats()
683683
#endif
684684
}
685685

686+
/**
687+
* @brief Performs "check circuit" on the AVM circuit for the given public inputs and hints.
688+
*
689+
* @param public_inputs_path Path to the file containing the serialised avm public inputs
690+
* @param hints_path Path to the file containing the serialised avm circuit hints
691+
*/
692+
void avm_check_circuit(const std::filesystem::path& public_inputs_path, const std::filesystem::path& hints_path)
693+
{
694+
695+
const auto avm_public_inputs = AvmPublicInputs::from(read_file(public_inputs_path));
696+
const auto avm_hints = bb::avm_trace::ExecutionHints::from(read_file(hints_path));
697+
avm_hints.print_sizes();
698+
699+
vinfo("initializing crs with size: ", avm_trace::Execution::SRS_SIZE);
700+
init_bn254_crs(avm_trace::Execution::SRS_SIZE);
701+
702+
avm_trace::Execution::check_circuit(avm_public_inputs, avm_hints);
703+
704+
print_avm_stats();
705+
}
706+
686707
/**
687708
* @brief Writes an avm proof and corresponding (incomplete) verification key to files.
688709
*
@@ -700,18 +721,7 @@ void avm_prove(const std::filesystem::path& public_inputs_path,
700721

701722
const auto avm_public_inputs = AvmPublicInputs::from(read_file(public_inputs_path));
702723
const auto avm_hints = bb::avm_trace::ExecutionHints::from(read_file(hints_path));
703-
704-
// Using [0] is fine now for the top-level call, but we might need to index by address in future
705-
vinfo("bytecode size: ", avm_hints.all_contract_bytecode[0].bytecode.size());
706-
vinfo("hints.storage_read_hints size: ", avm_hints.storage_read_hints.size());
707-
vinfo("hints.storage_write_hints size: ", avm_hints.storage_write_hints.size());
708-
vinfo("hints.nullifier_read_hints size: ", avm_hints.nullifier_read_hints.size());
709-
vinfo("hints.nullifier_write_hints size: ", avm_hints.nullifier_write_hints.size());
710-
vinfo("hints.note_hash_read_hints size: ", avm_hints.note_hash_read_hints.size());
711-
vinfo("hints.note_hash_write_hints size: ", avm_hints.note_hash_write_hints.size());
712-
vinfo("hints.l1_to_l2_message_read_hints size: ", avm_hints.l1_to_l2_message_read_hints.size());
713-
vinfo("hints.contract_instance_hints size: ", avm_hints.contract_instance_hints.size());
714-
vinfo("hints.contract_bytecode_hints size: ", avm_hints.all_contract_bytecode.size());
724+
avm_hints.print_sizes();
715725

716726
vinfo("initializing crs with size: ", avm_trace::Execution::SRS_SIZE);
717727
init_bn254_crs(avm_trace::Execution::SRS_SIZE);
@@ -1448,6 +1458,13 @@ int main(int argc, char* argv[])
14481458
std::filesystem::path public_inputs_path =
14491459
get_option(args, "--avm-public-inputs", "./target/avm_public_inputs.bin");
14501460
return avm2_verify(proof_path, public_inputs_path, vk_path) ? 0 : 1;
1461+
} else if (command == "avm_check_circuit") {
1462+
std::filesystem::path avm_public_inputs_path =
1463+
get_option(args, "--avm-public-inputs", "./target/avm_public_inputs.bin");
1464+
std::filesystem::path avm_hints_path = get_option(args, "--avm-hints", "./target/avm_hints.bin");
1465+
extern std::filesystem::path avm_dump_trace_path;
1466+
avm_dump_trace_path = get_option(args, "--avm-dump-trace", "");
1467+
avm_check_circuit(avm_public_inputs_path, avm_hints_path);
14511468
} else if (command == "avm_prove") {
14521469
std::filesystem::path avm_public_inputs_path =
14531470
get_option(args, "--avm-public-inputs", "./target/avm_public_inputs.bin");

barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,40 @@ std::vector<FF> Execution::getDefaultPublicInputs()
243243
return public_inputs_vec;
244244
}
245245

246+
/**
247+
* @brief Run the bytecode, generate the corresponding execution trace and check the circuit for
248+
* execution of the supplied bytecode.
249+
*
250+
* @throws runtime_error exception when the bytecode is invalid.
251+
*/
252+
void Execution::check_circuit(AvmPublicInputs const& public_inputs, ExecutionHints const& execution_hints)
253+
{
254+
std::vector<FF> returndata;
255+
std::vector<FF> calldata;
256+
for (const auto& enqueued_call_hints : execution_hints.enqueued_call_hints) {
257+
calldata.insert(calldata.end(), enqueued_call_hints.calldata.begin(), enqueued_call_hints.calldata.end());
258+
}
259+
std::vector<Row> trace = AVM_TRACK_TIME_V(
260+
"prove/gen_trace", gen_trace(public_inputs, returndata, execution_hints, /*apply_e2e_assertions=*/true));
261+
if (!avm_dump_trace_path.empty()) {
262+
info("Dumping trace as CSV to: " + avm_dump_trace_path.string());
263+
dump_trace_as_csv(trace, avm_dump_trace_path);
264+
}
265+
auto circuit_builder = bb::avm::AvmCircuitBuilder();
266+
circuit_builder.set_trace(std::move(trace));
267+
vinfo("Circuit subgroup size: 2^",
268+
// this calculates the integer log2
269+
std::bit_width(circuit_builder.get_circuit_subgroup_size()) - 1);
270+
271+
if (circuit_builder.get_circuit_subgroup_size() > SRS_SIZE) {
272+
throw_or_abort("Circuit subgroup size (" + std::to_string(circuit_builder.get_circuit_subgroup_size()) +
273+
") exceeds SRS_SIZE (" + std::to_string(SRS_SIZE) + ")");
274+
}
275+
276+
vinfo("------- CHECKING CIRCUIT -------");
277+
AVM_TRACK_TIME("prove/check_circuit", circuit_builder.check_circuit());
278+
}
279+
246280
/**
247281
* @brief Run the bytecode, generate the corresponding execution trace and prove the correctness
248282
* of the execution of the supplied bytecode.
@@ -352,8 +386,8 @@ std::vector<Row> Execution::gen_trace(AvmPublicInputs const& public_inputs,
352386
uint32_t start_side_effect_counter = 0;
353387
// Temporary until we get proper nested call handling
354388
std::vector<FF> calldata;
355-
for (const auto& enqueued_call_hints : execution_hints.enqueued_call_hints) {
356-
calldata.insert(calldata.end(), enqueued_call_hints.calldata.begin(), enqueued_call_hints.calldata.end());
389+
for (const auto& enqueued_call_hint : execution_hints.enqueued_call_hints) {
390+
calldata.insert(calldata.end(), enqueued_call_hint.calldata.begin(), enqueued_call_hint.calldata.end());
357391
}
358392
AvmTraceBuilder trace_builder =
359393
Execution::trace_builder_constructor(public_inputs, execution_hints, start_side_effect_counter);

barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class Execution {
5353

5454
static std::tuple<bb::avm::AvmFlavor::VerificationKey, bb::HonkProof> prove(
5555
AvmPublicInputs const& public_inputs = AvmPublicInputs(), ExecutionHints const& execution_hints = {});
56+
static void check_circuit(AvmPublicInputs const& public_inputs = AvmPublicInputs(),
57+
ExecutionHints const& execution_hints = {});
5658
static bool verify(bb::avm::AvmFlavor::VerificationKey vk, HonkProof const& proof);
5759

5860
private:

barretenberg/cpp/src/barretenberg/vm/avm/trace/execution_hints.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,24 @@ struct ExecutionHints {
257257
return *this;
258258
}
259259

260+
void print_sizes() const
261+
{
262+
vinfo("hints.enqueued_call_hints size: ", enqueued_call_hints.size());
263+
vinfo("hints.contract_instance_hints size: ", contract_instance_hints.size());
264+
vinfo("hints.contract_bytecode_hints size: ", all_contract_bytecode.size());
265+
if (all_contract_bytecode.size() > 0) {
266+
// Using [0] is fine now for the top-level call, but we might need to index by address in future
267+
vinfo("0th bytecode size: ", all_contract_bytecode[0].bytecode.size());
268+
}
269+
vinfo("hints.storage_read_hints size: ", storage_read_hints.size());
270+
vinfo("hints.storage_write_hints size: ", storage_write_hints.size());
271+
vinfo("hints.nullifier_read_hints size: ", nullifier_read_hints.size());
272+
vinfo("hints.nullifier_write_hints size: ", nullifier_write_hints.size());
273+
vinfo("hints.note_hash_read_hints size: ", note_hash_read_hints.size());
274+
vinfo("hints.note_hash_write_hints size: ", note_hash_write_hints.size());
275+
vinfo("hints.l1_to_l2_message_read_hints size: ", l1_to_l2_message_read_hints.size());
276+
}
277+
260278
static void push_vec_into_map(std::unordered_map<uint32_t, FF>& into_map,
261279
const std::vector<std::pair<FF, FF>>& from_pair_vec)
262280
{

noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ contract AvmTest {
7171
storage.single.read()
7272
}
7373

74+
#[public]
75+
fn read_assert_storage_single(a: Field) {
76+
assert(a == storage.single.read(), "Storage value does not match input");
77+
}
78+
7479
// should still be able to use ` -> pub *` for return type even though macro forces `pub`
7580
#[public]
7681
fn set_read_storage_single(a: Field) -> pub Field {

0 commit comments

Comments
 (0)