Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions barretenberg/cpp/pil/vm2/bytecode/bc_hashing.pil
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ namespace bc_hashing;
#[PC_INCREMENTS]
sel * (pc_index' - ((1 - LATCH_CONDITION) * (31 + pc_index))) = 0;

pol commit bytecode_id;
pol commit class_id;
#[ID_CONSISTENCY]
(1 - LATCH_CONDITION) * (bytecode_id' - bytecode_id) = 0;
(1 - LATCH_CONDITION) * (class_id' - class_id) = 0;

pol commit packed_field;
#[GET_PACKED_FIELD]
sel { pc_index, bytecode_id, packed_field }
sel { pc_index, class_id, packed_field }
in
bc_decomposition.sel_packed { bc_decomposition.pc, bc_decomposition.id, bc_decomposition.packed_field };

Expand All @@ -97,7 +97,7 @@ namespace bc_hashing;
// At the start of a new bytecode hash, the initial incremental hash has to be the length of the bytecode
// Note the looked up PC = 0 (enforced by the PC_INCREMENTS relation), i.e. the initial incremental hash value == bytecode length
#[IV_IS_LEN]
start { pc_index, bytecode_id, incremental_hash }
start { pc_index, class_id, incremental_hash }
in
bc_decomposition.sel_packed { bc_decomposition.pc, bc_decomposition.id, bc_decomposition.bytes_remaining };

Expand Down
25 changes: 11 additions & 14 deletions barretenberg/cpp/pil/vm2/bytecode/bc_retrieval.pil
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ include "../constants_gen.pil";
// - Check updatability.
//
// The lookups into this subtrace are expected to be on the columns
// { bytecode_id, address, error }
// This trace is the owner of the bytecode_id (incrementing).
// { class_id, address, error }
// This trace uses the class_id from the contract instance.
//
// Note that this trace will prove both success or failure of retrieval.

Expand All @@ -32,17 +32,11 @@ sel = 0;
#[TRACE_CONTINUITY]
(1 - sel) * (1 - precomputed.first_row) * sel' = 0;

// This id is generated at runtime starting from zero and incremented by 1.
// The primary source of bytecode_id is this sub-trace.
pol commit bytecode_id;
// Use class_id from the contract instance instead of bytecode_id
pol commit class_id;
pol commit error; // some error occurred.
pol commit address; // contract address.

// `bytecode_id` starts from zero and incremented by 1.
// Note: we only need to require TRACE_CONTINUITY because of this.
((1 - sel) * sel') * bytecode_id = 0; // First row that has sel = 1.
sel * sel' * (bytecode_id' - bytecode_id) = 0; // Next row.

// contract instance members.
//
// Note that bytecode retrieval doesn't care about the other instance members
Expand Down Expand Up @@ -71,6 +65,9 @@ pol commit instance_exists;
// The only error that can happen is if the nullifier does not exist.
error = sel * (1 - instance_exists);

// When the instance exists, class_id should match current_class_id
sel * instance_exists * (class_id - current_class_id) = 0;

#[CONTRACT_INSTANCE_RETRIEVAL]
sel {
address,
Expand Down Expand Up @@ -105,11 +102,11 @@ instance_exists {
// TODO(dbanks12): re-enable once C++ and PIL use standard poseidon2 hashing for bytecode commitments.
// Note: only need to hash the bytecode if the instance exists. Otherwise there is nothing to hash!
//#[BYTECODE_HASH_IS_CORRECT]
//instance_exists { bytecode_id, public_bytecode_commitment } in bc_hashing.latch { bc_hashing.bytecode_id, bc_hashing.output_hash };
//instance_exists { class_id, public_bytecode_commitment } in bc_hashing.latch { bc_hashing.class_id, bc_hashing.output_hash };

// Note: we don't need to silo and check the class id because the deployer contract guarrantees
// that if a contract instance exists, the class has been registered.

// TODO: To ensure byetcode_id unicity inside of bc_decomposition.pil, we will have to introduce
// a permutation of the form: sel_XXX {bytecode_id} is bc_decomposition.last_of_contract {bc_decomposition.id}
// sel_XXX will have to be picked so that it selects a bytecode_id iff it has an entry in bc_decomposition
// TODO: To ensure class_id unicity inside of bc_decomposition.pil, we will have to introduce
// a permutation of the form: sel_XXX {class_id} is bc_decomposition.last_of_contract {bc_decomposition.id}
// sel_XXX will have to be picked so that it selects a class_id iff it has an entry in bc_decomposition
6 changes: 3 additions & 3 deletions barretenberg/cpp/pil/vm2/bytecode/instr_fetching.pil
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ sel = 0;

// This pair identifies uniquely a given instruction among the bytecodes.
pol commit pc;
pol commit bytecode_id;
pol commit class_id;


// ****************************************************************************
Expand Down Expand Up @@ -159,7 +159,7 @@ sel_has_tag { tag_value, tag_out_of_range } in precomputed.sel_range_8 { precomp

// The size of the bytecode is bytes_remaining at pc == 0.
#[BYTECODE_SIZE_FROM_BC_DEC]
sel { bytecode_id, precomputed.zero, bytecode_size } in
sel { class_id, precomputed.zero, bytecode_size } in
bc_decomposition.sel { bc_decomposition.id, bc_decomposition.pc, bc_decomposition.bytes_remaining };

// bytecode[pc] to bytecode[pc + 36]
Expand All @@ -182,7 +182,7 @@ sel_pc_in_range = sel * (1 - pc_out_of_range);
// Bring in the bytes from the bytecode columns.
#[BYTES_FROM_BC_DEC]
sel_pc_in_range {
bytecode_id,
class_id,
pc,
bytes_to_read,
bd0, bd1, bd2, bd3, bd4,
Expand Down
16 changes: 16 additions & 0 deletions barretenberg/cpp/pil/vm2/context.pil
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ namespace execution;
pol commit transaction_fee;
// Constrained boolean by tx trace (for enqueued call) and #[NEXT_IS_STATIC] for nested
pol commit is_static;

// Class ID of the current contract
pol commit class_id;

pol commit parent_calldata_addr;
pol commit parent_calldata_size;
Expand Down Expand Up @@ -165,6 +168,13 @@ namespace execution;
#[IS_STATIC_NEXT_ROW]
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (is_static' - is_static) = 0;
NOT_LAST_EXEC * sel_enter_call * (is_static' - sel_execute_static_call) = 0;

// nested_exit_call = 1 ==> constraints come from lookup
// sel_enter_call = 1 ==> class_id' = class_id from bytecode retrieval
// otherwise = 0 ==> class_id' = class_id
#[CLASS_ID_NEXT_ROW]
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (class_id' - class_id) = 0;
// When entering a call, class_id will be set from bytecode retrieval on the next row

// nested_exit_call = 1 ==> constraints come from lookup
// sel_enter_call = 1 ==> parent_calldata_addr' = rop[3] (resolved operand 4 from execution trace)
Expand Down Expand Up @@ -256,6 +266,7 @@ namespace execution;
msg_sender,
contract_address,
is_static,
class_id,
parent_calldata_addr,
parent_calldata_size,
parent_l2_gas_limit,
Expand All @@ -271,6 +282,7 @@ namespace execution;
context_stack.msg_sender,
context_stack.contract_address,
context_stack.is_static,
context_stack.parent_class_id,
context_stack.parent_calldata_addr,
context_stack.parent_calldata_size,
context_stack.parent_l2_gas_limit,
Expand All @@ -294,6 +306,7 @@ namespace execution;
msg_sender',
contract_address',
is_static',
class_id',
parent_calldata_addr',
parent_calldata_size',
parent_l2_gas_limit',
Expand All @@ -311,6 +324,7 @@ namespace execution;
context_stack.msg_sender,
context_stack.contract_address,
context_stack.is_static,
context_stack.parent_class_id,
context_stack.parent_calldata_addr,
context_stack.parent_calldata_size,
context_stack.parent_l2_gas_limit,
Expand All @@ -332,6 +346,7 @@ namespace execution;
msg_sender',
contract_address',
is_static',
class_id',
parent_calldata_addr',
parent_calldata_size',
parent_l2_gas_limit',
Expand All @@ -347,6 +362,7 @@ namespace execution;
context_stack.msg_sender,
context_stack.contract_address,
context_stack.is_static,
context_stack.parent_class_id,
context_stack.parent_calldata_addr,
context_stack.parent_calldata_size,
context_stack.parent_l2_gas_limit,
Expand Down
2 changes: 2 additions & 0 deletions barretenberg/cpp/pil/vm2/context_stack.pil
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace context_stack;
pol commit msg_sender;
pol commit contract_address;
pol commit is_static;

pol commit parent_class_id;

pol commit parent_calldata_addr;
pol commit parent_calldata_size;
Expand Down
19 changes: 11 additions & 8 deletions barretenberg/cpp/pil/vm2/execution.pil
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,24 @@ last = sel * (1 - sel');
* Temporality group 1: Bytecode retrieval (unconditional)
**************************************************************************************************/

pol commit bytecode_id;
// class_id is now defined in context.pil
pol commit sel_bytecode_retrieval_failure;

// Note: the class_id is a unique identifier for the contract class, but note that bytecode retrieval
// may happen multiple times for the same class since nullifier and public data roots will change.
// Inner gadgets deduplicate instead.
// TODO(dbanks12): since this lookup is no longer active for all rows,
// we likely need to constrain that bytecode_id does not change during a context,
// we likely need to constrain that class_id does not change during a context,
// or we need to otherwise consider the implications of this.
#[BYTECODE_RETRIEVAL_RESULT]
sel_first_row_in_context {
bytecode_id,
class_id,
contract_address,
prev_nullifier_tree_root, // from context.pil
prev_public_data_tree_root, // from context.pil
sel_bytecode_retrieval_failure
} in bc_retrieval.sel {
bc_retrieval.bytecode_id,
bc_retrieval.class_id,
bc_retrieval.address,
bc_retrieval.nullifier_tree_root,
bc_retrieval.public_data_tree_root,
Expand Down Expand Up @@ -139,9 +142,9 @@ pol commit op[7]; // operands

#[INSTRUCTION_FETCHING_RESULT]
sel_bytecode_retrieval_success {
pc, bytecode_id, sel_instruction_fetching_failure
pc, class_id, sel_instruction_fetching_failure
} in instr_fetching.sel {
instr_fetching.pc, instr_fetching.bytecode_id, instr_fetching.sel_parsing_err
instr_fetching.pc, instr_fetching.class_id, instr_fetching.sel_parsing_err
};

pol commit sel_instruction_fetching_success;
Expand All @@ -150,11 +153,11 @@ sel_instruction_fetching_success = sel * (1 - sel_instruction_fetching_failure);

#[INSTRUCTION_FETCHING_BODY]
sel_instruction_fetching_success {
pc, bytecode_id, ex_opcode, instr_length,
pc, class_id, ex_opcode, instr_length,
indirect, op[0], op[1], op[2], op[3], op[4], op[5], op[6]
} in instr_fetching.sel {
instr_fetching.pc,
instr_fetching.bytecode_id,
instr_fetching.class_id,
instr_fetching.exec_opcode,
instr_fetching.instr_size,
instr_fetching.indirect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ TEST(BytecodeDecompositionConstrainingTest, SingleBytecode)
init_trace(trace);
BytecodeTraceBuilder builder;
builder.process_decomposition(
{ { .bytecode_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(40)) } }, trace);
{ { .class_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(40)) } }, trace);

EXPECT_EQ(trace.get_num_rows(), 1 + 40);
check_relation<bc_decomposition>(trace);
Expand All @@ -56,7 +56,7 @@ TEST(BytecodeDecompositionConstrainingTest, ShortSingleBytecode)
init_trace(trace);
BytecodeTraceBuilder builder;
builder.process_decomposition(
{ { .bytecode_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(5)) } }, trace);
{ { .class_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(5)) } }, trace);

EXPECT_EQ(trace.get_num_rows(), 1 + 5);
check_relation<bc_decomposition>(trace);
Expand All @@ -68,8 +68,8 @@ TEST(BytecodeDecompositionConstrainingTest, MultipleBytecodes)
init_trace(trace);
BytecodeTraceBuilder builder;
builder.process_decomposition(
{ { .bytecode_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(40)) },
{ .bytecode_id = 2, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(55)) } },
{ { .class_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(40)) },
{ .class_id = 2, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(55)) } },
trace);

EXPECT_EQ(trace.get_num_rows(), 1 + 40 + 55);
Expand All @@ -82,11 +82,11 @@ TEST(BytecodeDecompositionConstrainingTest, MultipleBytecodesWithShortOnes)
init_trace(trace);
BytecodeTraceBuilder builder;
builder.process_decomposition(
{ { .bytecode_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(40)) },
{ .bytecode_id = 2, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(5)) },
{ .bytecode_id = 3, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(10)) },
{ .bytecode_id = 4, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(55)) },
{ .bytecode_id = 5, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(2)) } },
{ { .class_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(40)) },
{ .class_id = 2, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(5)) },
{ .class_id = 3, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(10)) },
{ .class_id = 4, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(55)) },
{ .class_id = 5, .bytecode = std::make_shared<std::vector<uint8_t>>(random_bytes(2)) } },
trace);

