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](AztecProtocol/aztec-packages#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 and AztecBot committed Dec 7, 2024
1 parent 16563ce commit 48640a4
Show file tree
Hide file tree
Showing 13 changed files with 1,119 additions and 734 deletions.
25 changes: 12 additions & 13 deletions 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
12 changes: 8 additions & 4 deletions cpp/src/barretenberg/vm/avm/tests/execution.test.cpp
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 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

0 comments on commit 48640a4

Please sign in to comment.