Skip to content

Commit

Permalink
feat(avm): indirect support for kernel read opcodes (#6940)
Browse files Browse the repository at this point in the history
  • Loading branch information
Maddiaa0 authored Jun 6, 2024
1 parent d492ac8 commit ccc474d
Show file tree
Hide file tree
Showing 4 changed files with 377 additions and 130 deletions.
27 changes: 16 additions & 11 deletions barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,37 +434,42 @@ std::vector<Row> Execution::gen_trace(std::vector<Instruction> const& instructio
break;
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6284): support indirect for below
case OpCode::SENDER:
trace_builder.op_sender(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_sender(std::get<uint8_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::ADDRESS:
trace_builder.op_address(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_address(std::get<uint8_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::STORAGEADDRESS:
trace_builder.op_storage_address(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_storage_address(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::FEEPERL2GAS:
trace_builder.op_fee_per_l2_gas(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_fee_per_l2_gas(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::FEEPERDAGAS:
trace_builder.op_fee_per_da_gas(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_fee_per_da_gas(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::TRANSACTIONFEE:
trace_builder.op_transaction_fee(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_transaction_fee(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::CHAINID:
trace_builder.op_chain_id(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_chain_id(std::get<uint8_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::VERSION:
trace_builder.op_version(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_version(std::get<uint8_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::BLOCKNUMBER:
trace_builder.op_block_number(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_block_number(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::COINBASE:
trace_builder.op_coinbase(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_coinbase(std::get<uint8_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::TIMESTAMP:
trace_builder.op_timestamp(std::get<uint32_t>(inst.operands.at(1)));
trace_builder.op_timestamp(std::get<uint8_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
break;
case OpCode::NOTEHASHEXISTS:
trace_builder.op_note_hash_exists(std::get<uint32_t>(inst.operands.at(1)),
Expand Down
91 changes: 65 additions & 26 deletions barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,21 +1149,32 @@ void AvmTraceBuilder::op_cmov(
}

// Helper function to add kernel lookup operations into the main trace
Row AvmTraceBuilder::create_kernel_lookup_opcode(uint32_t dst_offset, uint32_t selector, FF value, AvmMemoryTag w_tag)
Row AvmTraceBuilder::create_kernel_lookup_opcode(
bool indirect, uint32_t dst_offset, uint32_t selector, FF value, AvmMemoryTag w_tag)
{
auto const clk = static_cast<uint32_t>(main_trace.size()) + 1;

bool tag_match = true;
uint32_t direct_dst_offset = dst_offset;
if (indirect) {
auto read_ind_dst =
mem_trace_builder.indirect_read_and_load_from_memory(call_ptr, clk, IndirectRegister::IND_A, dst_offset);
direct_dst_offset = uint32_t(read_ind_dst.val);
tag_match = tag_match && read_ind_dst.tag_match;
}

AvmMemoryTag r_tag = AvmMemoryTag::U0;
mem_trace_builder.write_into_memory(call_ptr, clk, IntermRegister::IA, dst_offset, value, r_tag, w_tag);
mem_trace_builder.write_into_memory(call_ptr, clk, IntermRegister::IA, direct_dst_offset, value, r_tag, w_tag);

return Row{
.avm_main_clk = clk,
.avm_kernel_kernel_in_offset = selector,
.avm_main_call_ptr = call_ptr,
.avm_main_ia = value,
.avm_main_ind_a = 0,
.avm_main_ind_a = indirect ? FF(dst_offset) : FF(0),
.avm_main_ind_op_a = FF(static_cast<uint32_t>(indirect)),
.avm_main_internal_return_ptr = internal_return_ptr,
.avm_main_mem_idx_a = dst_offset,
.avm_main_mem_idx_a = direct_dst_offset,
.avm_main_mem_op_a = 1,
.avm_main_pc = pc++,
.avm_main_q_kernel_lookup = 1,
Expand All @@ -1172,10 +1183,13 @@ Row AvmTraceBuilder::create_kernel_lookup_opcode(uint32_t dst_offset, uint32_t s
};
}

void AvmTraceBuilder::op_storage_address(uint32_t dst_offset)
void AvmTraceBuilder::op_storage_address(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_storage_address();
Row row = create_kernel_lookup_opcode(dst_offset, STORAGE_ADDRESS_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(
indirect_dst_flag, dst_offset, STORAGE_ADDRESS_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_storage_address = FF(1);

// Constrain gas cost
Expand All @@ -1184,10 +1198,12 @@ void AvmTraceBuilder::op_storage_address(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_sender(uint32_t dst_offset)
void AvmTraceBuilder::op_sender(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_sender();
Row row = create_kernel_lookup_opcode(dst_offset, SENDER_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, SENDER_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_sender = FF(1);

// Constrain gas cost
Expand All @@ -1196,10 +1212,12 @@ void AvmTraceBuilder::op_sender(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_address(uint32_t dst_offset)
void AvmTraceBuilder::op_address(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_address();
Row row = create_kernel_lookup_opcode(dst_offset, ADDRESS_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, ADDRESS_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_address = FF(1);

// Constrain gas cost
Expand All @@ -1208,10 +1226,13 @@ void AvmTraceBuilder::op_address(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_fee_per_da_gas(uint32_t dst_offset)
void AvmTraceBuilder::op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_fee_per_da_gas();
Row row = create_kernel_lookup_opcode(dst_offset, FEE_PER_DA_GAS_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row =
create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, FEE_PER_DA_GAS_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_fee_per_da_gas = FF(1);

// Constrain gas cost
Expand All @@ -1220,10 +1241,13 @@ void AvmTraceBuilder::op_fee_per_da_gas(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_fee_per_l2_gas(uint32_t dst_offset)
void AvmTraceBuilder::op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_fee_per_l2_gas();
Row row = create_kernel_lookup_opcode(dst_offset, FEE_PER_L2_GAS_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row =
create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, FEE_PER_L2_GAS_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_fee_per_l2_gas = FF(1);

// Constrain gas cost
Expand All @@ -1232,10 +1256,13 @@ void AvmTraceBuilder::op_fee_per_l2_gas(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_transaction_fee(uint32_t dst_offset)
void AvmTraceBuilder::op_transaction_fee(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_transaction_fee();
Row row = create_kernel_lookup_opcode(dst_offset, TRANSACTION_FEE_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(
indirect_dst_flag, dst_offset, TRANSACTION_FEE_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_transaction_fee = FF(1);

// Constrain gas cost
Expand All @@ -1244,10 +1271,12 @@ void AvmTraceBuilder::op_transaction_fee(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_chain_id(uint32_t dst_offset)
void AvmTraceBuilder::op_chain_id(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_chain_id();
Row row = create_kernel_lookup_opcode(dst_offset, CHAIN_ID_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, CHAIN_ID_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_chain_id = FF(1);

// Constrain gas cost
Expand All @@ -1256,10 +1285,12 @@ void AvmTraceBuilder::op_chain_id(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_version(uint32_t dst_offset)
void AvmTraceBuilder::op_version(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_version();
Row row = create_kernel_lookup_opcode(dst_offset, VERSION_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, VERSION_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_version = FF(1);

// Constrain gas cost
Expand All @@ -1268,10 +1299,13 @@ void AvmTraceBuilder::op_version(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_block_number(uint32_t dst_offset)
void AvmTraceBuilder::op_block_number(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_block_number();
Row row = create_kernel_lookup_opcode(dst_offset, BLOCK_NUMBER_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row =
create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, BLOCK_NUMBER_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_block_number = FF(1);

// Constrain gas cost
Expand All @@ -1280,10 +1314,12 @@ void AvmTraceBuilder::op_block_number(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_coinbase(uint32_t dst_offset)
void AvmTraceBuilder::op_coinbase(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_coinbase();
Row row = create_kernel_lookup_opcode(dst_offset, COINBASE_SELECTOR, ia_value, AvmMemoryTag::FF);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row = create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, COINBASE_SELECTOR, ia_value, AvmMemoryTag::FF);
row.avm_main_sel_op_coinbase = FF(1);

// Constrain gas cost
Expand All @@ -1292,10 +1328,13 @@ void AvmTraceBuilder::op_coinbase(uint32_t dst_offset)
main_trace.push_back(row);
}

void AvmTraceBuilder::op_timestamp(uint32_t dst_offset)
void AvmTraceBuilder::op_timestamp(uint8_t indirect, uint32_t dst_offset)
{
FF ia_value = kernel_trace_builder.op_timestamp();
Row row = create_kernel_lookup_opcode(dst_offset, TIMESTAMP_SELECTOR, ia_value, AvmMemoryTag::U64);

bool indirect_dst_flag = is_operand_indirect(indirect, 0);
Row row =
create_kernel_lookup_opcode(indirect_dst_flag, dst_offset, TIMESTAMP_SELECTOR, ia_value, AvmMemoryTag::U64);
row.avm_main_sel_op_timestamp = FF(1);

// Constrain gas cost
Expand Down
26 changes: 14 additions & 12 deletions barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,21 @@ class AvmTraceBuilder {
void op_cmov(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t cond_offset, uint32_t dst_offset);

// Call Context
void op_storage_address(uint32_t dst_offset);
void op_sender(uint32_t dst_offset);
void op_address(uint32_t dst_offset);
void op_storage_address(uint8_t indirect, uint32_t dst_offset);
void op_sender(uint8_t indirect, uint32_t dst_offset);
void op_address(uint8_t indirect, uint32_t dst_offset);

// Fees
void op_fee_per_da_gas(uint32_t dst_offset);
void op_fee_per_l2_gas(uint32_t dst_offset);
void op_transaction_fee(uint32_t dst_offset);
void op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset);
void op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offset);
void op_transaction_fee(uint8_t indirect, uint32_t dst_offset);

// Globals
void op_chain_id(uint32_t dst_offset);
void op_version(uint32_t dst_offset);
void op_block_number(uint32_t dst_offset);
void op_coinbase(uint32_t dst_offset);
void op_timestamp(uint32_t dst_offset);
void op_chain_id(uint8_t indirect, uint32_t dst_offset);
void op_version(uint8_t indirect, uint32_t dst_offset);
void op_block_number(uint8_t indirect, uint32_t dst_offset);
void op_coinbase(uint8_t indirect, uint32_t dst_offset);
void op_timestamp(uint8_t indirect, uint32_t dst_offset);

// Outputs
// With single output values
Expand Down Expand Up @@ -223,13 +223,15 @@ class AvmTraceBuilder {
*
* Used for looking up into the kernel inputs (context) - {caller, address, etc.}
*
* @param indirect - Perform indirect memory resolution
* @param dst_offset - Memory address to write the lookup result to
* @param selector - The index of the kernel input lookup column
* @param value - The value read from the memory address
* @param w_tag - The memory tag of the value read
* @return Row
*/
Row create_kernel_lookup_opcode(uint32_t dst_offset, uint32_t selector, FF value, AvmMemoryTag w_tag);
Row create_kernel_lookup_opcode(
bool indirect, uint32_t dst_offset, uint32_t selector, FF value, AvmMemoryTag w_tag);

/**
* @brief Create a kernel output opcode object
Expand Down
Loading

0 comments on commit ccc474d

Please sign in to comment.