EXPECT_EQ(trace.get_num_rows(), 1 + 40 + 5 + 10 + 55 + 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TEST(BytecodeHashingConstrainingTest, SingleBytecodeHash)
BytecodeTraceBuilder builder;

builder.process_hashing(
{ { .bytecode_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) /* 62 bytes */ } }, trace);
{ { .class_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) /* 62 bytes */ } }, trace);

check_relation<bc_hashing>(trace);
}
Expand All @@ -74,8 +74,8 @@ TEST(BytecodeHashingConstrainingTest, MultipleBytecodeHash)
BytecodeTraceBuilder builder;

builder.process_hashing(
{ { .bytecode_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) /* 62 bytes */ },
{ .bytecode_id = 2, .bytecode_length = 62000, .bytecode_fields = random_fields(2000) /* 62k bytes */ } },
{ { .class_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) /* 62 bytes */ },
{ .class_id = 2, .bytecode_length = 62000, .bytecode_fields = random_fields(2000) /* 62k bytes */ } },
trace);

check_relation<bc_hashing>(trace);
Expand Down Expand Up @@ -110,7 +110,7 @@ TEST(BytecodeHashingConstrainingTest, PoseidonInteractions)

poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace);
bytecode_builder.process_hashing(
{ { .bytecode_id = 1, .bytecode_length = 62, .bytecode_fields = fields /* 62 bytes */ } }, trace);
{ { .class_id = 1, .bytecode_length = 62, .bytecode_fields = fields /* 62 bytes */ } }, trace);

