Skip to content

Commit

Permalink
feat: manage enqueued calls & phases in AVM witgen (#10310)
Browse files Browse the repository at this point in the history
Another larger PR:
1) Swap out to use the enqueued side effect trace (so we private insert
hints)
2) Perform private inserts of nullifiers in witgen
3) Apply asserts in witgen to ensure the endTree snapshots and endGas
line up with expected public inputs
4) Enforce side effect limits in witgen
5) Handle enqueued calls & phases in witgen

Later:
1) [Handle nested calls in
witgen](#10384)
2) Remove old side effect trace & old public inputs completely

---------

Co-authored-by: David Banks <[email protected]>
Co-authored-by: dbanks12 <[email protected]>
  • Loading branch information
3 people authored Dec 6, 2024
1 parent 00aaef6 commit e7ebef8
Show file tree
Hide file tree
Showing 28 changed files with 1,371 additions and 1,188 deletions.
25 changes: 12 additions & 13 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,27 +588,27 @@ void vk_as_fields(const std::string& vk_path, const std::string& output_path)
* - Filesystem: The proof and vk are written to the paths output_path/proof and output_path/{vk, vk_fields.json}
*
* @param bytecode_path Path to the file containing the serialised bytecode
* @param calldata_path Path to the file containing the serialised calldata (could be empty)
* @param public_inputs_path Path to the file containing the serialised avm public inputs
* @param hints_path Path to the file containing the serialised avm circuit hints
* @param output_path Path (directory) to write the output proof and verification keys
*/
void avm_prove(const std::filesystem::path& calldata_path,
const std::filesystem::path& public_inputs_path,
void avm_prove(const std::filesystem::path& public_inputs_path,
const std::filesystem::path& hints_path,
const std::filesystem::path& output_path)
{
std::vector<fr> const calldata = many_from_buffer<fr>(read_file(calldata_path));
auto const avm_new_public_inputs = AvmPublicInputs::from(read_file(public_inputs_path));

auto const avm_public_inputs = AvmPublicInputs::from(read_file(public_inputs_path));
auto const avm_hints = bb::avm_trace::ExecutionHints::from(read_file(hints_path));

// Using [0] is fine now for the top-level call, but we might need to index by address in future
vinfo("bytecode size: ", avm_hints.all_contract_bytecode[0].bytecode.size());
vinfo("calldata size: ", calldata.size());
vinfo("hints.storage_value_hints size: ", avm_hints.storage_value_hints.size());
vinfo("hints.note_hash_exists_hints size: ", avm_hints.note_hash_exists_hints.size());
vinfo("hints.nullifier_exists_hints size: ", avm_hints.nullifier_exists_hints.size());
vinfo("hints.l1_to_l2_message_exists_hints size: ", avm_hints.l1_to_l2_message_exists_hints.size());
vinfo("hints.storage_read_hints size: ", avm_hints.storage_read_hints.size());
vinfo("hints.storage_write_hints size: ", avm_hints.storage_write_hints.size());
vinfo("hints.nullifier_read_hints size: ", avm_hints.nullifier_read_hints.size());
vinfo("hints.nullifier_write_hints size: ", avm_hints.nullifier_write_hints.size());
vinfo("hints.note_hash_read_hints size: ", avm_hints.note_hash_read_hints.size());
vinfo("hints.note_hash_write_hints size: ", avm_hints.note_hash_write_hints.size());
vinfo("hints.l1_to_l2_message_read_hints size: ", avm_hints.l1_to_l2_message_read_hints.size());
vinfo("hints.externalcall_hints size: ", avm_hints.externalcall_hints.size());
vinfo("hints.contract_instance_hints size: ", avm_hints.contract_instance_hints.size());
vinfo("hints.contract_bytecode_hints size: ", avm_hints.all_contract_bytecode.size());
Expand All @@ -618,7 +618,7 @@ void avm_prove(const std::filesystem::path& calldata_path,

// Prove execution and return vk
auto const [verification_key, proof] =
AVM_TRACK_TIME_V("prove/all", avm_trace::Execution::prove(calldata, avm_new_public_inputs, avm_hints));
AVM_TRACK_TIME_V("prove/all", avm_trace::Execution::prove(avm_public_inputs, avm_hints));

std::vector<fr> vk_as_fields = verification_key.to_field_elements();

Expand Down Expand Up @@ -1243,15 +1243,14 @@ int main(int argc, char* argv[])
write_recursion_inputs_honk<UltraFlavor>(bytecode_path, witness_path, output_path, recursive);
#ifndef DISABLE_AZTEC_VM
} else if (command == "avm_prove") {
std::filesystem::path avm_calldata_path = get_option(args, "--avm-calldata", "./target/avm_calldata.bin");
std::filesystem::path avm_public_inputs_path =
get_option(args, "--avm-public-inputs", "./target/avm_public_inputs.bin");
std::filesystem::path avm_hints_path = get_option(args, "--avm-hints", "./target/avm_hints.bin");
// This outputs both files: proof and vk, under the given directory.
std::filesystem::path output_path = get_option(args, "-o", "./proofs");
extern std::filesystem::path avm_dump_trace_path;
avm_dump_trace_path = get_option(args, "--avm-dump-trace", "");
avm_prove(avm_calldata_path, avm_public_inputs_path, avm_hints_path, output_path);
avm_prove(avm_public_inputs_path, avm_hints_path, output_path);
} else if (command == "avm_verify") {
return avm_verify(proof_path, vk_path) ? 0 : 1;
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class AvmExecutionTests : public ::testing::Test {
* @param bytecode
* @return The trace as a vector of Row.
*/
std::vector<Row> gen_trace_from_bytecode(const std::vector<uint8_t>& bytecode)
std::vector<Row> gen_trace_from_bytecode(const std::vector<uint8_t>& bytecode) const
{
std::vector<FF> calldata{};
std::vector<FF> returndata{};
Expand All @@ -89,17 +89,21 @@ class AvmExecutionTests : public ::testing::Test {

static std::vector<Row> gen_trace(const std::vector<uint8_t>& bytecode,
const std::vector<FF>& calldata,
AvmPublicInputs& public_inputs,
AvmPublicInputs public_inputs,
std::vector<FF>& returndata,
ExecutionHints& execution_hints)
ExecutionHints execution_hints)
{
auto [contract_class_id, contract_instance] = gen_test_contract_hint(bytecode);
execution_hints.with_avm_contract_bytecode(
{ AvmContractBytecode{ bytecode, contract_instance, contract_class_id } });

// These are magic values because of how some tests work! Don't change them
public_inputs.public_app_logic_call_requests[0].contract_address = contract_instance.address;
return Execution::gen_trace(calldata, public_inputs, returndata, execution_hints);
execution_hints.enqueued_call_hints.push_back({
.contract_address = contract_instance.address,
.calldata = calldata,
});
return Execution::gen_trace(public_inputs, returndata, execution_hints);
}

static std::tuple<ContractClassIdHint, ContractInstanceHint> gen_test_contract_hint(
Expand Down
2 changes: 2 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace bb::avm_trace {

enum class AvmError : uint32_t {
NO_ERROR,
REVERT_OPCODE,
INVALID_PROGRAM_COUNTER,
INVALID_OPCODE,
INVALID_TAG_VALUE,
Expand All @@ -18,6 +19,7 @@ enum class AvmError : uint32_t {
CONTRACT_INST_MEM_UNKNOWN,
RADIX_OUT_OF_BOUNDS,
DUPLICATE_NULLIFIER,
SIDE_EFFECT_LIMIT_REACHED,
};

} // namespace bb::avm_trace
Loading

1 comment on commit e7ebef8

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: e7ebef8 Previous: c00ebdd Ratio
wasmconstruct_proof_ultrahonk_power_of_2/20 16528.366928 ms/iter 15274.610086999997 ms/iter 1.08

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

Please sign in to comment.