// TODO(dbanks12): re-enable once C++ and PIL use standard poseidon2 hashing for bytecode commitments.
// check_interaction<BytecodeTraceBuilder, lookup_bc_hashing_poseidon2_hash_settings>(trace);
Expand All @@ -128,9 +128,9 @@ TEST(BytecodeHashingConstrainingTest, BytecodeInteractions)
std::vector<FF> fields = simulation::encode_bytecode(bytecode);
BytecodeTraceBuilder builder;

builder.process_hashing({ { .bytecode_id = 1, .bytecode_length = 40, .bytecode_fields = fields } }, trace);
builder.process_decomposition(
{ { .bytecode_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(bytecode) } }, trace);
builder.process_hashing({ { .class_id = 1, .bytecode_length = 40, .bytecode_fields = fields } }, trace);
builder.process_decomposition({ { .class_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(bytecode) } },
trace);

check_interaction<BytecodeTraceBuilder,
lookup_bc_hashing_get_packed_field_settings,
Expand All @@ -146,8 +146,8 @@ TEST(BytecodeHashingConstrainingTest, NegativeInvalidStartAfterLatch)
});

BytecodeTraceBuilder builder;
builder.process_hashing({ { .bytecode_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) },
{ .bytecode_id = 2, .bytecode_length = 93, .bytecode_fields = random_fields(3) } },
builder.process_hashing({ { .class_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) },
{ .class_id = 2, .bytecode_length = 93, .bytecode_fields = random_fields(3) } },
trace);
check_relation<bc_hashing>(trace, bc_hashing::SR_START_AFTER_LATCH);

Expand All @@ -165,7 +165,7 @@ TEST(BytecodeHashingConstrainingTest, NegativeInvalidPCIncrement)
BytecodeTraceBuilder builder;
builder.process_hashing(
{
{ .bytecode_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) },
{ .class_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) },
},
trace);
check_relation<bc_hashing>(trace, bc_hashing::SR_PC_INCREMENTS);
Expand All @@ -184,7 +184,7 @@ TEST(BytecodeHashingConstrainingTest, NegativeChainOutput)
BytecodeTraceBuilder builder;
builder.process_hashing(
{
{ .bytecode_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) },
{ .class_id = 1, .bytecode_length = 62, .bytecode_fields = random_fields(2) },
},
trace);
check_relation<bc_hashing>(trace, bc_hashing::SR_CHAIN_OUTPUT_TO_INCR);
Expand Down Expand Up @@ -222,9 +222,9 @@ TEST(BytecodeHashingConstrainingTest, NegativeBytecodeInteraction)

BytecodeTraceBuilder builder;

builder.process_hashing({ { .bytecode_id = 1, .bytecode_length = 40, .bytecode_fields = fields } }, trace);
builder.process_decomposition(
{ { .bytecode_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(bytecode) } }, trace);
builder.process_hashing({ { .class_id = 1, .bytecode_length = 40, .bytecode_fields = fields } }, trace);
builder.process_decomposition({ { .class_id = 1, .bytecode = std::make_shared<std::vector<uint8_t>>(bytecode) } },
trace);

// Row = 3 is the start of the hashing for bytecode id = 2
// Modify the pc index for the lookup of the second packed field
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,9 @@ TEST(ClassIdDerivationPoseidonTest, WithRetrievalInteraction)
class_id_derivation.assert_derivation(class_id, klass);
builder.process({ { .class_id = class_id, .klass = klass } }, trace);

bc_trace_builder.process_retrieval({ { .bytecode_id = 0,
.address = 1,
.current_class_id = class_id,
.contract_class = klass,
.nullifier_root = 3 } },
trace);
bc_trace_builder.process_retrieval(
{ { .class_id = 0, .address = 1, .current_class_id = class_id, .contract_class = klass, .nullifier_root = 3 } },
trace);

check_interaction<BytecodeTraceBuilder, lookup_bc_retrieval_class_id_derivation_settings>(trace);
}
Expand Down
Loading
Loading