diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs index 1de1f7803c8..b61467b2791 100644 --- a/avm-transpiler/src/opcodes.rs +++ b/avm-transpiler/src/opcodes.rs @@ -65,7 +65,6 @@ pub enum AvmOpcode { // External calls CALL, STATICCALL, - DELEGATECALL, RETURN, REVERT_8, REVERT_16, @@ -161,7 +160,6 @@ impl AvmOpcode { // Control Flow - Contract Calls AvmOpcode::CALL => "CALL", AvmOpcode::STATICCALL => "STATICCALL", - AvmOpcode::DELEGATECALL => "DELEGATECALL", AvmOpcode::RETURN => "RETURN", AvmOpcode::REVERT_8 => "REVERT_8", AvmOpcode::REVERT_16 => "REVERT_16", diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index f0888b22a46..b4adcf6dcd1 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -800,7 +800,6 @@ fn handle_getter_instruction( ) { enum EnvironmentVariable { ADDRESS, - STORAGEADDRESS, SENDER, FUNCTIONSELECTOR, TRANSACTIONFEE, @@ -827,7 +826,6 @@ fn handle_getter_instruction( let var_idx = match function { "avmOpcodeAddress" => EnvironmentVariable::ADDRESS, - "avmOpcodeStorageAddress" => EnvironmentVariable::STORAGEADDRESS, "avmOpcodeSender" => EnvironmentVariable::SENDER, "avmOpcodeFeePerL2Gas" => EnvironmentVariable::FEEPERL2GAS, "avmOpcodeFeePerDaGas" => EnvironmentVariable::FEEPERDAGAS, diff --git a/barretenberg/cpp/pil/avm/constants_gen.pil b/barretenberg/cpp/pil/avm/constants_gen.pil index 8eab33c0234..482f52edd44 100644 --- a/barretenberg/cpp/pil/avm/constants_gen.pil +++ b/barretenberg/cpp/pil/avm/constants_gen.pil @@ -20,7 +20,6 @@ namespace constants(256); pol MEM_TAG_U128 = 6; pol SENDER_KERNEL_INPUTS_COL_OFFSET = 0; pol ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; - pol STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; pol FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET = 2; pol IS_STATIC_CALL_KERNEL_INPUTS_COL_OFFSET = 3; pol CHAIN_ID_KERNEL_INPUTS_COL_OFFSET = 4; diff --git a/barretenberg/cpp/pil/avm/kernel.pil b/barretenberg/cpp/pil/avm/kernel.pil index 133d293d0fc..3b6594c297b 100644 --- a/barretenberg/cpp/pil/avm/kernel.pil +++ b/barretenberg/cpp/pil/avm/kernel.pil @@ -92,9 +92,6 @@ namespace main(256); #[ADDRESS_KERNEL] sel_op_address * (kernel_in_offset - constants.ADDRESS_KERNEL_INPUTS_COL_OFFSET) = 0; - #[STORAGE_ADDRESS_KERNEL] - sel_op_storage_address * (kernel_in_offset - constants.STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET) = 0; - #[SENDER_KERNEL] sel_op_sender * (kernel_in_offset - constants.SENDER_KERNEL_INPUTS_COL_OFFSET) = 0; @@ -174,7 +171,7 @@ namespace main(256); //KERNEL_OUTPUT_SELECTORS * (side_effect_counter' - (side_effect_counter + 1)) = 0; //===== LOOKUPS INTO THE PUBLIC INPUTS =========================================== - pol KERNEL_INPUT_SELECTORS = sel_op_address + sel_op_storage_address + sel_op_sender + pol KERNEL_INPUT_SELECTORS = sel_op_address + sel_op_sender + sel_op_function_selector + sel_op_transaction_fee + sel_op_chain_id + sel_op_version + sel_op_block_number + sel_op_timestamp + sel_op_fee_per_l2_gas + sel_op_fee_per_da_gas + sel_op_is_static_call; diff --git a/barretenberg/cpp/pil/avm/main.pil b/barretenberg/cpp/pil/avm/main.pil index 4e395413142..e13f0b62b54 100644 --- a/barretenberg/cpp/pil/avm/main.pil +++ b/barretenberg/cpp/pil/avm/main.pil @@ -32,7 +32,7 @@ namespace main(256); pol commit sel_execution_end; // Toggle next row of last execution trace row. // Used as a LHS selector of the lookup to enforce final gas values which correspond to - // l2_gas_remaining and da_gas_remaining values located at the row after last execution row. + // l2_gas_remaining and da_gas_remaining values located at the row after last execution row. sel_execution_end' = sel_execution_row * (1 - sel_execution_row') * (1 - sel_first); //===== PUBLIC COLUMNS========================================================= @@ -47,7 +47,6 @@ namespace main(256); // CONTEXT - ENVIRONMENT pol commit sel_op_address; - pol commit sel_op_storage_address; pol commit sel_op_sender; pol commit sel_op_function_selector; pol commit sel_op_transaction_fee; @@ -218,7 +217,6 @@ namespace main(256); // TODO: Very likely, we can remove these constraints as the selectors should be derived during // opcode decomposition. sel_op_address * (1 - sel_op_address) = 0; - sel_op_storage_address * (1 - sel_op_storage_address) = 0; sel_op_sender * (1 - sel_op_sender) = 0; sel_op_function_selector * (1 - sel_op_function_selector) = 0; sel_op_transaction_fee * (1 - sel_op_transaction_fee) = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp index e4aa027a298..0866ba51d9e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -1403,57 +1403,53 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) "0001" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag - + to_hex(static_cast(EnvironmentVariable::STORAGEADDRESS)) + // envvar STORAGEADDRESS - "0002" // dst_offset - + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 - "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::SENDER)) + // envvar SENDER - "0003" // dst_offset + "0002" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::FUNCTIONSELECTOR)) + // envvar FUNCTIONSELECTOR - "0004" // dst_offset + "0003" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::TRANSACTIONFEE)) + // envvar TRANSACTIONFEE - "0005" // dst_offset + "0004" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::CHAINID)) + // envvar CHAINID - "0006" // dst_offset + "0005" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::VERSION)) + // envvar VERSION - "0007" // dst_offset + "0006" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::BLOCKNUMBER)) + // envvar BLOCKNUMBER - "0008" // dst_offset + "0007" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::TIMESTAMP)) + // envvar TIMESTAMP - "0009" // dst_offset + "0008" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::FEEPERL2GAS)) + // envvar FEEPERL2GAS - "000A" // dst_offset + "0009" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::FEEPERDAGAS)) + // envvar FEEPERDAGAS - "000B" // dst_offset + "000A" // dst_offset + to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16 "00" // Indirect flag + to_hex(static_cast(EnvironmentVariable::ISSTATICCALL)) + // envvar ISSTATICCALL - "000C" // dst_offset + "000B" // dst_offset + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "0001" // ret offset 1 - "000C"; // ret size 12 + "000B"; // ret size 12 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); - ASSERT_THAT(instructions, SizeIs(13)); + ASSERT_THAT(instructions, SizeIs(12)); // ADDRESS EXPECT_THAT(instructions.at(0), @@ -1463,126 +1459,114 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) VariantWith(static_cast(EnvironmentVariable::ADDRESS)), VariantWith(1))))); - // STORAGEADDRESS - EXPECT_THAT(instructions.at(1), - AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), - Field(&Instruction::operands, - ElementsAre(VariantWith(0), - VariantWith(static_cast(EnvironmentVariable::STORAGEADDRESS)), - VariantWith(2))))); - // SENDER - EXPECT_THAT(instructions.at(2), + EXPECT_THAT(instructions.at(1), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::SENDER)), - VariantWith(3))))); + VariantWith(2))))); // FUNCTIONSELECTOR EXPECT_THAT( - instructions.at(3), + instructions.at(2), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::FUNCTIONSELECTOR)), - VariantWith(4))))); + VariantWith(3))))); // TRANSACTIONFEE - EXPECT_THAT(instructions.at(4), + EXPECT_THAT(instructions.at(3), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::TRANSACTIONFEE)), - VariantWith(5))))); + VariantWith(4))))); // CHAINID - EXPECT_THAT(instructions.at(5), + EXPECT_THAT(instructions.at(4), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::CHAINID)), - VariantWith(6))))); + VariantWith(5))))); // VERSION - EXPECT_THAT(instructions.at(6), + EXPECT_THAT(instructions.at(5), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::VERSION)), - VariantWith(7))))); + VariantWith(6))))); // BLOCKNUMBER - EXPECT_THAT(instructions.at(7), + EXPECT_THAT(instructions.at(6), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::BLOCKNUMBER)), - VariantWith(8))))); + VariantWith(7))))); // TIMESTAMP - EXPECT_THAT(instructions.at(8), + EXPECT_THAT(instructions.at(7), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::TIMESTAMP)), - VariantWith(9))))); + VariantWith(8))))); // FEEPERL2GAS - EXPECT_THAT(instructions.at(9), + EXPECT_THAT(instructions.at(8), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::FEEPERL2GAS)), - VariantWith(10))))); + VariantWith(9))))); // FEEPERDAGAS - EXPECT_THAT(instructions.at(10), + EXPECT_THAT(instructions.at(9), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::FEEPERDAGAS)), - VariantWith(11))))); + VariantWith(10))))); // ISSTATICCALL - EXPECT_THAT(instructions.at(11), + EXPECT_THAT(instructions.at(10), AllOf(Field(&Instruction::op_code, OpCode::GETENVVAR_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(static_cast(EnvironmentVariable::ISSTATICCALL)), - VariantWith(12))))); + VariantWith(11))))); // Public inputs for the circuit std::vector calldata; FF sender = 1; FF address = 2; - // NOTE: address doesn't actually exist in public circuit public inputs, - // so storage address is just an alias of address for now - FF storage_address = address; - FF function_selector = 4; - FF transaction_fee = 5; - FF chainid = 6; - FF version = 7; - FF blocknumber = 8; - FF timestamp = 9; - FF feeperl2gas = 10; - FF feeperdagas = 11; - FF is_static_call = 12; + FF function_selector = 3; + FF transaction_fee = 4; + FF chainid = 5; + FF version = 6; + FF blocknumber = 7; + FF timestamp = 8; + FF feeperl2gas = 9; + FF feeperdagas = 10; + FF is_static_call = 11; // The return data for this test should be a the opcodes in sequence, as the opcodes dst address lines up with // this array The returndata call above will then return this array std::vector const expected_returndata = { - address, storage_address, sender, function_selector, transaction_fee, chainid, - version, blocknumber, timestamp, feeperl2gas, feeperdagas, is_static_call, + address, sender, function_selector, transaction_fee, chainid, version, + blocknumber, timestamp, feeperl2gas, feeperdagas, is_static_call, }; // Set up public inputs to contain the above values // TODO: maybe have a javascript like object construction so that this is readable // Reduce the amount of times we have similar code to this // - public_inputs_vec[STORAGE_ADDRESS_PCPI_OFFSET] = address; - public_inputs_vec[STORAGE_ADDRESS_PCPI_OFFSET] = storage_address; + public_inputs_vec[ADDRESS_PCPI_OFFSET] = address; public_inputs_vec[SENDER_PCPI_OFFSET] = sender; public_inputs_vec[FUNCTION_SELECTOR_PCPI_OFFSET] = function_selector; public_inputs_vec[TRANSACTION_FEE_PCPI_OFFSET] = transaction_fee; @@ -1609,11 +1593,6 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_address == 1; }); EXPECT_EQ(address_row->main_ia, address); - // Check storage address - auto storage_addr_row = - std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_storage_address == 1; }); - EXPECT_EQ(storage_addr_row->main_ia, storage_address); - // Check sender auto sender_row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_sender == 1; }); EXPECT_EQ(sender_row->main_ia, sender); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp index 0faf3e1f66e..2143d2419f2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp @@ -256,40 +256,6 @@ TEST_F(AvmKernelPositiveTests, kernelAddress) test_kernel_lookup(true, indirect_apply_opcodes, checks); } -TEST_F(AvmKernelPositiveTests, kernelStorageAddress) -{ - uint32_t dst_offset = 42; - uint32_t indirect_dst_offset = 69; - auto direct_apply_opcodes = [=](AvmTraceBuilder& trace_builder) { - trace_builder.op_storage_address(/*indirect*/ 0, dst_offset); - }; - auto indirect_apply_opcodes = [=](AvmTraceBuilder& trace_builder) { - trace_builder.op_set( - /*indirect*/ 0, - /*value*/ dst_offset, - /*dst_offset*/ indirect_dst_offset, - AvmMemoryTag::U32); - trace_builder.op_storage_address(/*indirect*/ 1, indirect_dst_offset); - }; - - auto checks = [=](bool indirect, const std::vector& trace) { - auto storage_address_row = std::ranges::find_if( - trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_storage_address == FF(1); }); - EXPECT_TRUE(storage_address_row != trace.end()); - - expect_row(storage_address_row, - /*kernel_in_offset=*/STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET, - /*ia=*/STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET + - 1, // Note the value generated above for public inputs is the same as the index read + 1 - /*ind_a*/ indirect ? indirect_dst_offset : 0, - /*mem_addr_a=*/dst_offset, - /*w_in_tag=*/AvmMemoryTag::FF); - }; - - test_kernel_lookup(false, direct_apply_opcodes, checks); - test_kernel_lookup(true, indirect_apply_opcodes, checks); -} - TEST_F(AvmKernelPositiveTests, kernelFunctionSelector) { // Direct @@ -681,32 +647,6 @@ TEST_F(AvmKernelNegativeTests, incorrectIaAddress) negative_test_incorrect_ia_kernel_lookup(apply_opcodes, checks, incorrect_ia, BAD_LOOKUP); } -TEST_F(AvmKernelNegativeTests, incorrectIaStorageAddress) -{ - uint32_t dst_offset = 42; - FF incorrect_ia = FF(69); - - // We test that the sender opcode is inlcuded at index x in the public inputs - auto apply_opcodes = [=](AvmTraceBuilder& trace_builder) { - trace_builder.op_storage_address(/*indirect*/ 0, dst_offset); - }; - auto checks = [=](bool indirect, const std::vector& trace) { - auto row = std::ranges::find_if( - trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_storage_address == FF(1); }); - EXPECT_TRUE(row != trace.end()); - - expect_row( - row, - /*kernel_in_offset=*/STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET, - /*ia=*/incorrect_ia, // Note the value generated above for public inputs is the same as the index read + 1 - /*ind_a*/ indirect, - /*mem_addr_a=*/dst_offset, - /*w_in_tag=*/AvmMemoryTag::FF); - }; - - negative_test_incorrect_ia_kernel_lookup(apply_opcodes, checks, incorrect_ia, BAD_LOOKUP); -} - TEST_F(AvmKernelNegativeTests, incorrectIaFunctionSelector) { uint32_t dst_offset = 42; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index 81360626bfc..8a573f820e5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -148,7 +148,6 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = // Control Flow - Contract Calls { OpCode::CALL, external_call_format }, { OpCode::STATICCALL, external_call_format }, - // DELEGATECALL, -- not in simulator { OpCode::RETURN, { OperandType::INDIRECT8, OperandType::UINT16, OperandType::UINT16 } }, // REVERT, { OpCode::REVERT_8, { OperandType::INDIRECT8, OperandType::UINT8, OperandType::UINT8 } }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp index 9f37ad46e98..667014ebe34 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp @@ -78,7 +78,6 @@ const std::unordered_map GAS_COST_TABLE = { { OpCode::SENDL2TOL1MSG, make_cost(AVM_SENDL2TOL1MSG_BASE_L2_GAS, AVM_SENDL2TOL1MSG_BASE_DA_GAS, 0, 0) }, { OpCode::CALL, make_cost(AVM_CALL_BASE_L2_GAS, 0, AVM_CALL_DYN_L2_GAS, 0) }, { OpCode::STATICCALL, make_cost(AVM_STATICCALL_BASE_L2_GAS, 0, AVM_STATICCALL_DYN_L2_GAS, 0) }, - { OpCode::DELEGATECALL, make_cost(AVM_DELEGATECALL_BASE_L2_GAS, 0, AVM_DELEGATECALL_DYN_L2_GAS, 0) }, { OpCode::RETURN, make_cost(AVM_RETURN_BASE_L2_GAS, 0, AVM_RETURN_DYN_L2_GAS, 0) }, { OpCode::REVERT_8, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) }, { OpCode::REVERT_16, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp index 5cc04964bf8..ecd1fc65076 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp @@ -56,11 +56,8 @@ template VmPublicInputs_ convert_public_inputs(std::vector>& main_trace) dest.main_kernel_in_offset = ADDRESS_KERNEL_INPUTS_COL_OFFSET; dest.main_sel_q_kernel_lookup = 1; break; - case KernelTraceOpType::STORAGE_ADDRESS: - dest.main_kernel_in_offset = STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET; - dest.main_sel_q_kernel_lookup = 1; - break; case KernelTraceOpType::SENDER: dest.main_kernel_in_offset = SENDER_KERNEL_INPUTS_COL_OFFSET; dest.main_sel_q_kernel_lookup = 1; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/kernel_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/kernel_trace.hpp index 49979bca3cd..094441fe83b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/kernel_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/kernel_trace.hpp @@ -17,7 +17,6 @@ class AvmKernelTraceBuilder { enum class KernelTraceOpType { // IN ADDRESS, - STORAGE_ADDRESS, SENDER, FUNCTION_SELECTOR, TRANSACTION_FEE, @@ -70,7 +69,6 @@ class AvmKernelTraceBuilder { // Context FF op_address(uint32_t clk); - FF op_storage_address(uint32_t clk); FF op_sender(uint32_t clk); FF op_function_selector(uint32_t clk); FF op_transaction_fee(uint32_t clk); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp index 724ee32e2cc..5fe13fb17f3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp @@ -147,8 +147,6 @@ std::string to_string(OpCode opcode) return "CALL"; case OpCode::STATICCALL: return "STATICCALL"; - case OpCode::DELEGATECALL: - return "DELEGATECALL"; case OpCode::RETURN: return "RETURN"; case OpCode::REVERT_8: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp index feab28e807a..1ed090f40b5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp @@ -90,7 +90,6 @@ enum class OpCode : uint8_t { // Control Flow - Contract Calls CALL, STATICCALL, - DELEGATECALL, RETURN, REVERT_8, REVERT_16, @@ -116,7 +115,6 @@ enum class OpCode : uint8_t { enum class EnvironmentVariable { ADDRESS, - STORAGEADDRESS, SENDER, FUNCTIONSELECTOR, TRANSACTIONFEE, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index f5af8ca0d78..db7fe0ddc0c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -1266,9 +1266,6 @@ void AvmTraceBuilder::op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t case EnvironmentVariable::ADDRESS: op_address(indirect, dst_offset); break; - case EnvironmentVariable::STORAGEADDRESS: - op_storage_address(indirect, dst_offset); - break; case EnvironmentVariable::SENDER: op_sender(indirect, dst_offset); break; @@ -1323,19 +1320,6 @@ void AvmTraceBuilder::op_address(uint8_t indirect, uint32_t dst_offset) main_trace.push_back(row); } -void AvmTraceBuilder::op_storage_address(uint8_t indirect, uint32_t dst_offset) -{ - auto const clk = static_cast(main_trace.size()) + 1; - FF ia_value = kernel_trace_builder.op_storage_address(clk); - Row row = create_kernel_lookup_opcode(indirect, dst_offset, ia_value, AvmMemoryTag::FF); - row.main_sel_op_storage_address = FF(1); - - // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); - - main_trace.push_back(row); -} - void AvmTraceBuilder::op_sender(uint8_t indirect, uint32_t dst_offset) { auto const clk = static_cast(main_trace.size()) + 1; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index dc8e743c3d1..c0b4fb75521 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -63,7 +63,6 @@ class AvmTraceBuilder { // Execution Environment void op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t dst_offset); void op_address(uint8_t indirect, 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_function_selector(uint8_t indirect, uint32_t dst_offset); void op_transaction_fee(uint8_t indirect, uint32_t dst_offset); diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index e80e5ae7faa..6ae5175611a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -16,7 +16,7 @@ #define AZTEC_ADDRESS_LENGTH 1 #define GAS_FEES_LENGTH 2 #define GAS_LENGTH 2 -#define CALL_CONTEXT_LENGTH 5 +#define CALL_CONTEXT_LENGTH 4 #define CONTENT_COMMITMENT_LENGTH 4 #define CONTRACT_STORAGE_READ_LENGTH 3 #define CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH 3 @@ -28,16 +28,16 @@ #define LOG_HASH_LENGTH 3 #define NOTE_HASH_LENGTH 2 #define NULLIFIER_LENGTH 3 -#define PUBLIC_INNER_CALL_REQUEST_LENGTH 14 +#define PUBLIC_INNER_CALL_REQUEST_LENGTH 13 #define STATE_REFERENCE_LENGTH 8 #define TOTAL_FEES_LENGTH 1 #define HEADER_LENGTH 24 -#define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 691 -#define PUBLIC_CONTEXT_INPUTS_LENGTH 42 +#define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 674 +#define PUBLIC_CONTEXT_INPUTS_LENGTH 41 #define AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS 86 #define AVM_PROOF_LENGTH_IN_FIELDS 3848 #define AVM_PUBLIC_COLUMN_MAX_SIZE 1024 -#define AVM_PUBLIC_INPUTS_FLATTENED_SIZE 2739 +#define AVM_PUBLIC_INPUTS_FLATTENED_SIZE 2722 #define MEM_TAG_FF 0 #define MEM_TAG_U1 1 #define MEM_TAG_U8 2 @@ -47,7 +47,6 @@ #define MEM_TAG_U128 6 #define SENDER_KERNEL_INPUTS_COL_OFFSET 0 #define ADDRESS_KERNEL_INPUTS_COL_OFFSET 1 -#define STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET 1 #define FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET 2 #define IS_STATIC_CALL_KERNEL_INPUTS_COL_OFFSET 3 #define CHAIN_ID_KERNEL_INPUTS_COL_OFFSET 4 @@ -106,7 +105,6 @@ #define AVM_SENDL2TOL1MSG_BASE_L2_GAS 226 #define AVM_CALL_BASE_L2_GAS 2445 #define AVM_STATICCALL_BASE_L2_GAS 2445 -#define AVM_DELEGATECALL_BASE_L2_GAS 2445 #define AVM_RETURN_BASE_L2_GAS 28 #define AVM_REVERT_BASE_L2_GAS 28 #define AVM_DEBUGLOG_BASE_L2_GAS 12 @@ -124,7 +122,6 @@ #define AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS 146 #define AVM_CALL_DYN_L2_GAS 4 #define AVM_STATICCALL_DYN_L2_GAS 4 -#define AVM_DELEGATECALL_DYN_L2_GAS 4 #define AVM_RETURN_DYN_L2_GAS 6 #define AVM_REVERT_DYN_L2_GAS 6 #define AVM_KECCAK_DYN_L2_GAS 100 diff --git a/barretenberg/cpp/src/barretenberg/vm/constants.hpp b/barretenberg/cpp/src/barretenberg/vm/constants.hpp index ddfffef9e78..7456b2ef924 100644 --- a/barretenberg/cpp/src/barretenberg/vm/constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/constants.hpp @@ -26,9 +26,9 @@ static_assert(KERNEL_OUTPUTS_LENGTH < AVM_PUBLIC_COLUMN_MAX_SIZE, // These line up with indexes found in // https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts inline const uint32_t SENDER_PCPI_OFFSET = 0; -inline const uint32_t STORAGE_ADDRESS_PCPI_OFFSET = 1; +inline const uint32_t ADDRESS_PCPI_OFFSET = 1; inline const uint32_t FUNCTION_SELECTOR_PCPI_OFFSET = 2; -inline const uint32_t IS_STATIC_CALL_PCPI_OFFSET = 4; +inline const uint32_t IS_STATIC_CALL_PCPI_OFFSET = 3; inline const uint32_t PCPI_GLOBALS_START = PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH - 7 - GLOBAL_VARIABLES_LENGTH; diff --git a/cspell.json b/cspell.json index d886dd8733e..85d6c13f72c 100644 --- a/cspell.json +++ b/cspell.json @@ -66,8 +66,6 @@ "decrementation", "deduped", "defi", - "delegatecall", - "delegatecalls", "demonomorphization", "demonomorphize", "demonomorphized", @@ -316,7 +314,5 @@ "lib", "*.cmake" ], - "flagWords": [ - "anonymous" - ] + "flagWords": ["anonymous"] } diff --git a/docs/docs/protocol-specs/addresses-and-keys/precompiles.md b/docs/docs/protocol-specs/addresses-and-keys/precompiles.md index 737c09e2299..07348290ea1 100644 --- a/docs/docs/protocol-specs/addresses-and-keys/precompiles.md +++ b/docs/docs/protocol-specs/addresses-and-keys/precompiles.md @@ -70,7 +70,7 @@ Encrypts and tags the given plaintext using the provided public keys, and return encrypt_and_broadcast(public_keys_hash: Field, encryption_type: EncryptionType, recipient: AztecAddress, plaintext: Field[MAX_PLAINTEXT_LENGTH]): Field[MAX_TAGGED_CIPHERTEXT_LENGTH] ``` -Encrypts and tags the given plaintext using the provided public keys, broadcasts them as an event, and returns the encrypted note prefixed with its tag for note discovery. These functions should be invoked via a [delegate call](../calls/delegate-calls.md), so that the broadcasted event is emitted as if it were from the caller contract. +Encrypts and tags the given plaintext using the provided public keys, broadcasts them as an event, and returns the encrypted note prefixed with its tag for note discovery. ``` encrypt([call_context: CallContext, public_keys_hash: Field, encryption_type: EncryptionType, recipient: AztecAddress, plaintext: Field[MAX_PLAINTEXT_LENGTH] ][N]): Field[MAX_CIPHERTEXT_LENGTH][N] diff --git a/docs/docs/protocol-specs/calls/delegate-calls.md b/docs/docs/protocol-specs/calls/delegate-calls.md deleted file mode 100644 index a9edd81b23e..00000000000 --- a/docs/docs/protocol-specs/calls/delegate-calls.md +++ /dev/null @@ -1,17 +0,0 @@ -# Delegate calls - - - -Delegate calls are function calls against a contract class identifier instead of an instance. Any call -- synchronous or asynchronous -- can be made as a delegate call. The behavior of a delegate call is to execute the function code in the specified class identifier but in the context of the current instance. This opens the door to script-like executions and upgradeable contracts. Delegate calls are based on [EIP7](https://eips.ethereum.org/EIPS/eip-7). - -At the protocol level, a delegate call is identified by a `is_delegate_call` flag in the `CircuitPublicInputs` of the `CallStackItem`. The `contract_address` field is reinterpreted as a contract class instead. When executing a delegate call, the kernel preserves the values of the `CallContext` `msgSender` and `storageContractAddress`. - - - -At the contract level, a caller can initiate a delegate call via a `delegateCallPrivateFunction` or `delegateCallPublicFunction` oracle call. The caller is responsible for asserting that the returned `CallStackItem` has the `is_delegate_call` flag correctly set. diff --git a/docs/docs/protocol-specs/calls/index.md b/docs/docs/protocol-specs/calls/index.md index b19bfcbc5b3..956e31b1080 100644 --- a/docs/docs/protocol-specs/calls/index.md +++ b/docs/docs/protocol-specs/calls/index.md @@ -17,7 +17,7 @@ Functions in the Aztec Network can call other functions. There are several types - [Enqueued calls](./enqueued-calls.md): when a private function calls a public function. - [Batched calls](./batched-calls.md): when multiple calls to the same function are enqueued and processed as a single call on a concatenation of the arguments. -The protocol also supports alternative call methods, such as [static](./static-calls.md), [delegate](./delegate-calls.md), and [unconstrained](./unconstrained-calls.md) calls. +The protocol also supports alternative call methods, such as [static](./static-calls.md), and [unconstrained](./unconstrained-calls.md) calls. In addition to function calls, the protocol allows for communication via message-passing back-and-forth between L1 and L2, as well as from public to private functions. diff --git a/docs/docs/protocol-specs/circuits/private-function.md b/docs/docs/protocol-specs/circuits/private-function.md index 3beae7c57b4..11d7407dcfb 100644 --- a/docs/docs/protocol-specs/circuits/private-function.md +++ b/docs/docs/protocol-specs/circuits/private-function.md @@ -38,28 +38,28 @@ Some tweaks might be needed following this discussion: https://docs.google.com/s The public inputs of _every_ private function _must_ adhere to the following ABI: -| Field | Type | Description | -| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | -| `call_context` | [`CallContext`](#callcontext) | Context of the call corresponding to this function execution. | -| `args_hash` | `field` | Hash of the function arguments. | -| `return_values` | [`field`; [`RETURN_VALUES_LENGTH`](../constants.md#circuit-constants)] | Return values of this function call. | -| `note_hashes` | [[`NoteHash`](#notehash); [`MAX_NOTE_HASHES_PER_CALL`](../constants.md#circuit-constants)] | New note hashes created in this function call. | -| `nullifiers` | [[`Nullifier`](#nullifier); [`MAX_NULLIFIERS_PER_CALL`](../constants.md#circuit-constants)] | New nullifiers created in this function call. | -| `l2_to_l1_messages` | [[`L2toL1Message`](#l2tol1message); [`MAX_L2_TO_L1_MSGS_PER_CALL`](../constants.md#circuit-constants)] | New L2 to L1 messages created in this function call. | -| `unencrypted_log_hashes` | [[`UnencryptedLogHash`](#unencryptedloghash); [`MAX_UNENCRYPTED_LOG_HASHES_PER_CALL`](../constants.md#circuit-constants)] | Hashes of the unencrypted logs emitted in this function call. | -| `encrypted_log_hashes` | [[`EncryptedLogHash`](#encryptedloghash); [`MAX_ENCRYPTED_LOG_HASHES_PER_CALL`](../constants.md#circuit-constants)] | Hashes of the encrypted logs emitted in this function call. | -| `encrypted_note_preimage_hashes` | [[`EncryptedNotePreimageHash`](#encryptednotepreimagehash); [`MAX_ENCRYPTED_NOTE_PREIMAGE_HASHES_PER_CALL`](../constants.md#circuit-constants)] | Hashes of the encrypted note preimages emitted in this function call. | -| `note_hash_read_requests` | [[`ReadRequest`](#readrequest); [`MAX_NOTE_HASH_READ_REQUESTS_PER_CALL`](../constants.md#circuit-constants)] | Requests to prove the note hashes being read exist. | -| `nullifier_read_requests` | [[`ReadRequest`](#readrequest); [`MAX_NULLIFIER_READ_REQUESTS_PER_CALL`](../constants.md#circuit-constants)] | Requests to prove the nullifiers being read exist. | -| `key_validation_requests` | [[`ParentSecretKeyValidationRequest`](#parentsecretkeyvalidationrequest); [`MAX_KEY_VALIDATION_REQUESTS_PER_CALL`](../constants.md#circuit-constants)] | Requests to validate keys used in this function call. | -| `public_call_requests` | [[`PublicCallRequest`](#publiccallrequest); [`MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL`](../constants.md#circuit-constants)] | Requests to call public functions. | -| `private_call_requests` | [[`PrivateCallRequest`](#privatecallrequest); [`MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL`](../constants.md#circuit-constants)] | Requests to call Private functions. | -| `counter_start` | `u32` | Counter at which the function call was initiated. | -| `counter_end` | `u32` | Counter at which the function call ended. | -| `min_revertible_side_effect_counter` | `u32` | Counter below which the side effects are non-revertible. | -| `block_header` | [`BlockHeader`](#blockheader) | Information about the trees used for the transaction. | -| `chain_id` | `field` | Chain ID of the transaction. | -| `version` | `field` | Version of the transaction. | +| Field | Type | Description | +| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | +| `call_context` | [`CallContext`](#callcontext) | Context of the call corresponding to this function execution. | +| `args_hash` | `field` | Hash of the function arguments. | +| `return_values` | [`field`; [`RETURN_VALUES_LENGTH`](../constants.md#circuit-constants)] | Return values of this function call. | +| `note_hashes` | [[`NoteHash`](#notehash); [`MAX_NOTE_HASHES_PER_CALL`](../constants.md#circuit-constants)] | New note hashes created in this function call. | +| `nullifiers` | [[`Nullifier`](#nullifier); [`MAX_NULLIFIERS_PER_CALL`](../constants.md#circuit-constants)] | New nullifiers created in this function call. | +| `l2_to_l1_messages` | [[`L2toL1Message`](#l2tol1message); [`MAX_L2_TO_L1_MSGS_PER_CALL`](../constants.md#circuit-constants)] | New L2 to L1 messages created in this function call. | +| `unencrypted_log_hashes` | [[`UnencryptedLogHash`](#unencryptedloghash); [`MAX_UNENCRYPTED_LOG_HASHES_PER_CALL`](../constants.md#circuit-constants)] | Hashes of the unencrypted logs emitted in this function call. | +| `encrypted_log_hashes` | [[`EncryptedLogHash`](#encryptedloghash); [`MAX_ENCRYPTED_LOG_HASHES_PER_CALL`](../constants.md#circuit-constants)] | Hashes of the encrypted logs emitted in this function call. | +| `encrypted_note_preimage_hashes` | [[`EncryptedNotePreimageHash`](#encryptednotepreimagehash); [`MAX_ENCRYPTED_NOTE_PREIMAGE_HASHES_PER_CALL`](../constants.md#circuit-constants)] | Hashes of the encrypted note preimages emitted in this function call. | +| `note_hash_read_requests` | [[`ReadRequest`](#readrequest); [`MAX_NOTE_HASH_READ_REQUESTS_PER_CALL`](../constants.md#circuit-constants)] | Requests to prove the note hashes being read exist. | +| `nullifier_read_requests` | [[`ReadRequest`](#readrequest); [`MAX_NULLIFIER_READ_REQUESTS_PER_CALL`](../constants.md#circuit-constants)] | Requests to prove the nullifiers being read exist. | +| `key_validation_requests` | [[`ParentSecretKeyValidationRequest`](#parentsecretkeyvalidationrequest); [`MAX_KEY_VALIDATION_REQUESTS_PER_CALL`](../constants.md#circuit-constants)] | Requests to validate keys used in this function call. | +| `public_call_requests` | [[`PublicCallRequest`](#publiccallrequest); [`MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL`](../constants.md#circuit-constants)] | Requests to call public functions. | +| `private_call_requests` | [[`PrivateCallRequest`](#privatecallrequest); [`MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL`](../constants.md#circuit-constants)] | Requests to call Private functions. | +| `counter_start` | `u32` | Counter at which the function call was initiated. | +| `counter_end` | `u32` | Counter at which the function call ended. | +| `min_revertible_side_effect_counter` | `u32` | Counter below which the side effects are non-revertible. | +| `block_header` | [`BlockHeader`](#blockheader) | Information about the trees used for the transaction. | +| `chain_id` | `field` | Chain ID of the transaction. | +| `version` | `field` | Version of the transaction. | After generating a proof for a private function circuit, that proof (and associated public inputs) will be passed-into a private kernel circuit as private inputs. Private kernel circuits use the private function's proof, public inputs, and verification key, to verify the correct execution of the private function. Private kernel circuits then perform a number of checks and computations on the private function's public inputs. @@ -67,13 +67,12 @@ After generating a proof for a private function circuit, that proof (and associa ### `CallContext` -| Field | Type | Description | -| -------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `msg_sender` | `AztecAddress` | Address of the caller contract. | -| `storage_contract_address` | `AztecAddress` | Address of the contract against which all state changes will be stored. (It is not called `contract_address`, because in the context of delegate calls, that would be an ambiguous name.) | -| `portal_contract_address` | `AztecAddress` | Address of the portal contract to the storage contract. | -| `is_delegate_call` | `bool` | A flag indicating whether the call is a [delegate call](../calls/delegate-calls.md). | -| `is_static_call` | `bool` | A flag indicating whether the call is a [static call](../calls/static-calls.md). | +| Field | Type | Description | +| ------------------------- | -------------- | -------------------------------------------------------------------------------- | +| `msg_sender` | `AztecAddress` | Address of the caller contract. | +| `contract_address` | `AztecAddress` | Address of the contract against which all state changes will be stored. | +| `portal_contract_address` | `AztecAddress` | Address of the portal contract to the storage contract. | +| `is_static_call` | `bool` | A flag indicating whether the call is a [static call](../calls/static-calls.md). | ### `GasSettings` diff --git a/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md b/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md index 936559390ec..4701fd06fa5 100644 --- a/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md +++ b/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md @@ -134,7 +134,7 @@ It is effectively set in private by the contract that calls `context.set_as_fee_ This manifests as a boolean flag `is_fee_payer` in the `PrivateCircuitPublicInputs`. The private kernel circuits will check this flag for every call stack item. -When a call stack item is found with `is_fee_payer` set, the kernel circuit will set `fee_payer` in its `PrivateKernelCircuitPublicInputs` to be the `callContext.storageContractAddress`. +When a call stack item is found with `is_fee_payer` set, the kernel circuit will set `fee_payer` in its `PrivateKernelCircuitPublicInputs` to be the `callContext.contractAddress`. This is subsequently passed through the `PublicKernelCircuitPublicInputs` to the `KernelCircuitPublicInputs`. diff --git a/docs/docs/protocol-specs/public-vm/_nested-context.md b/docs/docs/protocol-specs/public-vm/_nested-context.md index c6fbd1824ab..ca3193d61bf 100644 --- a/docs/docs/protocol-specs/public-vm/_nested-context.md +++ b/docs/docs/protocol-specs/public-vm/_nested-context.md @@ -6,24 +6,21 @@ The following shorthand syntax is used to refer to nested context derivation in // instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } isStaticCall = instr.opcode == STATICCALL -isDelegateCall = instr.opcode == DELEGATECALL -nestedContext = deriveContext(context, instr.args, isStaticCall, isDelegateCall) +nestedContext = deriveContext(context, instr.args, isStaticCall) ``` Nested context derivation is defined as follows: ```jsx nestedExecutionEnvironment = ExecutionEnvironment { address: M[addrOffset], - storageAddress: isDelegateCall ? context.storageAddress : M[addrOffset], - sender: isDelegateCall ? context.sender : context.address, + sender: context.address, functionSelector: context.environment.functionSelector, transactionFee: context.environment.transactionFee, contractCallDepth: context.contractCallDepth + 1, contractCallPointer: context.worldStateAccessTrace.contractCalls.length + 1, globals: context.globals, isStaticCall: isStaticCall, - isDelegateCall: isDelegateCall, calldata: context.memory[M[argsOffset]:M[argsOffset]+argsSize], } diff --git a/docs/docs/protocol-specs/public-vm/avm-circuit.md b/docs/docs/protocol-specs/public-vm/avm-circuit.md index 146557a1af3..3b8cd10f4bd 100644 --- a/docs/docs/protocol-specs/public-vm/avm-circuit.md +++ b/docs/docs/protocol-specs/public-vm/avm-circuit.md @@ -1,10 +1,13 @@ # AVM Circuit + The AVM circuit's purpose is to prove execution of a sequence of instructions for a public execution request. Regardless of whether execution succeeds or reverts, the circuit always generates a valid proof of execution. ## Introduction ### Circuit Architecture Outline + The circuit is comprised of the following components: + - **Bytecode Table**: includes bytecode for all calls, indexed by call pointer and program counter. - **Instruction Controller**: fetches an instruction from the Bytecode Table. Decodes the instructions into sub-operations to be forwarded to other modules. - **Intermediate Registers**: for staging sub-operation inputs and outputs. @@ -17,29 +20,35 @@ The circuit is comprised of the following components: - **Circuit I/O**: data structures used to ingest circuit inputs and emit outputs. ## Bytecode Table + To review, the AVM circuit's primary purpose is to prove execution of the proper sequence of instructions given a contract call's bytecode and inputs. The circuit will prove correct execution of any nested contract calls as well. Each nested call will have its own bytecode and inputs, but will be processed within the same circuit. Prior to the VM circuit's execution, a vector is assembled to contain the bytecode for all of a request's contract calls (initial and nested). If a request's execution contains contract calls to contracts A, B, C, and D (in that order), the VM circuit's bytecode vector will contain A's bytecode, followed by B's, C's, and finally D's. Each one will be zero-padded to some constant length `MAX_PUBLIC_INSTRUCTIONS_PER_CONTRACT`. Each entry in the bytecode vector will be paired with a call pointer and program counter. This **Bytecode Table** maps a call pointer and program counter to an instruction, and is used by the Instruction Controller to fetch instructions. + > Note: "call pointer" is expanded on in a later section. Each contract's public bytecode is committed to during contract deployment. As part of the AVM circuit verification algorithm, the bytecode vector (as a concatenation of all relevant contract bytecodes) is verified against the corresponding bytecode commitments. This is expanded on in ["Bytecode Validation Circuit"](./bytecode-validation-circuit). While the AVM circuit enforces that the correct instructions are executed according to its bytecode table, the verifier checks that bytecode table against the previously validated bytecode commitments. ## Instruction Controller + The Instruction Controller's responsibilities include instruction fetching and decoding. ### Instruction fetching + The Instruction Controller's **instruction fetch** mechanism makes use of the bytecode table to determine which instruction to execute based on the call pointer and program counter. Each instruction fetch corresponds to a circuit lookup to enforce that the correct instruction is processed for a given contract and program counter. The combination of the instruction fetch circuitry, the bytecode table, and the ["Bytecode Validation Circuit"](./bytecode-validation-circuit) ensure that VM circuit processes the proper sequence of instructions. ### Instruction decoding and sub-operations + An instruction (its opcode, flags, and arguments) represents some high-level VM operation. For example, an `ADD` instruction says "add two items from memory and store the result in memory". The Instruction Controller **instruction decode** mechanism decodes instructions into sub-operations. While an instruction likely requires many circuit components, a **sub-operation** is a smaller task that can be fed to just one VM circuit component for processing. By decoding an instruction into sub-operations, the VM circuit translates high-level instructions into smaller achievable tasks. To continue with the `ADD` example, it would translate "add two items from memory and store the result in memory" to "load an item from memory, load another item from memory, add them, and store the result to memory." A **pre-computed/hardcoded sub-operations table** maps instruction opcodes to sub-operations. This provides the Instruction Controller with everything it needs to decode an instruction. The Instruction Controller forwards sub-operations according to the following categorizations: + - Control flow sub-operations are forwarded to the Control Flow Unit - Gas tracking sub-operations are forwarded to the Gas Controller - Memory sub-operations are forwarded to the Memory Controller @@ -52,9 +61,11 @@ The Instruction Controller forwards sub-operations according to the following ca > Note: for simple instructions (like `ADD`), the instruction can be fetched and all sub-operations can be processed in a single clock cycle. Since the VM circuit has limited resources, some complex instructions (like `CALLDATACOPY`) involve too many sub-operations to be processed in one clock cycle. A "clock cycle" in the AVM circuit represents the smallest subdivision of time during which some parallel operations can be performed. A clock cycle corresponds to a row in the circuit's **operations trace**. Simple instructions correspond to only a single row in this trace, but complex instructions span multiple rows. A `CLK` column tracks the clock cycle for each row and its set of sub-operations. #### Decoding example + The `ADD` instruction is decoded into two `LOAD` memory sub-operations, an `ADD` ALU (chiplet) sub-operation, and a `STORE` memory sub-operation. Take the following `ADD` instruction as an example: `ADD aOffset bOffset dstOffset`. Assuming this instruction is executed as part of contract call with pointer `C`, it is decoded into the following sub-operations: + ``` // Load word from call's memory into register Ia (index 0) LOAD 0 aOffset // Ia = M[aOffset] @@ -70,6 +81,7 @@ STORE 2 dstOffset > Note: the `ADD` instruction is an example of a "simple" instruction that can be fully processed in a single clock cycle. All four of the above-listed sub-operations happen in one clock cycle and therefore take up only a single row in the circuit's operations trace. ## Intermediate Registers + User code (AVM bytecode) has no concept of "registers", and so instructions often operate directly on user memory. Sub-operations on the other hand operate on intermediate registers. The only circuit component that has direct access to memory is the Memory Controller (further explained later), and therefore only memory sub-operations access memory. All other sub-operations operate on **intermediate registers** which serve as a staging ground between memory and the various processing components of the VM circuit. Three intermediate registers exist: $I_a$, $I_b$, and $I_c$. @@ -77,12 +89,15 @@ Three intermediate registers exist: $I_a$, $I_b$, and $I_c$. > Refer to ["AVM State Model"](./memory-model) for more details on the absence of "external registers" in the AVM. ## Control Flow Unit + Processes updates to the program counter and call pointer to ensure that execution proceeds properly from one instruction to the next. ### Program Counter + The Control Flow Unit's **program counter** is an index into the bytecode of the current call's contract. For most instructions, the Control Flow Unit will simply increment the program counter. Certain instructions (like `JUMP`) decode into control flow sub-operations (like `PCSTORE`). The Control Flow Unit processes such instructions to update the program counter. ### Call Pointer + A **contract call pointer** uniquely identifies a contract call among all contract calls processed by the current circuit. The Control Flow Unit tracks the currently active call pointer and the next available one. When a nested contract call is encountered, it assigns it the next available call pointer (`callPointer = nextCallPointer++`) and increments that next pointer value. It then sets the program counter to 0. A request's initial contract call is assigned call pointer of `1`. The first nested contract call encountered during execution is assigned call pointer of `2`. The Control Flow Unit assigns call pointers based on execution order. @@ -90,23 +105,33 @@ A request's initial contract call is assigned call pointer of `1`. The first nes There is certain information that must be tracked by the VM circuit on a per-call basis. For example, each call will correspond to the execution of a different contract's bytecode, and each call will access call-specific memory. As a per-call unique identifier, the contract call pointer enables bytecode and memory lookups, among other things, on a per-call basis. #### "Input" and "output" call pointers + It is important to note that the initial contract call's pointer is `1`, not `0`. The zero call pointer is a special case known as the "input" call pointer. As expanded on later, the VM circuit memory table has a separate section for each call pointer. The memory table section for the **input call pointer** is reserved for the initial call's `calldata`. This will be expanded on later. ### Internal Call Stack + **TODO** + ### Nested contract calls + **TODO** + #### Initializing nested call context + **TODO** + #### Snapshotting and restoring context + **TODO** ## Memory Controller + The VM circuit's **Memory Controller** processes loads and stores between intermediate registers and memory. ### Memory Sub-operations + When decoded, instructions that operate on memory map to some Memory Controller sub-operations. A memory read maps to a `LOAD` sub-operation which loads a word from memory into an intermediate register. The memory offset for this sub-operation is generally specified by an instruction argument. Similarly, a memory write maps to a `STORE` sub-operation which stores a word from an intermediate register to memory. ### User Memory @@ -138,14 +163,19 @@ The tag consistency check can be performed within every row (order of rows does Note that `CLK` also plays the role of a foreign key to point to the corresponding sub-operation. This is crucial to enforce consistency of copied values between the sub-operations and memory table. ### Calldata + **TODO** + #### Initial call's calldata + Any lookup into calldata from a request's initial contract call must retrieve a value matching the `calldata` public inputs column. To enforce this, an equivalence check is applied between the `calldata` column and the memory trace for user memory accesses that use "input call pointer". ## Storage Controller + **TODO** ## Side-effect Accumulator + **TODO** ## Chiplets @@ -169,10 +199,13 @@ The planned chiplets for the AVM are: - **Gadgets:** Relevant cryptographic operations or other computationally intensive operations. There will likely be multiple chiplets of this category, including `Poseidon2Permutation`, `Keccakf1600`, and `ECADD`. ## Circuit I/O + ### How do "Public Inputs" work in the AVM circuit? + ZK circuit proof systems generally define some mechanism for "public inputs" for which witness values must be communicated in full to a verifier. The AVM proof system defines its own mechanism for public inputs in which it flags certain trace columns as "public input columns". Any public input columns must be communicated in full to a verifier. ### AVM public inputs structure + The VM circuit's I/O (`AvmPublicInputs`) is defined below: ``` @@ -182,11 +215,9 @@ AvmSessionInputs { feePerDaGas: field, globals: PublicGlobalVariables, address: AztecAddress, - storageAddress: AztecAddress, sender: AztecAddress, contractCallDepth: field, isStaticCall: boolean, - isDelegateCall: boolean, transactionFee: field, // Initializes Machine State l2GasLeft: field, @@ -209,12 +240,14 @@ AvmSessionPublicInputs { > The `WorldStateAccessTrace` and `AccruedSubstate` types are defined in ["State"](./state). Their vectors are assigned constant/maximum lengths when used as circuit inputs. ### AVM public input columns + The `AvmPublicInputs` structure is represented in the VM trace via the following public input columns: + 1. `sessionInputs` has a dedicated column and is used to initialize the initial call's `AvmContext.ExecutionEnvironment` and `AvmContext.MachineState`. 1. `calldata` occupies its own public input column as it is handled differently from the rest of the `ExecutionEnvironment`. It is used to initialize the initial call's `AvmContext.ExecutionEnvironment.calldata`. - - Equivalence is enforced between this `calldata` column and the "input call pointer"'s memory. Through this mechanism, the initial call's `calldata` is placed in a region memory that can be referenced via the `CALLDATACOPY` instruction from within the initial call. + - Equivalence is enforced between this `calldata` column and the "input call pointer"'s memory. Through this mechanism, the initial call's `calldata` is placed in a region memory that can be referenced via the `CALLDATACOPY` instruction from within the initial call. 1. `worldStateAccessTrace` is a trace of all world state accesses. Each of its component vectors has a dedicated set of public input columns (a sub-table). An instruction that reads or writes world state must match a trace entry. The [trace type definition in the "State" section] lists, for each trace vector, the instruction that populate its entries. 1. `accruedSubstate` contains the final `AccruedSubstate`. - - This includes the accrued substate of all _unreverted_ sub-contexts. - - Reverted substate is not present in the Circuit I/O as it does not require further validation/processing by downstream circuits. + - This includes the accrued substate of all _unreverted_ sub-contexts. + - Reverted substate is not present in the Circuit I/O as it does not require further validation/processing by downstream circuits. 1. `sessionResults` has a dedicated column and represents the core "results" of the AVM session processed by this circuit (remaining gas, reverted). diff --git a/docs/docs/protocol-specs/public-vm/context.mdx b/docs/docs/protocol-specs/public-vm/context.mdx index 6bb784ef606..776d27337b2 100644 --- a/docs/docs/protocol-specs/public-vm/context.mdx +++ b/docs/docs/protocol-specs/public-vm/context.mdx @@ -26,7 +26,6 @@ A context's **execution environment** remains constant throughout a contract cal | Field | Type | Description | | ------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | address | `AztecAddress` | | -| storageAddress | `AztecAddress` | | | sender | `AztecAddress` | | | functionSelector | `u32` | | | transactionFee | `field` | Computed transaction fee based on gas fees, inclusion fee, and gas usage. Zero in all phases but teardown. | @@ -34,7 +33,6 @@ A context's **execution environment** remains constant throughout a contract cal | contractCallPointer | `field` | Uniquely identifies each contract call processed by an AVM session. An initial call is assigned pointer value of 1 (expanded on in the AVM circuit section's ["Call Pointer"](./avm-circuit#call-pointer) subsection). | | globals | `PublicGlobalVariables` | | | isStaticCall | `boolean` | | -| isDelegateCall | `boolean` | | | calldata | `[field; ]` | | ## Contract Call Results @@ -72,14 +70,12 @@ Given a [`PublicCallRequest`](../transactions/tx-object#public-call-request) and ``` INITIAL_EXECUTION_ENVIRONMENT = ExecutionEnvironment { address: PublicCallRequest.contractAddress, - storageAddress: PublicCallRequest.CallContext.storageContractAddress, sender: PublicCallRequest.CallContext.msgSender, functionelector: PublicCallRequest.functionSelector, contractCallDepth: 0, contractCallPointer: 1, globals: isStaticCall: PublicCallRequest.CallContext.isStaticCall, - isDelegateCall: PublicCallRequest.CallContext.isDelegateCall, calldata: PublicCallRequest.args, } @@ -97,7 +93,6 @@ INITIAL_WORLD_STATE_ACCESS_TRACE = WorldStateAccessTrace { TracedContractCall { callPointer: nestedContext.environment.callPointer, address: nestedContext.address, - storageAddress: nestedContext.storageAddress, counter: 0, endLifetime: 0, // The call's end-lifetime will be updated later if it or its caller reverts } diff --git a/docs/docs/protocol-specs/public-vm/execution.md b/docs/docs/protocol-specs/public-vm/execution.md index 06d0d87e5e4..4c4c9114c9a 100644 --- a/docs/docs/protocol-specs/public-vm/execution.md +++ b/docs/docs/protocol-specs/public-vm/execution.md @@ -1,61 +1,61 @@ # Execution, Gas, Halting - Execution of an AVM program, within a provided [execution context](./context), includes the following steps: 1. Fetch contract bytecode and decode into a vector of [AVM instructions](./instruction-set) 1. Repeat the next step until a [halt](#halting) is reached 1. Execute the instruction at the index specified by the context's [program counter](#program-counter-and-control-flow) - - Instruction execution will update the program counter + - Instruction execution will update the program counter The following shorthand syntax is used to refer to this execution routine in the ["Instruction Set"](./instruction-set), ["Nested execution"](./nested-calls#nested-execution), and other sections: ```jsx -execute(context) +execute(context); ``` ## Bytecode fetch and decode Before execution begins, a contract's bytecode is retrieved. + ```jsx -bytecode = context.worldState.contracts[context.environment.address].bytecode +bytecode = context.worldState.contracts[context.environment.address].bytecode; ``` > As described in ["Contract Deployment"](../contract-deployment), contracts are not stored in a dedicated tree. A [contract class](../contract-deployment/classes) is [represented](../contract-deployment/classes#registration) as an unencrypted log containing the `ContractClass` structure (which contains the bytecode) and a nullifier representing the class identifier. A [contract instance](../contract-deployment/instances) is [represented](../contract-deployment/classes#registration) as an unencrypted log containing the `ContractInstance` structure and a nullifier representing the contract address. > Thus, the syntax used above for bytecode retrieval is shorthand for: ->1. Perform a membership check of the contract instance address nullifier ->1. Retrieve the `ContractInstance` from a database that tracks all such unencrypted logs -> ```jsx -> contractInstance = contractInstances[context.environment.address] -> ``` ->1. Perform a membership check of the contract class identifier nullifier ->1. Retrieve the `ContractClass` and its bytecode from a database that tracks all such unencrypted logs -> ```jsx -> contractClass = contractClasses[contractInstance.contract_class_id] -> bytecode = contractClass.packed_public_bytecode -> ``` +> +> 1. Perform a membership check of the contract instance address nullifier +> 1. Retrieve the `ContractInstance` from a database that tracks all such unencrypted logs +> ```jsx +> contractInstance = contractInstances[context.environment.address]; +> ``` +> 1. Perform a membership check of the contract class identifier nullifier +> 1. Retrieve the `ContractClass` and its bytecode from a database that tracks all such unencrypted logs +> ```jsx +> contractClass = contractClasses[contractInstance.contract_class_id]; +> bytecode = contractClass.packed_public_bytecode; +> ``` The bytecode is then decoded into a vector of `instructions`. An instruction is referenced throughout this document according to the following interface: -| Member | Description | -| --- | --- | -| `opcode` | The 8-bit opcode value that identifies the operation an instruction is meant to perform. | +| Member | Description | +| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `opcode` | The 8-bit opcode value that identifies the operation an instruction is meant to perform. | | `indirect` | Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. | -| `inTag` | The [tag/size](./memory-model.md#tags-and-tagged-memory) to check inputs against and/or tag the destination with. | -| `args` | Named arguments as specified for an instruction in the ["Instruction Set"](./instruction-set). As an example, `instr.args.aOffset` refers to an instructions argument named `aOffset`. | -| `execute` | Apply this instruction's transition function to an execution context (_e.g._ `instr.execute(context)`). | - +| `inTag` | The [tag/size](./memory-model.md#tags-and-tagged-memory) to check inputs against and/or tag the destination with. | +| `args` | Named arguments as specified for an instruction in the ["Instruction Set"](./instruction-set). As an example, `instr.args.aOffset` refers to an instructions argument named `aOffset`. | +| `execute` | Apply this instruction's transition function to an execution context (_e.g._ `instr.execute(context)`). | ## Instruction execution Once bytecode has been fetched and decoded into the `instructions` vector, instruction execution begins. The AVM executes the instruction at the index specified by the context's program counter. + ```jsx -while (!halted) - instr = instructions[machineState.pc] - instr.execute(context) +while (!halted) instr = instructions[machineState.pc]; +instr.execute(context); ``` An instruction's execution mutates the context's state as specified in the ["Instruction Set"](./instruction-set). @@ -73,17 +73,19 @@ The `INTERNALCALL` instruction pushes `machineState.pc+1` to `machineState.inter > An instruction will never assign program counter a value from memory (`machineState.memory`). A `JUMP`, `JUMPI`, or `INTERNALCALL` instruction's destination is a constant from the program bytecode. This property allows for easier static program analysis. ## Gas checks and tracking + > See ["Gas and Fees"](../gas-and-fees) for a deeper dive into Aztec's gas model and for definitions of each type of gas. Each instruction has an associated `l2GasCost` and `daGasCost`. The AVM uses these values to enforce that sufficient gas is available before executing an instruction, and to deduct the cost from the context's remaining gas. The process of checking and charging gas is referred to in other sections using the following shorthand: ```jsx -chargeGas(context, l2GasCost, daGasCost) +chargeGas(context, l2GasCost, daGasCost); ``` ### Checking gas Before an instruction is executed, the VM enforces that there is sufficient gas remaining via the following assertions: + ``` assert machineState.l2GasLeft - instr.l2GasCost >= 0 assert machineState.daGasLeft - instr.daGasCost >= 0 @@ -118,11 +120,11 @@ An instruction's gas cost is meant to reflect the computational cost of generati - In addition to the base cost, the cost of an instruction increases with the number of reads and writes to memory. This is affected by the total number of input and outputs: the gas cost for [`AND`](./instruction-set/#isa-section-and) should be greater than that of [`NOT`](./instruction-set/#isa-section-not) since it takes one more input. - Input parameters flagged as "indirect" require an extra memory access, so these should further increase the gas cost of the instruction. - The base cost for instructions that operate on a data range of a specified "size" scale in cost with that size, but only if they perform an operation on the data other than copying. For example, [`CALLDATACOPY`](./instruction-set/#isa-section-calldatacopy) copies `copySize` words from `environment.calldata` to `machineState.memory`, so its increased cost is captured by the extra memory accesses. On the other hand, [`SSTORE`](./instruction-set#isa-section-sstore) requires accesses to persistent storage proportional to `srcSize`, so its base cost should also increase. -- The [`CALL`](./instruction-set#isa-section-call)/[`STATICCALL`](./instruction-set#isa-section-staticcall)/[`DELEGATECALL`](./instruction-set#isa-section-delegatecall) instruction's gas cost is determined by its `*Gas` arguments, but any gas unused by the nested contract call's execution is refunded after its completion ([more on this later](./nested-calls#updating-the-calling-context-after-nested-call-halts)). +- The [`CALL`](./instruction-set#isa-section-call)/[`STATICCALL`](./instruction-set#isa-section-staticcall) instruction's gas cost is determined by its `*Gas` arguments, but any gas unused by the nested contract call's execution is refunded after its completion ([more on this later](./nested-calls#updating-the-calling-context-after-nested-call-halts)). > An instruction's gas cost will roughly align with the number of rows it corresponds to in the SNARK execution trace including rows in the sub-operation table, memory table, chiplet tables, etc. -> An instruction's gas cost takes into account the costs of associated downstream computations. An instruction that triggers accesses to the public data tree (`SLOAD`/`SSTORE`) incurs a cost that accounts for state access validation in later circuits (public kernel or rollup). A contract call instruction (`CALL`/`STATICCALL`/`DELEGATECALL`) incurs a cost accounting for the nested call's complete execution as well as any work required by the public kernel circuit for this additional call. +> An instruction's gas cost takes into account the costs of associated downstream computations. An instruction that triggers accesses to the public data tree (`SLOAD`/`SSTORE`) incurs a cost that accounts for state access validation in later circuits (public kernel or rollup). A contract call instruction (`CALL`/`STATICCALL`) incurs a cost accounting for the nested call's complete execution as well as any work required by the public kernel circuit for this additional call. ## Halting @@ -159,94 +161,98 @@ results.reverted = true The AVM's exceptional halting conditions area listed below: 1. **Insufficient gas** - ``` - assert machineState.l2GasLeft - instr.l2GasCost >= 0 - assert machineState.daGasLeft - instr.l2GasCost >= 0 - ``` + ``` + assert machineState.l2GasLeft - instr.l2GasCost >= 0 + assert machineState.daGasLeft - instr.l2GasCost >= 0 + ``` 1. **Invalid instruction encountered** - ``` - assert instructions[machineState.pc].opcode <= MAX_AVM_OPCODE - ``` + ``` + assert instructions[machineState.pc].opcode <= MAX_AVM_OPCODE + ``` 1. **Jump destination past end of program** - ``` - assert instructions[machineState.pc].opcode not in {JUMP, JUMPI, INTERNALCALL} - OR instr.args.loc < instructions.length - ``` + ``` + assert instructions[machineState.pc].opcode not in {JUMP, JUMPI, INTERNALCALL} + OR instr.args.loc < instructions.length + ``` 1. **Failed memory tag check** - - Defined per-instruction in the [Instruction Set](./instruction-set) + - Defined per-instruction in the [Instruction Set](./instruction-set) 1. **Out of bounds memory access (max memory offset is $2^{32}-1$)** - ``` - for offset in instr.args.*Offset: - assert offset < 2^32 - ``` + ``` + for offset in instr.args.*Offset: + assert offset < 2^32 + ``` 1. **World state modification attempt during a static call** - ``` - assert !environment.isStaticCall - OR instructions[machineState.pc].opcode not in WS_AS_MODIFYING_OPS - ``` - > Definition: `WS_AS_MODIFYING_OPS` represents the list of all opcodes corresponding to instructions that modify world state or accrued substate. + ``` + assert !environment.isStaticCall + OR instructions[machineState.pc].opcode not in WS_AS_MODIFYING_OPS + ``` + > Definition: `WS_AS_MODIFYING_OPS` represents the list of all opcodes corresponding to instructions that modify world state or accrued substate. 1. **Maximum contract call depth (1024) exceeded** - ``` - assert environment.contractCallDepth <= 1024 - assert instructions[machineState.pc].opcode not in {CALL, STATICCALL, DELEGATECALL} - OR environment.contractCallDepth < 1024 - ``` + ``` + assert environment.contractCallDepth <= 1024 + assert instructions[machineState.pc].opcode not in {CALL, STATICCALL} + OR environment.contractCallDepth < 1024 + ``` 1. **Maximum contract call calls per execution request (1024) exceeded** - ``` - assert worldStateAccessTrace.contractCalls.length <= 1024 - assert instructions[machineState.pc].opcode not in {CALL, STATICCALL, DELEGATECALL} - OR worldStateAccessTrace.contractCalls.length < 1024 - ``` + ``` + assert worldStateAccessTrace.contractCalls.length <= 1024 + assert instructions[machineState.pc].opcode not in {CALL, STATICCALL} + OR worldStateAccessTrace.contractCalls.length < 1024 + ``` 1. **Maximum internal call depth (1024) exceeded** - ``` - assert machineState.internalCallStack.length <= 1024 - assert instructions[machineState.pc].opcode != INTERNALCALL - OR environment.contractCallDepth < 1024 - ``` + ``` + assert machineState.internalCallStack.length <= 1024 + assert instructions[machineState.pc].opcode != INTERNALCALL + OR environment.contractCallDepth < 1024 + ``` 1. **Maximum world state accesses (1024-per-category) exceeded** - ``` - assert worldStateAccessTrace.publicStorageReads.length <= 1024 - AND worldStateAccessTrace.publicStorageWrites.length <= 1024 - AND worldStateAccessTrace.noteHashChecks.length <= 1024 - AND worldStateAccessTrace.noteHashes.length <= 1024 - AND worldStateAccessTrace.nullifierChecks.length <= 1024 - AND worldStateAccessTrace.nullifiers.length <= 1024 - AND worldStateAccessTrace.l1ToL2MessageChecks.length <= 1024 - AND worldStateAccessTrace.archiveChecks.length <= 1024 - - // Storage - assert instructions[machineState.pc].opcode != SLOAD - OR worldStateAccessTrace.publicStorageReads.length < 1024 - assert instructions[machineState.pc].opcode != SSTORE - OR worldStateAccessTrace.publicStorageWrites.length < 1024 - - // Note hashes - assert instructions[machineState.pc].opcode != NOTEHASHEXISTS - OR noteHashChecks.length < 1024 - assert instructions[machineState.pc].opcode != EMITNOTEHASH - OR noteHashes.length < 1024 - - // Nullifiers - assert instructions[machineState.pc].opcode != NULLIFIEREXISTS - OR nullifierChecks.length < 1024 - assert instructions[machineState.pc].opcode != EMITNULLIFIER - OR nullifiers.length < 1024 - - // Read L1 to L2 messages - assert instructions[machineState.pc].opcode != L1TOL2MSGEXISTS - OR worldStateAccessTrace.l1ToL2MessagesChecks.length < 1024 - ``` + + ``` + assert worldStateAccessTrace.publicStorageReads.length <= 1024 + AND worldStateAccessTrace.publicStorageWrites.length <= 1024 + AND worldStateAccessTrace.noteHashChecks.length <= 1024 + AND worldStateAccessTrace.noteHashes.length <= 1024 + AND worldStateAccessTrace.nullifierChecks.length <= 1024 + AND worldStateAccessTrace.nullifiers.length <= 1024 + AND worldStateAccessTrace.l1ToL2MessageChecks.length <= 1024 + AND worldStateAccessTrace.archiveChecks.length <= 1024 + + // Storage + assert instructions[machineState.pc].opcode != SLOAD + OR worldStateAccessTrace.publicStorageReads.length < 1024 + assert instructions[machineState.pc].opcode != SSTORE + OR worldStateAccessTrace.publicStorageWrites.length < 1024 + + // Note hashes + assert instructions[machineState.pc].opcode != NOTEHASHEXISTS + OR noteHashChecks.length < 1024 + assert instructions[machineState.pc].opcode != EMITNOTEHASH + OR noteHashes.length < 1024 + + // Nullifiers + assert instructions[machineState.pc].opcode != NULLIFIEREXISTS + OR nullifierChecks.length < 1024 + assert instructions[machineState.pc].opcode != EMITNULLIFIER + OR nullifiers.length < 1024 + + // Read L1 to L2 messages + assert instructions[machineState.pc].opcode != L1TOL2MSGEXISTS + OR worldStateAccessTrace.l1ToL2MessagesChecks.length < 1024 + ``` + 1. **Maximum accrued substate entries (per-category) exceeded** - ``` - assert accruedSubstate.unencryptedLogs.length <= MAX_UNENCRYPTED_LOGS - AND accruedSubstate.sentL2ToL1Messages.length <= MAX_SENT_L2_TO_L1_MESSAGES - - // Unencrypted logs - assert instructions[machineState.pc].opcode != EMITUNENCRYPTEDLOG - OR unencryptedLogs.length < MAX_UNENCRYPTED_LOGS - - // Sent L2 to L1 messages - assert instructions[machineState.pc].opcode != SENDL2TOL1MSG - OR sentL2ToL1Messages.length < MAX_SENT_L2_TO_L1_MESSAGES - ``` - > Note that ideally the AVM should limit the _total_ accrued substate entries per-category instead of the entries per-call. + + ``` + assert accruedSubstate.unencryptedLogs.length <= MAX_UNENCRYPTED_LOGS + AND accruedSubstate.sentL2ToL1Messages.length <= MAX_SENT_L2_TO_L1_MESSAGES + + // Unencrypted logs + assert instructions[machineState.pc].opcode != EMITUNENCRYPTEDLOG + OR unencryptedLogs.length < MAX_UNENCRYPTED_LOGS + + // Sent L2 to L1 messages + assert instructions[machineState.pc].opcode != SENDL2TOL1MSG + OR sentL2ToL1Messages.length < MAX_SENT_L2_TO_L1_MESSAGES + ``` + + > Note that ideally the AVM should limit the _total_ accrued substate entries per-category instead of the entries per-call. diff --git a/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx b/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx index eb473ccb742..4d081801c4d 100644 --- a/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx +++ b/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx @@ -143,14 +143,6 @@ Click on an instruction name to jump to its section. 0x10 - \[\`STORAGEADDRESS\`\](#isa-section-storageaddress) - Get the _storage_ address of the currently executing context - { - `M[dstOffset] = context.environment.storageAddress` - } - - - 0x11 \[\`SENDER\`\](#isa-section-sender) Get the address of the sender (caller of the current context) { @@ -158,7 +150,7 @@ Click on an instruction name to jump to its section. } - 0x12 + 0x11 \[\`FUNCTIONSELECTOR\`\](#isa-section-functionselector) Get the function selector of the contract function being executed { @@ -166,7 +158,7 @@ Click on an instruction name to jump to its section. } - 0x13 + 0x12 \[\`TRANSACTIONFEE\`\](#isa-section-transactionfee) Get the computed transaction fee during teardown phase, zero otherwise { @@ -174,7 +166,7 @@ Click on an instruction name to jump to its section. } - 0x14 + 0x13 \[\`CHAINID\`\](#isa-section-chainid) Get this rollup's L1 chain ID { @@ -182,7 +174,7 @@ Click on an instruction name to jump to its section. } - 0x15 + 0x14 \[\`VERSION\`\](#isa-section-version) Get this rollup's L2 version ID { @@ -190,7 +182,7 @@ Click on an instruction name to jump to its section. } - 0x16 + 0x15 \[\`BLOCKNUMBER\`\](#isa-section-blocknumber) Get this L2 block's number { @@ -198,7 +190,7 @@ Click on an instruction name to jump to its section. } - 0x17 + 0x16 \[\`TIMESTAMP\`\](#isa-section-timestamp) Get this L2 block's timestamp { @@ -206,7 +198,7 @@ Click on an instruction name to jump to its section. } - 0x18 + 0x17 \[\`FEEPERL2GAS\`\](#isa-section-feeperl2gas) Get the fee to be paid per "L2 gas" - constant for entire transaction { @@ -214,7 +206,7 @@ Click on an instruction name to jump to its section. } - 0x19 + 0x18 \[\`FEEPERDAGAS\`\](#isa-section-feeperdagas) Get the fee to be paid per "DA gas" - constant for entire transaction { @@ -222,7 +214,7 @@ Click on an instruction name to jump to its section. } - 0x1a + 0x19 \[\`CALLDATACOPY\`\](#isa-section-calldatacopy) Copy calldata into memory { @@ -230,7 +222,7 @@ Click on an instruction name to jump to its section. } - 0x1b + 0x1a \[\`L2GASLEFT\`\](#isa-section-l2gasleft) Remaining "L2 gas" for this call (after this instruction) { @@ -238,7 +230,7 @@ Click on an instruction name to jump to its section. } - 0x1c + 0x1b \[\`DAGASLEFT\`\](#isa-section-dagasleft) Remaining "DA gas" for this call (after this instruction) { @@ -246,7 +238,7 @@ Click on an instruction name to jump to its section. } - 0x1d + 0x1c \[\`JUMP\`\](#isa-section-jump) Jump to a location in the bytecode { @@ -254,7 +246,7 @@ Click on an instruction name to jump to its section. } - 0x1e + 0x1d \[\`JUMPI\`\](#isa-section-jumpi) Conditionally jump to a location in the bytecode { @@ -262,7 +254,7 @@ Click on an instruction name to jump to its section. } - 0x1f + 0x1e \[\`INTERNALCALL\`\](#isa-section-internalcall) Make an internal call. Push the current PC to the internal call stack and jump to the target location. @@ -271,7 +263,7 @@ context.machineState.pc = loc`} - 0x20 + 0x1f \[\`INTERNALRETURN\`\](#isa-section-internalreturn) Return from an internal call. Pop from the internal call stack and jump to the popped location. { @@ -279,7 +271,7 @@ context.machineState.pc = loc`} } - 0x21 + 0x20 \[\`SET\`\](#isa-section-set) Set a memory word from a constant in the bytecode { @@ -287,7 +279,7 @@ context.machineState.pc = loc`} } - 0x22 + 0x21 \[\`MOV\`\](#isa-section-mov) Move a word from source memory location to destination { @@ -295,7 +287,7 @@ context.machineState.pc = loc`} } - 0x23 + 0x22 \[\`CMOV\`\](#isa-section-cmov) Move a word (conditionally chosen) from one memory location to another (`d = cond > 0 ? a : b`) { @@ -303,7 +295,7 @@ context.machineState.pc = loc`} } - 0x24 + 0x23 \[\`SLOAD\`\](#isa-section-sload) Load a word from this contract's persistent public storage. Zero is loaded for unwritten slots. @@ -311,7 +303,7 @@ context.machineState.pc = loc`} - 0x25 + 0x24 \[\`SSTORE\`\](#isa-section-sstore) Write a word to this contract's persistent public storage @@ -319,29 +311,29 @@ context.machineState.pc = loc`} - 0x26 + 0x25 \[\`NOTEHASHEXISTS\`\](#isa-section-notehashexists) Check whether a note hash exists in the note hash tree (as of the start of the current block) {`exists = context.worldState.noteHashes.has({ leafIndex: M[leafIndexOffset] - leaf: hash(context.environment.storageAddress, M[noteHashOffset]), + leaf: hash(context.environment.address, M[noteHashOffset]), }) M[existsOffset] = exists`} - 0x27 + 0x26 \[\`EMITNOTEHASH\`\](#isa-section-emitnotehash) Emit a new note hash to be inserted into the note hash tree {`context.worldState.noteHashes.append( - hash(context.environment.storageAddress, M[noteHashOffset]) + hash(context.environment.address, M[noteHashOffset]) )`} - 0x28 + 0x27 \[\`NULLIFIEREXISTS\`\](#isa-section-nullifierexists) Check whether a nullifier exists in the nullifier tree (including nullifiers from earlier in the current transaction or from earlier in the current block) @@ -352,17 +344,17 @@ M[existsOffset] = exists`} - 0x29 + 0x28 \[\`EMITNULLIFIER\`\](#isa-section-emitnullifier) Emit a new nullifier to be inserted into the nullifier tree {`context.worldState.nullifiers.append( - hash(context.environment.storageAddress, M[nullifierOffset]) + hash(context.environment.address, M[nullifierOffset]) )`} - 0x2a + 0x29 \[\`L1TOL2MSGEXISTS\`\](#isa-section-l1tol2msgexists) Check if a message exists in the L1-to-L2 message tree @@ -373,7 +365,7 @@ M[existsOffset] = exists`} - 0x2b + 0x2a \[\`GETCONTRACTINSTANCE\`\](#isa-section-getcontractinstance) Copies contract instance data to memory @@ -389,7 +381,7 @@ M[existsOffset] = exists`} - 0x2c + 0x2b \[\`EMITUNENCRYPTEDLOG\`\](#isa-section-emitunencryptedlog) Emit an unencrypted log @@ -402,7 +394,7 @@ M[existsOffset] = exists`} - 0x2d + 0x2c \[\`SENDL2TOL1MSG\`\](#isa-section-sendl2tol1msg) Send an L2-to-L1 message @@ -416,7 +408,7 @@ M[existsOffset] = exists`} - 0x2e + 0x2d \[\`CALL\`\](#isa-section-call) Call into another contract @@ -425,13 +417,13 @@ chargeGas(context, l2GasCost=M[instr.args.gasOffset], daGasCost=M[instr.args.gasOffset+1]) traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=false) +nestedContext = deriveContext(context, instr.args, isStaticCall=false) execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext)`} - 0x2f + 0x2e \[\`STATICCALL\`\](#isa-section-staticcall) Call into another contract, disallowing World State and Accrued Substate modifications @@ -440,28 +432,13 @@ chargeGas(context, l2GasCost=M[instr.args.gasOffset], daGasCost=M[instr.args.gasOffset+1]) traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=true, isDelegateCall=false) +nestedContext = deriveContext(context, instr.args, isStaticCall=true execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext)`} - 0x30 - \[\`DELEGATECALL\`\](#isa-section-delegatecall) - (UNIMPLEMENTED) Call into another contract, but keep the caller's `sender` and `storageAddress` - -{`// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } -chargeGas(context, - l2GasCost=M[instr.args.gasOffset], - daGasCost=M[instr.args.gasOffset+1]) -traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=true) -execute(nestedContext) -updateContextAfterNestedCall(context, instr.args, nestedContext)`} - - - - 0x31 + 0x2f \[\`RETURN\`\](#isa-section-return) Halt execution within this context (without revert), optionally returning some data @@ -470,7 +447,7 @@ halt`} - 0x32 + 0x30 \[\`REVERT\`\](#isa-section-revert) Halt execution within this context as `reverted`, optionally returning some data @@ -480,7 +457,7 @@ halt`} - 0x33 + 0x31 \[\`TORADIXLE\`\](#isa-section-to_radix_le) Convert a word to an array of limbs in little-endian radix form TBD: Storage of limbs and if T[dstOffset] is constrained to U8 @@ -822,30 +799,12 @@ Get the address of the currently executing l2 contract [![](/img/protocol-specs/public-vm/bit-formats/ADDRESS.png)](/img/protocol-specs/public-vm/bit-formats/ADDRESS.png) -### `STORAGEADDRESS` -Get the _storage_ address of the currently executing context - -[See in table.](#isa-table-storageaddress) - -- **Opcode**: 0x10 -- **Category**: Execution Environment -- **Flags**: - - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. -- **Args**: - - **dstOffset**: memory offset specifying where to store operation's result -- **Expression**: `M[dstOffset] = context.environment.storageAddress` -- **Details**: The storage address is used for public storage accesses. -- **Tag updates**: `T[dstOffset] = field` -- **Bit-size**: 56 - -[![](/img/protocol-specs/public-vm/bit-formats/STORAGEADDRESS.png)](/img/protocol-specs/public-vm/bit-formats/STORAGEADDRESS.png) - ### `SENDER` Get the address of the sender (caller of the current context) [See in table.](#isa-table-sender) -- **Opcode**: 0x11 +- **Opcode**: 0x10 - **Category**: Execution Environment - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -862,7 +821,7 @@ Get the function selector of the contract function being executed [See in table.](#isa-table-functionselector) -- **Opcode**: 0x12 +- **Opcode**: 0x11 - **Category**: Execution Environment - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -878,7 +837,7 @@ Get the computed transaction fee during teardown phase, zero otherwise [See in table.](#isa-table-transactionfee) -- **Opcode**: 0x13 +- **Opcode**: 0x12 - **Category**: Execution Environment - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -894,7 +853,7 @@ Get this rollup's L1 chain ID [See in table.](#isa-table-chainid) -- **Opcode**: 0x14 +- **Opcode**: 0x13 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -911,7 +870,7 @@ Get this rollup's L2 version ID [See in table.](#isa-table-version) -- **Opcode**: 0x15 +- **Opcode**: 0x14 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -928,7 +887,7 @@ Get this L2 block's number [See in table.](#isa-table-blocknumber) -- **Opcode**: 0x16 +- **Opcode**: 0x15 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -945,7 +904,7 @@ Get this L2 block's timestamp [See in table.](#isa-table-timestamp) -- **Opcode**: 0x17 +- **Opcode**: 0x16 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -962,7 +921,7 @@ Get the fee to be paid per "L2 gas" - constant for entire transaction [See in table.](#isa-table-feeperl2gas) -- **Opcode**: 0x18 +- **Opcode**: 0x17 - **Category**: Execution Environment - Globals - Gas - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -979,7 +938,7 @@ Get the fee to be paid per "DA gas" - constant for entire transaction [See in table.](#isa-table-feeperdagas) -- **Opcode**: 0x19 +- **Opcode**: 0x18 - **Category**: Execution Environment - Globals - Gas - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -996,7 +955,7 @@ Copy calldata into memory [See in table.](#isa-table-calldatacopy) -- **Opcode**: 0x1a +- **Opcode**: 0x19 - **Category**: Execution Environment - Calldata - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1016,7 +975,7 @@ Remaining "L2 gas" for this call (after this instruction) [See in table.](#isa-table-l2gasleft) -- **Opcode**: 0x1b +- **Opcode**: 0x1a - **Category**: Machine State - Gas - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1033,7 +992,7 @@ Remaining "DA gas" for this call (after this instruction) [See in table.](#isa-table-dagasleft) -- **Opcode**: 0x1c +- **Opcode**: 0x1b - **Category**: Machine State - Gas - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1050,7 +1009,7 @@ Jump to a location in the bytecode [See in table.](#isa-table-jump) -- **Opcode**: 0x1d +- **Opcode**: 0x1c - **Category**: Machine State - Control Flow - **Args**: - **loc**: target location to jump to @@ -1065,7 +1024,7 @@ Conditionally jump to a location in the bytecode [See in table.](#isa-table-jumpi) -- **Opcode**: 0x1e +- **Opcode**: 0x1d - **Category**: Machine State - Control Flow - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1083,7 +1042,7 @@ Make an internal call. Push the current PC to the internal call stack and jump t [See in table.](#isa-table-internalcall) -- **Opcode**: 0x1f +- **Opcode**: 0x1e - **Category**: Machine State - Control Flow - **Args**: - **loc**: target location to jump/call to @@ -1095,14 +1054,13 @@ context.machineState.pc = loc`} - **Details**: Target location is an immediate value (a constant in the bytecode). - **Bit-size**: 48 -[![](/img/protocol-specs/public-vm/bit-formats/INTERNALCALL.png)](/img/protocol-specs/public-vm/bit-formats/INTERNALCALL.png) ### `INTERNALRETURN` Return from an internal call. Pop from the internal call stack and jump to the popped location. [See in table.](#isa-table-internalreturn) -- **Opcode**: 0x20 +- **Opcode**: 0x1f - **Category**: Machine State - Control Flow - **Expression**: `context.machineState.pc = context.machineState.internalCallStack.pop()` - **Bit-size**: 16 @@ -1114,7 +1072,7 @@ Set a memory word from a constant in the bytecode [See in table.](#isa-table-set) -- **Opcode**: 0x21 +- **Opcode**: 0x20 - **Category**: Machine State - Memory - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1134,7 +1092,7 @@ Move a word from source memory location to destination [See in table.](#isa-table-mov) -- **Opcode**: 0x22 +- **Opcode**: 0x21 - **Category**: Machine State - Memory - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1152,7 +1110,7 @@ Move a word (conditionally chosen) from one memory location to another (`d \= co [See in table.](#isa-table-cmov) -- **Opcode**: 0x23 +- **Opcode**: 0x22 - **Category**: Machine State - Memory - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1173,7 +1131,7 @@ Load a word from this contract's persistent public storage. Zero is loaded for u [See in table.](#isa-table-sload) -- **Opcode**: 0x24 +- **Opcode**: 0x23 - **Category**: World State - Public Storage - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1187,7 +1145,7 @@ Load a word from this contract's persistent public storage. Zero is loaded for u - **Details**: {`// Expression is shorthand for -leafIndex = hash(context.environment.storageAddress, M[slotOffset]) +leafIndex = hash(context.environment.address, M[slotOffset]) exists = context.worldState.publicStorage.has(leafIndex) // exists == previously-written if exists: value = context.worldState.publicStorage.get(leafIndex: leafIndex) @@ -1218,7 +1176,7 @@ Write a word to this contract's persistent public storage [See in table.](#isa-table-sstore) -- **Opcode**: 0x25 +- **Opcode**: 0x24 - **Category**: World State - Public Storage - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1233,7 +1191,7 @@ Write a word to this contract's persistent public storage {`// Expression is shorthand for context.worldState.publicStorage.set({ - leafIndex: hash(context.environment.storageAddress, M[slotOffset]), + leafIndex: hash(context.environment.address, M[slotOffset]), leaf: M[srcOffset], })`} @@ -1258,7 +1216,7 @@ Check whether a note hash exists in the note hash tree (as of the start of the c [See in table.](#isa-table-notehashexists) -- **Opcode**: 0x26 +- **Opcode**: 0x25 - **Category**: World State - Notes & Nullifiers - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1270,7 +1228,7 @@ Check whether a note hash exists in the note hash tree (as of the start of the c {`exists = context.worldState.noteHashes.has({ leafIndex: M[leafIndexOffset] - leaf: hash(context.environment.storageAddress, M[noteHashOffset]), + leaf: hash(context.environment.address, M[noteHashOffset]), }) M[existsOffset] = exists`} @@ -1296,7 +1254,7 @@ Emit a new note hash to be inserted into the note hash tree [See in table.](#isa-table-emitnotehash) -- **Opcode**: 0x27 +- **Opcode**: 0x26 - **Category**: World State - Notes & Nullifiers - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1305,7 +1263,7 @@ Emit a new note hash to be inserted into the note hash tree - **Expression**: {`context.worldState.noteHashes.append( - hash(context.environment.storageAddress, M[noteHashOffset]) + hash(context.environment.address, M[noteHashOffset]) )`} - **World State access tracing**: @@ -1328,7 +1286,7 @@ Check whether a nullifier exists in the nullifier tree (including nullifiers fro [See in table.](#isa-table-nullifierexists) -- **Opcode**: 0x28 +- **Opcode**: 0x27 - **Category**: World State - Notes & Nullifiers - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1349,7 +1307,7 @@ M[existsOffset] = exists`} TracedNullifierCheck { callPointer: context.environment.callPointer, nullifier: M[nullifierOffset], - storageAddress: M[addressOffset], + address: M[addressOffset], exists: exists, // defined above counter: ++context.worldStateAccessTrace.accessCounter, } @@ -1365,7 +1323,7 @@ Emit a new nullifier to be inserted into the nullifier tree [See in table.](#isa-table-emitnullifier) -- **Opcode**: 0x29 +- **Opcode**: 0x28 - **Category**: World State - Notes & Nullifiers - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1374,7 +1332,7 @@ Emit a new nullifier to be inserted into the nullifier tree - **Expression**: {`context.worldState.nullifiers.append( - hash(context.environment.storageAddress, M[nullifierOffset]) + hash(context.environment.address, M[nullifierOffset]) )`} - **World State access tracing**: @@ -1397,7 +1355,7 @@ Check if a message exists in the L1-to-L2 message tree [See in table.](#isa-table-l1tol2msgexists) -- **Opcode**: 0x2a +- **Opcode**: 0x29 - **Category**: World State - Messaging - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1436,7 +1394,7 @@ Copies contract instance data to memory [See in table.](#isa-table-getcontractinstance) -- **Opcode**: 0x2b +- **Opcode**: 0x2a - **Category**: Other - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1466,7 +1424,7 @@ Emit an unencrypted log [See in table.](#isa-table-emitunencryptedlog) -- **Opcode**: 0x2c +- **Opcode**: 0x2b - **Category**: Accrued Substate - Logging - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1491,7 +1449,7 @@ Send an L2-to-L1 message [See in table.](#isa-table-sendl2tol1msg) -- **Opcode**: 0x2d +- **Opcode**: 0x2c - **Category**: Accrued Substate - Messaging - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1517,7 +1475,7 @@ Call into another contract [See in table.](#isa-table-call) -- **Opcode**: 0x2e +- **Opcode**: 0x2d - **Category**: Control Flow - Contract Calls - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1536,7 +1494,7 @@ chargeGas(context, l2GasCost=M[instr.args.gasOffset], daGasCost=M[instr.args.gasOffset+1]) traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=false) +nestedContext = deriveContext(context, instr.args, isStaticCall=false) execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext)`} @@ -1564,7 +1522,7 @@ Call into another contract, disallowing World State and Accrued Substate modific [See in table.](#isa-table-staticcall) -- **Opcode**: 0x2f +- **Opcode**: 0x2e - **Category**: Control Flow - Contract Calls - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1583,7 +1541,7 @@ chargeGas(context, l2GasCost=M[instr.args.gasOffset], daGasCost=M[instr.args.gasOffset+1]) traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=true, isDelegateCall=false) +nestedContext = deriveContext(context, instr.args, isStaticCall=true execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext)`} @@ -1603,56 +1561,12 @@ T[retOffset:retOffset+retSize] = field`} [![](/img/protocol-specs/public-vm/bit-formats/STATICCALL.png)](/img/protocol-specs/public-vm/bit-formats/STATICCALL.png) -### `DELEGATECALL` -(UNIMPLEMENTED) Call into another contract, but keep the caller's `sender` and `storageAddress` - -[See in table.](#isa-table-delegatecall) - -- **Opcode**: 0x30 -- **Category**: Control Flow - Contract Calls -- **Flags**: - - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. -- **Args**: - - **gasOffset**: offset to two words containing `{l2GasLeft, daGasLeft}`: amount of gas to provide to the callee - - **addrOffset**: address of the contract to call - - **argsOffset**: memory offset to args (will become the callee's calldata) - - **argsSizeOffset**: memory offset for the number of words to pass via callee's calldata - - **retOffset**: destination memory offset specifying where to store the data returned from the callee - - **retSize**: number of words to copy from data returned by callee - - **successOffset**: destination memory offset specifying where to store the call's success (0: failure, 1: success) -- **Expression**: - -{`// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } -chargeGas(context, - l2GasCost=M[instr.args.gasOffset], - daGasCost=M[instr.args.gasOffset+1]) -traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=true) -execute(nestedContext) -updateContextAfterNestedCall(context, instr.args, nestedContext)`} - -- **Details**: Same as `CALL`, but `sender` and `storageAddress` remains - the same in the nested call as they were in the caller. - ["Nested contract calls"](./nested-calls) provides a full explanation of this - instruction along with the shorthand used in the expression above. - The explanation includes details on charging gas for nested calls, - nested context derivation, world state tracing, and updating the parent context - after the nested call halts. -- **Tag checks**: `T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32` -- **Tag updates**: - -{`T[successOffset] = u8 -T[retOffset:retOffset+retSize] = field`} - -- **Bit-size**: 248 - - ### `RETURN` Halt execution within this context (without revert), optionally returning some data [See in table.](#isa-table-return) -- **Opcode**: 0x31 +- **Opcode**: 0x2f - **Category**: Control Flow - Contract Calls - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1674,7 +1588,7 @@ Halt execution within this context as `reverted`, optionally returning some data [See in table.](#isa-table-revert) -- **Opcode**: 0x32 +- **Opcode**: 0x30 - **Category**: Control Flow - Contract Calls - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1697,7 +1611,7 @@ Convert a word to an array of limbs in little-endian radix form [See in table.](#isa-table-to_radix_le) -- **Opcode**: 0x33 +- **Opcode**: 0x31 - **Category**: Conversions - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. diff --git a/docs/docs/protocol-specs/public-vm/instruction-set.mdx b/docs/docs/protocol-specs/public-vm/instruction-set.mdx index 13047ff724d..b6ee8e5d8ba 100644 --- a/docs/docs/protocol-specs/public-vm/instruction-set.mdx +++ b/docs/docs/protocol-specs/public-vm/instruction-set.mdx @@ -7,7 +7,7 @@ This page lists all of the instructions supported by the Aztec Virtual Machine ( The following notes are relevant to the table and sections below: - `M[offset]` notation is shorthand for `context.machineState.memory[offset]` -- `S[slot]` notation is shorthand for an access to the specified slot in the current contract's public storage (`context.worldState.publicStorage`) after the slot has been siloed by the storage address (`hash(context.environment.storageAddress, slot)`) +- `S[slot]` notation is shorthand for an access to the specified slot in the current contract's public storage (`context.worldState.publicStorage`) after the slot has been siloed by the contract address (`hash(context.environment.address, slot)`) - Any instruction whose description does not mention a program counter change simply increments it: `context.machineState.pc++` - All instructions update `context.machineState.*GasLeft` as detailed in ["Gas limits and tracking"](./execution#gas-checks-and-tracking) - Any instruction can lead to an exceptional halt as specified in ["Exceptional halting"](./execution#exceptional-halting) diff --git a/docs/docs/protocol-specs/public-vm/intro.md b/docs/docs/protocol-specs/public-vm/intro.md index a89e45fc1b2..94bf7d5d0da 100644 --- a/docs/docs/protocol-specs/public-vm/intro.md +++ b/docs/docs/protocol-specs/public-vm/intro.md @@ -12,7 +12,7 @@ In order to execute public contract bytecode, the AVM requires some context. An Instruction-by-instruction, the AVM [executes](./execution) the bytecode specified in its context. An **instruction** is a decoded bytecode entry that, when executed, modifies the AVM's execution context (in particular its [state](./state)) according to the instruction's definition in the ["AVM Instruction Set"](./instruction-set). Execution within a context ends when the AVM encounters a [**halt**](./execution#halting). -During execution, additional contract calls may be made. While an [**initial contract call**](./context#initial-contract-calls) initializes a new execution context directly from a public execution request, a [**nested contract call**](./nested-calls) occurs _during_ AVM execution and is triggered by a **contract call instruction** ([`CALL`](./instruction-set#isa-section-call), [`STATICCALL`](./instruction-set#isa-section-staticcall), or [`DELEGATECALL`](./instruction-set#isa-section-delegatecall)). It initializes a new execution context (**nested context**) from the current one (**calling context**) and triggers execution within it. When nested call's execution completes, execution proceeds in the calling context. +During execution, additional contract calls may be made. While an [**initial contract call**](./context#initial-contract-calls) initializes a new execution context directly from a public execution request, a [**nested contract call**](./nested-calls) occurs _during_ AVM execution and is triggered by a **contract call instruction** ([`CALL`](./instruction-set#isa-section-call), or [`STATICCALL`](./instruction-set#isa-section-staticcall)). It initializes a new execution context (**nested context**) from the current one (**calling context**) and triggers execution within it. When nested call's execution completes, execution proceeds in the calling context. A **caller** is a contract call's initiator. The caller of an initial contract call is an Aztec sequencer. The caller of a nested contract call is the AVM itself executing in the calling context. @@ -41,6 +41,5 @@ The entirety of a contract's public code is represented as a single block of byt ::: warning Ultimately, function selectors _may_ be removed as an enshrined protocol mechanism as described above. For now, each public function on a contract has a distinct bytecode that can be selected for execution via a function selector. ::: - > See the [Bytecode Validation Circuit](./bytecode-validation-circuit) to see how a contract's bytecode can be validated and committed to. diff --git a/docs/docs/protocol-specs/public-vm/nested-calls.mdx b/docs/docs/protocol-specs/public-vm/nested-calls.mdx index 182a248fbed..6c8f6c42b3b 100644 --- a/docs/docs/protocol-specs/public-vm/nested-calls.mdx +++ b/docs/docs/protocol-specs/public-vm/nested-calls.mdx @@ -1,6 +1,6 @@ # Nested Contract Calls -A **nested contract call** occurs _during_ AVM execution and is triggered by a **contract call instruction**. The AVM [instruction set](./instruction-set) includes three contract call instructions: [`CALL`](./instruction-set#isa-section-call), [`STATICCALL`](./instruction-set#isa-section-staticcall), and [`DELEGATECALL`](./instruction-set#isa-section-delegatecall). +A **nested contract call** occurs _during_ AVM execution and is triggered by a **contract call instruction**. The AVM [instruction set](./instruction-set) includes three contract call instructions: [`CALL`](./instruction-set#isa-section-call), and [`STATICCALL`](./instruction-set#isa-section-staticcall). A nested contract call performs the following operations: @@ -16,18 +16,12 @@ Or, in pseudocode: // instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } isStaticCall = instr.opcode == STATICCALL; -isDelegateCall = instr.opcode == DELEGATECALL; l2GasCost = min(M[instr.args.gasOffset], context.machineState.l2GasLeft); daGasCost = min(M[instr.args.gasOffset + 1], context.machineState.daGasLeft); chargeGas(context, l2GasCost, daGasCost); traceNestedCall(context, instr.args.addrOffset); -nestedContext = deriveContext( - context, - instr.args, - isStaticCall, - isDelegateCall -); +nestedContext = deriveContext(context, instr.args, isStaticCall); execute(nestedContext); updateContextAfterNestedCall(context, instr.args, nestedContext); ``` @@ -45,7 +39,6 @@ context.worldStateAccessTrace.contractCalls.append( TracedContractCall { callPointer: context.worldStateAccessTrace.contractCalls.length + 1, address: M[addrOffset], - storageAddress: M[addrOffset], counter: ++context.worldStateAccessTrace.accessCounter, endLifetime: 0, // The call's end-lifetime will be updated later if it or its caller reverts } diff --git a/docs/docs/protocol-specs/public-vm/state.md b/docs/docs/protocol-specs/public-vm/state.md index 5298d7dd264..9cb585bb92f 100644 --- a/docs/docs/protocol-specs/public-vm/state.md +++ b/docs/docs/protocol-specs/public-vm/state.md @@ -8,13 +8,13 @@ This section describes the types of state maintained by the AVM. ### _MachineState_ -| Field | Type | Description | -| --- | --- | --- | -| `l2GasLeft` | `field` | Tracks the amount of L2 gas remaining at any point during execution. Initialized from contract call arguments. | -| `daGasLeft` | `field` | Tracks the amount of DA gas remaining at any point during execution. Initialized from contract call arguments. | -| `pc` | `field` | Index into the contract's bytecode indicating which instruction to execute. Initialized to 0 during context initialization. | -| `internalCallStack` | `Vector` | A stack of program counters pushed to and popped from by `INTERNALCALL` and `INTERNALRETURN` instructions. Initialized as empty during context initialization. | -| `memory` | `[field; 2^32]` | A $2^{32}$ entry memory space accessible by user code (AVM instructions). All $2^{32}$ entries are assigned default value 0 during context initialization. See ["Memory Model"](./memory-model) for a complete description of AVM memory. | +| Field | Type | Description | +| ------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `l2GasLeft` | `field` | Tracks the amount of L2 gas remaining at any point during execution. Initialized from contract call arguments. | +| `daGasLeft` | `field` | Tracks the amount of DA gas remaining at any point during execution. Initialized from contract call arguments. | +| `pc` | `field` | Index into the contract's bytecode indicating which instruction to execute. Initialized to 0 during context initialization. | +| `internalCallStack` | `Vector` | A stack of program counters pushed to and popped from by `INTERNALCALL` and `INTERNALRETURN` instructions. Initialized as empty during context initialization. | +| `memory` | `[field; 2^32]` | A $2^{32}$ entry memory space accessible by user code (AVM instructions). All $2^{32}$ entries are assigned default value 0 during context initialization. See ["Memory Model"](./memory-model) for a complete description of AVM memory. | @@ -24,14 +24,14 @@ This section describes the types of state maintained by the AVM. [Aztec's global state](../state) is implemented as a few merkle trees. These trees are exposed to the AVM as follows: -| State | Tree | Merkle Tree Type | AVM Access | -| --- | --- | --- | --- | +| State | Tree | Merkle Tree Type | AVM Access | +| ----------------- | --------------------- | ---------------- | ------------------------------------------- | | Public Storage | Public Data Tree | Updatable | membership-checks (latest), reads, writes | | Note Hashes | Note Hash Tree | Append-only | membership-checks (start-of-block), appends | | Nullifiers | Nullifier Tree | Indexed | membership-checks (latest), appends | | L1-to-L2 Messages | L1-to-L2 Message Tree | Append-only | membership-checks (start-of-block) | | Headers | Archive Tree | Append-only | membership-checks, leaf-preimage-reads | -| Contracts\* | - | - | - | +| Contracts\* | - | - | - | > \* As described in ["Contract Deployment"](../contract-deployment), contracts are not stored in a dedicated tree. A [contract class](../contract-deployment/classes) is [represented](../contract-deployment/classes#registration) as an unencrypted log containing the `ContractClass` structure (which contains the bytecode) and a nullifier representing the class identifier. A [contract instance](../contract-deployment/instances) is [represented](../contract-deployment/classes#registration) as an unencrypted log containing the `ContractInstance` structure and a nullifier representing the contract address. @@ -45,15 +45,15 @@ As the AVM executes contract code, instructions may read or modify the world sta The following table defines an AVM context's world state interface: -| Field | AVM Instructions & Access | -| --- | --- | -| `contracts` | [`*CALL`](./instruction-set#isa-section-call) (special case, see below\*) | +| Field | AVM Instructions & Access | +| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `contracts` | [`*CALL`](./instruction-set#isa-section-call) (special case, see below\*) | | `publicStorage` | [`SLOAD`](./instruction-set#isa-section-sload) (membership-checks (latest) & reads), [`SSTORE`](./instruction-set#isa-section-sstore) (writes) | | `noteHashes` | [`NOTEHASHEXISTS`](./instruction-set#isa-section-notehashexists) (membership-checks (start-of-block)), [`EMITNOTEHASH`](./instruction-set#isa-section-emitnotehash) (appends) | | `nullifiers` | [`NULLIFIERSEXISTS`](./instruction-set#isa-section-nullifierexists) membership-checks (latest), [`EMITNULLIFIER`](./instruction-set#isa-section-emitnullifier) (appends) | | `l1ToL2Messages` | [`L1TOL2MSGEXISTS`](./instruction-set#isa-section-l1tol2msgexists) (membership-checks (start-of-block)) | -> \* `*CALL` is short for `CALL`/`STATICCALL`/`DELEGATECALL`. +> \* `*CALL` is short for `CALL`/`STATICCALL`. > \* For the purpose of the AVM, the world state's `contracts` member is readable for [bytecode fetching](./execution#bytecode-fetch-and-decode), and it is effectively updated when a new contract class or instance is created (along with a nullifier for the contract class identifier or contract address). @@ -69,21 +69,21 @@ This trace of an AVM session's contract calls and world state accesses is named Each entry in the world state access trace is listed below along with its type and the instructions that append to it: -| Field | Relevant State | Type | Instructions | -| --- | --- | --- | --- | -| `accessCounter` | all state | `field` | incremented by all instructions below | +| Field | Relevant State | Type | Instructions | +| --------------------- | ----------------- | ---------------------------------- | ------------------------------------------------------------------- | +| `accessCounter` | all state | `field` | incremented by all instructions below | | `contractCalls` | Contracts | `Vector` | [`*CALL`](./instruction-set#isa-section-call) | | `publicStorageReads` | Public Storage | `Vector` | [`SLOAD`](./instruction-set#isa-section-sload) | | `publicStorageWrites` | Public Storage | `Vector` | [`SSTORE`](./instruction-set#isa-section-sstore) | | `noteHashChecks` | Note Hashes | `Vector` | [`NOTEHASHEXISTS`](./instruction-set#isa-section-notehashexists) | -| `noteHashes` | Note Hashes | `Vector` | [`EMITNOTEHASH`](./instruction-set#isa-section-emitnotehash) | +| `noteHashes` | Note Hashes | `Vector` | [`EMITNOTEHASH`](./instruction-set#isa-section-emitnotehash) | | `nullifierChecks` | Nullifiers | `Vector` | [`NULLIFIERSEXISTS`](./instruction-set#isa-section-nullifierexists) | -| `nullifiers` | Nullifiers | `Vector` | [`EMITNULLIFIER`](./instruction-set#isa-section-emitnullifier) | -| `l1ToL2MessageChecks` | L1-To-L2 Messages | `Vector` | [`L1TOL2MSGEXISTS`](./instruction-set#isa-section-l1tol2msgexists) | +| `nullifiers` | Nullifiers | `Vector` | [`EMITNULLIFIER`](./instruction-set#isa-section-emitnullifier) | +| `l1ToL2MessageChecks` | L1-To-L2 Messages | `Vector` | [`L1TOL2MSGEXISTS`](./instruction-set#isa-section-l1tol2msgexists) | > The types tracked in these trace vectors are defined [here](./type-structs). -> `*CALL` is short for `CALL`/`STATICCALL`/`DELEGATECALL`. +> `*CALL` is short for `CALL`/`STATICCALL`. > Aztec tree operations like membership checks, appends, or leaf updates are performed in-circuit by downstream circuits (public kernel and rollup circuits), _after_ AVM execution. The world state access trace is a list of requests made by the AVM for later circuits to perform. @@ -95,9 +95,9 @@ Each entry in the world state access trace is listed below along with its type a #### _AccruedSubstate_ -| Field | Type | Instructions | -| --- | --- | --- | -| `unencryptedLogs` | `Vector` | [`EMITUNENCRYPTEDLOG`](./instruction-set#isa-section-emitunencryptedlog) | -| `sentL2ToL1Messages` | `Vector` | [`SENDL1TOL2MSG`](./instruction-set#isa-section-sendl2tol1msg) | +| Field | Type | Instructions | +| -------------------- | --------------------------- | ------------------------------------------------------------------------ | +| `unencryptedLogs` | `Vector` | [`EMITUNENCRYPTEDLOG`](./instruction-set#isa-section-emitunencryptedlog) | +| `sentL2ToL1Messages` | `Vector` | [`SENDL1TOL2MSG`](./instruction-set#isa-section-sendl2tol1msg) | > The types tracked in these vectors are defined [here](./type-structs). diff --git a/docs/docs/protocol-specs/public-vm/type-structs.md b/docs/docs/protocol-specs/public-vm/type-structs.md index a02360fb77c..9c53f4140f4 100644 --- a/docs/docs/protocol-specs/public-vm/type-structs.md +++ b/docs/docs/protocol-specs/public-vm/type-structs.md @@ -4,104 +4,103 @@ This section lists type definitions relevant to AVM State and Circuit I/O. #### _TracedContractCall_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | The call pointer assigned to this call. | -| `address` | `field` | The called contract address. | -| `storageAddress` | `field` | The storage contract address (different from `address` for delegate calls). | -| `counter` | `field` | When did this occur relative to other world state accesses. | -| `endLifetime` | `field` | End lifetime of a call. Final `accessCounter` for reverted calls, `endLifetime` of parent for successful calls. Successful initial/top-level calls have infinite (max-value) `endLifetime`. | +| Field | Type | Description | +| ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | The call pointer assigned to this call. | +| `address` | `field` | The called contract address. | +| `counter` | `field` | When did this occur relative to other world state accesses. | +| `endLifetime` | `field` | End lifetime of a call. Final `accessCounter` for reverted calls, `endLifetime` of parent for successful calls. Successful initial/top-level calls have infinite (max-value) `endLifetime`. | #### _TracedL1ToL2MessageCheck_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | -| `leafIndex` | `field` | | -| `msgHash` | `field` | The message hash which is also the tree leaf value. | -| `exists` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. | +| Field | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `leafIndex` | `field` | | +| `msgHash` | `field` | The message hash which is also the tree leaf value. | +| `exists` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. | #### _TracedStorageRead_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls`| -| `slot` | `field` | | -| `exists` | `field` | Whether this slot has ever been previously written | -| `value` | `field` | | -| `counter` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this read/write should be considered to "exist" if this call or a parent reverted. | +| Field | Type | Description | +| ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `slot` | `field` | | +| `exists` | `field` | Whether this slot has ever been previously written | +| `value` | `field` | | +| `counter` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this read/write should be considered to "exist" if this call or a parent reverted. | #### _TracedStorageWrite_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls`| -| `slot` | `field` | | -| `value` | `field` | | -| `counter` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this read/write should be considered to "exist" if this call or a parent reverted. | +| Field | Type | Description | +| ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `slot` | `field` | | +| `value` | `field` | | +| `counter` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this read/write should be considered to "exist" if this call or a parent reverted. | #### _TracedNoteHashCheck_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | -| `leafIndex` | `field` | | -| `noteHash` | `field` | unsiloed | -| `exists` | `field` | | -| `counter` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. | +| Field | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `leafIndex` | `field` | | +| `noteHash` | `field` | unsiloed | +| `exists` | `field` | | +| `counter` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. | #### _TracedNoteHash_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | -| `noteHash` | `field` | | -| `counter` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this object should be considered to "exist" if this call or a parent reverted. | +| Field | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `noteHash` | `field` | | +| `counter` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this object should be considered to "exist" if this call or a parent reverted. | > Note: `value` here is not siloed by contract address nor is it made unique with a nonce. Note hashes are siloed and made unique by the public kernel. #### _TracedNullifierCheck_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | -| `nullifier` | `field` | unsiloed | -| `exists` | `field` | | -| `counter` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. | +| Field | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `nullifier` | `field` | unsiloed | +| `exists` | `field` | | +| `counter` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. | #### _TracedNullifier_ -| Field | Type | Description | -| --- | --- | --- | -| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | -| `nullifier` | `field` | | -| `counter` | `field` | | -| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this object should be considered to "exist" if this call or a parent reverted. | +| Field | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `callPointer` | `field` | Associates this item with a `TracedContractCall` entry in `worldStateAccessTrace.contractCalls` | +| `nullifier` | `field` | | +| `counter` | `field` | | +| `endLifetime` | `field` | Equivalent to `endLifetime` of the containing contract call. The last `counter` at which this object should be considered to "exist" if this call or a parent reverted. | #### _TracedArchiveLeafCheck_ -| Field | Type | Description | -| --- | --- | --- | -| `leafIndex` | `field` | | -| `leaf` | `field` | | +| Field | Type | Description | +| ----------- | ------- | ----------- | +| `leafIndex` | `field` | | +| `leaf` | `field` | | #### _UnencryptedLog_ -| Field | Type | Description | -| --- | --- | --- | +| Field | Type | Description | +| --------- | ------------------------------------- | -------------------------------------- | | `address` | `AztecAddress` | Contract address that emitted the log. | -| `log` | `[field; MAX_UNENCRYPTED_LOG_LENGTH]` | | +| `log` | `[field; MAX_UNENCRYPTED_LOG_LENGTH]` | | #### _SentL2ToL1Message_ -| Field | Type | Description | -| --- | --- | --- | +| Field | Type | Description | +| ----------- | -------------- | --------------------------------------------- | | `address` | `AztecAddress` | L2 contract address that emitted the message. | -| `recipient` | `EthAddress` | L1 contract address to send the message to. | -| `content` | `field` | Message content. | +| `recipient` | `EthAddress` | L1 contract address to send the message to. | +| `content` | `field` | Message content. | diff --git a/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md b/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md index 666f261409a..fedfb1c41b5 100644 --- a/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md +++ b/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md @@ -128,8 +128,6 @@ ContractClassRegistererContractArtifact ContractInstanceDeployerContractArtifact CounterContractArtifact CrowdfundingContractArtifact -DelegatedOnContractArtifact -DelegatorContractArtifact DocsExampleContractArtifact EasyPrivateTokenContractArtifact EasyPrivateVotingContractArtifact diff --git a/docs/sidebars.js b/docs/sidebars.js index b6b2d2537c0..f8a9c10e42b 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -6,7 +6,6 @@ const path = require("path"); /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ export default { sidebar: [ - { type: "html", value: 'Aztec Protocol', @@ -63,16 +62,15 @@ export default { { type: "doc", label: "Building in Public", - id: "aztec" + id: "aztec", }, - ], guidesSidebar: [ { type: "doc", label: "Popular Guides", - id: "guides/index" + id: "guides/index", }, { type: "html", @@ -81,7 +79,7 @@ export default { }, { type: "autogenerated", - dirName: "guides/developer_guides" + dirName: "guides/developer_guides", }, { type: "html", @@ -90,14 +88,14 @@ export default { { type: "doc", label: "Privacy Considerations", - id: "guides/privacy_considerations" + id: "guides/privacy_considerations", }, ], tutorialsSidebar: [ { type: "doc", label: "Tutorials and Examples", - id: "tutorials/index" + id: "tutorials/index", }, { type: "html", @@ -106,7 +104,7 @@ export default { }, { type: "autogenerated", - dirName: "tutorials/codealong" + dirName: "tutorials/codealong", }, { type: "html", @@ -115,7 +113,7 @@ export default { }, { type: "autogenerated", - dirName: "tutorials/examples" + dirName: "tutorials/examples", }, ], @@ -123,7 +121,7 @@ export default { { type: "doc", label: "References", - id: "reference/index" + id: "reference/index", }, { type: "html", @@ -132,7 +130,7 @@ export default { }, { type: "autogenerated", - dirName: "reference/developer_references" + dirName: "reference/developer_references", }, { type: "doc", @@ -151,7 +149,7 @@ export default { roadmapSidebar: [ { type: "autogenerated", - dirName: "aztec/roadmap" + dirName: "aztec/roadmap", }, ], protocolSpecSidebar: [ @@ -252,7 +250,6 @@ export default { "protocol-specs/calls/enqueued-calls", "protocol-specs/calls/batched-calls", "protocol-specs/calls/static-calls", - "protocol-specs/calls/delegate-calls", "protocol-specs/calls/unconstrained-calls", "protocol-specs/calls/public-private-messaging", ], diff --git a/docs/src/preprocess/InstructionSet/InstructionSet.js b/docs/src/preprocess/InstructionSet/InstructionSet.js index be0a6c174ca..cec5a392c7c 100644 --- a/docs/src/preprocess/InstructionSet/InstructionSet.js +++ b/docs/src/preprocess/InstructionSet/InstructionSet.js @@ -513,24 +513,6 @@ const INSTRUCTION_SET_RAW = [ "Tag checks": "", "Tag updates": "`T[dstOffset] = field`", }, - { - id: "storageaddress", - Name: "`STORAGEADDRESS`", - Category: "Execution Environment", - Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], - Args: [ - { - name: "dstOffset", - description: - "memory offset specifying where to store operation's result", - }, - ], - Expression: "`M[dstOffset] = context.environment.storageAddress`", - Summary: "Get the _storage_ address of the currently executing context", - Details: "The storage address is used for public storage accesses.", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = field`", - }, { id: "sender", Name: "`SENDER`", @@ -562,7 +544,8 @@ const INSTRUCTION_SET_RAW = [ }, ], Expression: "`M[dstOffset] = context.environment.functionSelector`", - Summary: "Get the function selector of the contract function being executed", + Summary: + "Get the function selector of the contract function being executed", Details: "", "Tag checks": "", "Tag updates": "`T[dstOffset] = u32`", @@ -946,7 +929,7 @@ M[dstOffset] = S[M[slotOffset]] "Load a word from this contract's persistent public storage. Zero is loaded for unwritten slots.", Details: ` // Expression is shorthand for -leafIndex = hash(context.environment.storageAddress, M[slotOffset]) +leafIndex = hash(context.environment.address, M[slotOffset]) exists = context.worldState.publicStorage.has(leafIndex) // exists == previously-written if exists: value = context.worldState.publicStorage.get(leafIndex: leafIndex) @@ -989,7 +972,7 @@ S[M[slotOffset]] = M[srcOffset] Details: ` // Expression is shorthand for context.worldState.publicStorage.set({ - leafIndex: hash(context.environment.storageAddress, M[slotOffset]), + leafIndex: hash(context.environment.address, M[slotOffset]), leaf: M[srcOffset], }) `, @@ -1028,7 +1011,7 @@ context.worldStateAccessTrace.publicStorageWrites.append( Expression: ` exists = context.worldState.noteHashes.has({ leafIndex: M[leafIndexOffset] - leaf: hash(context.environment.storageAddress, M[noteHashOffset]), + leaf: hash(context.environment.address, M[noteHashOffset]), }) M[existsOffset] = exists `, @@ -1060,7 +1043,7 @@ context.worldStateAccessTrace.noteHashChecks.append( ], Expression: ` context.worldState.noteHashes.append( - hash(context.environment.storageAddress, M[noteHashOffset]) + hash(context.environment.address, M[noteHashOffset]) ) `, Summary: "Emit a new note hash to be inserted into the note hash tree", @@ -1111,7 +1094,7 @@ context.worldStateAccessTrace.nullifierChecks.append( TracedNullifierCheck { callPointer: context.environment.callPointer, nullifier: M[nullifierOffset], - storageAddress: M[addressOffset], + address: M[addressOffset], exists: exists, // defined above counter: ++context.worldStateAccessTrace.accessCounter, } @@ -1132,7 +1115,7 @@ context.worldStateAccessTrace.nullifierChecks.append( ], Expression: ` context.worldState.nullifiers.append( - hash(context.environment.storageAddress, M[nullifierOffset]) + hash(context.environment.address, M[nullifierOffset]) ) `, Summary: "Emit a new nullifier to be inserted into the nullifier tree", @@ -1291,7 +1274,7 @@ chargeGas(context, l2GasCost=M[instr.args.gasOffset], daGasCost=M[instr.args.gasOffset+1]) traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=false) +nestedContext = deriveContext(context, instr.args, isStaticCall=false) execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext) `, @@ -1320,7 +1303,7 @@ chargeGas(context, l2GasCost=M[instr.args.gasOffset], daGasCost=M[instr.args.gasOffset+1]) traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=true, isDelegateCall=false) +nestedContext = deriveContext(context, instr.args, isStaticCall=true execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext) `, @@ -1333,34 +1316,6 @@ updateContextAfterNestedCall(context, instr.args, nestedContext) "Tag updates": ` T[successOffset] = u8 T[retOffset:retOffset+retSize] = field -`, - }, - { - id: "delegatecall", - Name: "`DELEGATECALL`", - Category: "Control Flow - Contract Calls", - Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], - Args: CALL_INSTRUCTION_ARGS, - Expression: ` -// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } -chargeGas(context, - l2GasCost=M[instr.args.gasOffset], - daGasCost=M[instr.args.gasOffset+1]) -traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=true) -execute(nestedContext) -updateContextAfterNestedCall(context, instr.args, nestedContext) -`, - Summary: - "(UNIMPLEMENTED) Call into another contract, but keep the caller's `sender` and `storageAddress`", - Details: - `Same as \`CALL\`, but \`sender\` and \`storageAddress\` remains - the same in the nested call as they were in the caller. ` + - CALL_INSTRUCTION_DETAILS, - "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", - "Tag updates": ` -T[successOffset] = u8 -T[retOffset:retOffset+retSize] = field `, }, { diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 107ebc2d0d8..a047ff3bce0 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -150,7 +150,7 @@ library Constants { uint256 internal constant GAS_FEES_LENGTH = 2; uint256 internal constant GAS_LENGTH = 2; uint256 internal constant GAS_SETTINGS_LENGTH = 7; - uint256 internal constant CALL_CONTEXT_LENGTH = 5; + uint256 internal constant CALL_CONTEXT_LENGTH = 4; uint256 internal constant CONTENT_COMMITMENT_LENGTH = 4; uint256 internal constant CONTRACT_INSTANCE_LENGTH = 16; uint256 internal constant CONTRACT_STORAGE_READ_LENGTH = 3; @@ -179,21 +179,20 @@ library Constants { uint256 internal constant SCOPED_NOTE_HASH_LENGTH = 3; uint256 internal constant NULLIFIER_LENGTH = 3; uint256 internal constant SCOPED_NULLIFIER_LENGTH = 4; - uint256 internal constant PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH = 13; - uint256 internal constant PRIVATE_CALL_REQUEST_LENGTH = 10; - uint256 internal constant PUBLIC_CALL_REQUEST_LENGTH = 8; - uint256 internal constant PUBLIC_INNER_CALL_REQUEST_LENGTH = 14; + uint256 internal constant PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH = 12; + uint256 internal constant PRIVATE_CALL_REQUEST_LENGTH = 8; + uint256 internal constant PUBLIC_CALL_REQUEST_LENGTH = 6; + uint256 internal constant PUBLIC_INNER_CALL_REQUEST_LENGTH = 13; uint256 internal constant ROLLUP_VALIDATION_REQUESTS_LENGTH = 2; uint256 internal constant STATE_REFERENCE_LENGTH = 8; uint256 internal constant TX_CONTEXT_LENGTH = 9; uint256 internal constant TX_REQUEST_LENGTH = 13; uint256 internal constant TOTAL_FEES_LENGTH = 1; uint256 internal constant HEADER_LENGTH = 24; - uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 544; - uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 691; - uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 547; - uint256 internal constant PRIVATE_CONTEXT_INPUTS_LENGTH = 39; - uint256 internal constant PUBLIC_CONTEXT_INPUTS_LENGTH = 42; + uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 501; + uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 674; + uint256 internal constant PRIVATE_CONTEXT_INPUTS_LENGTH = 38; + uint256 internal constant PUBLIC_CONTEXT_INPUTS_LENGTH = 41; uint256 internal constant FEE_RECIPIENT_LENGTH = 2; uint256 internal constant AGGREGATION_OBJECT_LENGTH = 16; uint256 internal constant SCOPED_READ_REQUEST_LEN = 3; @@ -204,12 +203,12 @@ library Constants { uint256 internal constant PUBLIC_DATA_UPDATE_REQUEST_LENGTH = 3; uint256 internal constant COMBINED_ACCUMULATED_DATA_LENGTH = 610; uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 44; - uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1144; - uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1970; - uint256 internal constant PUBLIC_ACCUMULATED_DATA_LENGTH = 1119; + uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1064; + uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1888; + uint256 internal constant PUBLIC_ACCUMULATED_DATA_LENGTH = 1055; uint256 internal constant NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS = 8; - uint256 internal constant PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3127; - uint256 internal constant VM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2472; + uint256 internal constant PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2997; + uint256 internal constant VM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2374; uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 664; uint256 internal constant CONSTANT_ROLLUP_DATA_LENGTH = 13; uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 30; @@ -240,7 +239,6 @@ library Constants { uint256 internal constant MEM_TAG_U128 = 6; uint256 internal constant SENDER_KERNEL_INPUTS_COL_OFFSET = 0; uint256 internal constant ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; - uint256 internal constant STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; uint256 internal constant FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET = 2; uint256 internal constant IS_STATIC_CALL_KERNEL_INPUTS_COL_OFFSET = 3; uint256 internal constant CHAIN_ID_KERNEL_INPUTS_COL_OFFSET = 4; diff --git a/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr b/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr index 3c0dd775cf4..4cdee565695 100644 --- a/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr +++ b/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr @@ -62,16 +62,14 @@ impl AppPayload { call.target_address, call.function_selector, call.args_hash, - call.is_static, - false + call.is_static ); } else { let _result = context.call_private_function_with_packed_args( call.target_address, call.function_selector, call.args_hash, - call.is_static, - false + call.is_static ); } } diff --git a/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr b/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr index 75de54e7427..0c41e6a6cc4 100644 --- a/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr +++ b/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr @@ -61,16 +61,14 @@ impl FeePayload { call.target_address, call.function_selector, call.args_hash, - call.is_static, - false + call.is_static ); } else { let _result = context.call_private_function_with_packed_args( call.target_address, call.function_selector, call.args_hash, - call.is_static, - false + call.is_static ); } } diff --git a/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr b/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr index 21bcb6fb7ef..104a1e6199e 100644 --- a/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr +++ b/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr @@ -54,26 +54,14 @@ pub struct PrivateCallInterface { impl PrivateCallInterface { pub fn call(self, context: &mut PrivateContext) -> T where T: Deserialize { pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args( - self.target_contract, - self.selector, - self.args_hash, - false, - false - ); + let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false); let unpacked: T = returns.unpack_into(); unpacked } pub fn view(self, context: &mut PrivateContext) -> T where T: Deserialize { pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false); - returns.unpack_into() - } - - pub fn delegate_call(self, context: &mut PrivateContext) -> T where T: Deserialize { - pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true); + let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true); returns.unpack_into() } } @@ -97,23 +85,12 @@ pub struct PrivateVoidCallInterface { impl PrivateVoidCallInterface { pub fn call(self, context: &mut PrivateContext) { pack_arguments(self.args); - context.call_private_function_with_packed_args( - self.target_contract, - self.selector, - self.args_hash, - false, - false - ).assert_empty(); + context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false).assert_empty(); } pub fn view(self, context: &mut PrivateContext) { pack_arguments(self.args); - context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty(); - } - - pub fn delegate_call(self, context: &mut PrivateContext) { - pack_arguments(self.args); - context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true).assert_empty(); + context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true).assert_empty(); } } @@ -136,7 +113,7 @@ pub struct PrivateStaticCallInterface { impl PrivateStaticCallInterface { pub fn view(self, context: &mut PrivateContext) -> T where T: Deserialize { pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false); + let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true); returns.unpack_into() } } @@ -160,7 +137,7 @@ pub struct PrivateStaticVoidCallInterface { impl PrivateStaticVoidCallInterface { pub fn view(self, context: &mut PrivateContext) { pack_arguments(self.args); - context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty(); + context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true).assert_empty(); } } @@ -196,11 +173,6 @@ impl PublicCallInterface { returns.deserialize_into() } - pub fn delegate_call(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.delegate_call_public_function(self.target_contract, self.selector, self.args); - returns.deserialize_into() - } - pub fn enqueue(self, context: &mut PrivateContext) { let args_hash = hash_args(self.args); pack_arguments(self.args); @@ -208,8 +180,7 @@ impl PublicCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ false, - /*delegate=*/ false + /*static=*/ false ) } @@ -220,20 +191,7 @@ impl PublicCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true, - /*delegate=*/ false - ) - } - - pub fn delegate_enqueue(self, context: &mut PrivateContext) { - let args_hash = hash_args(self.args); - pack_arguments(self.args); - context.call_public_function_with_packed_args( - self.target_contract, - self.selector, - args_hash, - /*static=*/ false, - /*delegate=*/ true + /*static=*/ true ) } } @@ -270,11 +228,6 @@ impl PublicVoidCallInterface { returns.assert_empty() } - pub fn delegate_call(self, context: &mut PublicContext) { - let returns = context.delegate_call_public_function(self.target_contract, self.selector, self.args); - returns.assert_empty() - } - pub fn enqueue(self, context: &mut PrivateContext) { let args_hash = hash_args(self.args); pack_arguments(self.args); @@ -282,8 +235,7 @@ impl PublicVoidCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ false, - /*delegate=*/ false + /*static=*/ false ) } @@ -294,20 +246,7 @@ impl PublicVoidCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true, - /*delegate=*/ false - ) - } - - pub fn delegate_enqueue(self, context: &mut PrivateContext) { - let args_hash = hash_args(self.args); - pack_arguments(self.args); - context.call_public_function_with_packed_args( - self.target_contract, - self.selector, - args_hash, - /*static=*/ false, - /*delegate=*/ true + /*static=*/ true ) } } @@ -347,8 +286,7 @@ impl PublicStaticCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true, - /*delegate=*/ false + /*static=*/ true ) } } @@ -387,8 +325,7 @@ impl PublicStaticVoidCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true, - /*delegate=*/ false + /*static=*/ true ) } } diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 5feea1b244e..796e49514f4 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -103,7 +103,7 @@ impl PrivateContext { } fn this_address(self) -> AztecAddress { - self.inputs.call_context.storage_contract_address + self.inputs.call_context.contract_address } fn chain_id(self) -> Field { @@ -296,7 +296,7 @@ impl PrivateContext { ) -> PackedReturns { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false, false) + self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false) } pub fn static_call_private_function( @@ -307,18 +307,7 @@ impl PrivateContext { ) -> PackedReturns { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, true, false) - } - - pub fn delegate_call_private_function( - &mut self, - contract_address: AztecAddress, - function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] - ) -> PackedReturns { - let args_hash = hash_args_array(args); - arguments::pack_arguments_array(args); - self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false, true) + self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, true) } pub fn call_private_function_no_args( @@ -326,7 +315,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector ) -> PackedReturns { - self.call_private_function_with_packed_args(contract_address, function_selector, 0, false, false) + self.call_private_function_with_packed_args(contract_address, function_selector, 0, false) } pub fn static_call_private_function_no_args( @@ -334,15 +323,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector ) -> PackedReturns { - self.call_private_function_with_packed_args(contract_address, function_selector, 0, true, false) - } - - pub fn delegate_call_private_function_no_args( - &mut self, - contract_address: AztecAddress, - function_selector: FunctionSelector - ) -> PackedReturns { - self.call_private_function_with_packed_args(contract_address, function_selector, 0, false, true) + self.call_private_function_with_packed_args(contract_address, function_selector, 0, true) } pub fn call_private_function_with_packed_args( @@ -350,8 +331,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - is_static_call: bool, - is_delegate_call: bool + is_static_call: bool ) -> PackedReturns { let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call; let start_side_effect_counter = self.side_effect_counter; @@ -360,8 +340,7 @@ impl PrivateContext { function_selector, args_hash, start_side_effect_counter, - is_static_call, - is_delegate_call + is_static_call ); self.side_effect_counter = end_side_effect_counter + 1; @@ -379,22 +358,10 @@ impl PrivateContext { // self.min_revertible_side_effect_counter = item.public_inputs.min_revertible_side_effect_counter; // } - let call_context = self.generate_call_context( - contract_address, - function_selector, - is_static_call, - is_delegate_call - ); + let call_context = CallContext { msg_sender: self.this_address(), contract_address, function_selector, is_static_call }; self.private_call_requests.push( - PrivateCallRequest { - contract_address, - call_context, - args_hash, - returns_hash, - start_side_effect_counter, - end_side_effect_counter - } + PrivateCallRequest { call_context, args_hash, returns_hash, start_side_effect_counter, end_side_effect_counter } ); PackedReturns::new(returns_hash) @@ -408,7 +375,7 @@ impl PrivateContext { ) { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, false) + self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false) } pub fn static_call_public_function( @@ -419,18 +386,7 @@ impl PrivateContext { ) { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true, false) - } - - pub fn delegate_call_public_function( - &mut self, - contract_address: AztecAddress, - function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] - ) { - let args_hash = hash_args_array(args); - arguments::pack_arguments_array(args); - self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, true) + self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true) } pub fn call_public_function_no_args( @@ -438,7 +394,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector ) { - self.call_public_function_with_packed_args(contract_address, function_selector, 0, false, false) + self.call_public_function_with_packed_args(contract_address, function_selector, 0, false) } pub fn static_call_public_function_no_args( @@ -446,15 +402,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector ) { - self.call_public_function_with_packed_args(contract_address, function_selector, 0, true, false) - } - - pub fn delegate_call_public_function_no_args( - &mut self, - contract_address: AztecAddress, - function_selector: FunctionSelector - ) { - self.call_public_function_with_packed_args(contract_address, function_selector, 0, false, true) + self.call_public_function_with_packed_args(contract_address, function_selector, 0, true) } pub fn call_public_function_with_packed_args( @@ -462,8 +410,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - is_static_call: bool, - is_delegate_call: bool + is_static_call: bool ) { let counter = self.next_counter(); @@ -479,22 +426,16 @@ impl PrivateContext { function_selector, args_hash, counter, - is_static_call, - is_delegate_call + is_static_call ); // Public calls are rerouted through the dispatch function. let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) }; - let call_context = self.generate_call_context( - contract_address, - function_selector, - is_static_call, - is_delegate_call - ); + let call_context = CallContext { msg_sender: self.this_address(), contract_address, function_selector, is_static_call }; - let call_request = PublicCallRequest { contract_address, call_context, args_hash, counter }; + let call_request = PublicCallRequest { call_context, args_hash, counter }; self.public_call_requests.push(call_request); } @@ -506,7 +447,7 @@ impl PrivateContext { ) { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.set_public_teardown_function_with_packed_args(contract_address, function_selector, args_hash, false, false) + self.set_public_teardown_function_with_packed_args(contract_address, function_selector, args_hash, false) } pub fn set_public_teardown_function_with_packed_args( @@ -514,8 +455,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - is_static_call: bool, - is_delegate_call: bool + is_static_call: bool ) { let counter = self.next_counter(); @@ -531,48 +471,21 @@ impl PrivateContext { function_selector, args_hash, counter, - is_static_call, - is_delegate_call + is_static_call ); let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) }; - let call_context = self.generate_call_context( - contract_address, - function_selector, - is_static_call, - is_delegate_call - ); + let call_context = CallContext { msg_sender: self.this_address(), contract_address, function_selector, is_static_call }; self.public_teardown_call_request = PublicCallRequest { - contract_address, call_context, args_hash, counter, }; } - fn generate_call_context( - self, - contract_address: AztecAddress, - function_selector: FunctionSelector, - is_static_call: bool, - is_delegate_call: bool - ) -> CallContext { - let msg_sender = if is_delegate_call { - self.msg_sender() - } else { - self.this_address() - }; - let storage_contract_address = if is_delegate_call { - self.this_address() - } else { - contract_address - }; - CallContext { msg_sender, storage_contract_address, function_selector, is_static_call, is_delegate_call } - } - fn next_counter(&mut self) -> u32 { let counter = self.side_effect_counter; self.side_effect_counter += 1; diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index ff476c4a672..089c209f620 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -103,15 +103,6 @@ impl PublicContext { FunctionReturns::new(data_to_return) } - fn delegate_call_public_function( - _self: &mut Self, - _contract_address: AztecAddress, - _function_selector: FunctionSelector, - _args: [Field] - ) -> FunctionReturns { - panic(f"'delegate_call_public_function' not implemented!") - } - fn push_note_hash(_self: &mut Self, note_hash: Field) { emit_note_hash(note_hash); } @@ -122,9 +113,6 @@ impl PublicContext { fn this_address(_self: Self) -> AztecAddress { address() } - pub fn storage_address(_self: Self) -> AztecAddress { - storage_address() - } fn msg_sender(_self: Self) -> AztecAddress { sender() } @@ -210,9 +198,6 @@ fn gas_for_call(user_gas: GasOpts) -> [Field; 2] { unconstrained fn address() -> AztecAddress { address_opcode() } -unconstrained fn storage_address() -> AztecAddress { - storage_address_opcode() -} unconstrained fn sender() -> AztecAddress { sender_opcode() } @@ -317,9 +302,6 @@ impl Empty for PublicContext { #[oracle(avmOpcodeAddress)] unconstrained fn address_opcode() -> AztecAddress {} -#[oracle(avmOpcodeStorageAddress)] -unconstrained fn storage_address_opcode() -> AztecAddress {} - #[oracle(avmOpcodeSender)] unconstrained fn sender_opcode() -> AztecAddress {} diff --git a/noir-projects/aztec-nr/aztec/src/messaging.nr b/noir-projects/aztec-nr/aztec/src/messaging.nr index e54c44c45c0..aecc3db1c07 100644 --- a/noir-projects/aztec-nr/aztec/src/messaging.nr +++ b/noir-projects/aztec-nr/aztec/src/messaging.nr @@ -7,7 +7,7 @@ use dep::protocol_types::{address::{AztecAddress, EthAddress}, merkle_tree::root pub fn process_l1_to_l2_message( l1_to_l2_root: Field, - storage_contract_address: AztecAddress, + contract_address: AztecAddress, portal_contract_address: EthAddress, chain_id: Field, version: Field, @@ -18,7 +18,7 @@ pub fn process_l1_to_l2_message( let message_hash = compute_message_hash( portal_contract_address, chain_id, - storage_contract_address, + contract_address, version, content, secret_hash @@ -27,7 +27,7 @@ pub fn process_l1_to_l2_message( // We prove that `message_hash` is in the tree by showing the derivation of the tree root, using a merkle path we // get from an oracle. let (leaf_index, sibling_path) = unsafe { - get_l1_to_l2_membership_witness(storage_contract_address, message_hash, secret) + get_l1_to_l2_membership_witness(contract_address, message_hash, secret) }; let root = root_from_sibling_path(message_hash, leaf_index, sibling_path); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr b/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr index 46975d97bd6..aae089cd731 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr @@ -6,8 +6,7 @@ unconstrained fn call_private_function_oracle( _function_selector: FunctionSelector, _args_hash: Field, _start_side_effect_counter: u32, - _is_static_call: bool, - _is_delegate_call: bool + _is_static_call: bool ) -> [Field; 2] {} pub unconstrained fn call_private_function_internal( @@ -15,16 +14,14 @@ pub unconstrained fn call_private_function_internal( function_selector: FunctionSelector, args_hash: Field, start_side_effect_counter: u32, - is_static_call: bool, - is_delegate_call: bool + is_static_call: bool ) -> (u32, Field) { let fields = call_private_function_oracle( contract_address, function_selector, args_hash, start_side_effect_counter, - is_static_call, - is_delegate_call + is_static_call ); let mut reader = Reader::new(fields); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr b/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr index a50b4fa55e7..06a991fbdda 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr @@ -6,8 +6,7 @@ unconstrained fn enqueue_public_function_call_oracle( _function_selector: FunctionSelector, _args_hash: Field, _side_effect_counter: u32, - _is_static_call: bool, - _is_delegate_call: bool + _is_static_call: bool ) -> Field {} pub unconstrained fn enqueue_public_function_call_internal( @@ -15,16 +14,14 @@ pub unconstrained fn enqueue_public_function_call_internal( function_selector: FunctionSelector, args_hash: Field, side_effect_counter: u32, - is_static_call: bool, - is_delegate_call: bool + is_static_call: bool ) -> Field { enqueue_public_function_call_oracle( contract_address, function_selector, args_hash, side_effect_counter, - is_static_call, - is_delegate_call + is_static_call ) } @@ -34,8 +31,7 @@ unconstrained fn set_public_teardown_function_call_oracle( _function_selector: FunctionSelector, _args_hash: Field, _side_effect_counter: u32, - _is_static_call: bool, - _is_delegate_call: bool + _is_static_call: bool ) -> Field {} pub unconstrained fn set_public_teardown_function_call_internal( @@ -43,16 +39,14 @@ pub unconstrained fn set_public_teardown_function_call_internal( function_selector: FunctionSelector, args_hash: Field, side_effect_counter: u32, - is_static_call: bool, - is_delegate_call: bool + is_static_call: bool ) -> Field { set_public_teardown_function_call_oracle( contract_address, function_selector, args_hash, side_effect_counter, - is_static_call, - is_delegate_call + is_static_call ) } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr index 96cb1d3c02e..3c6c6b4cace 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr @@ -77,16 +77,14 @@ pub unconstrained fn assert_private_call_fails( function_selector: FunctionSelector, argsHash: Field, sideEffectsCounter: Field, - isStaticCall: bool, - isDelegateCall: bool + isStaticCall: bool ) { oracle_assert_private_call_fails( target_address, function_selector, argsHash, sideEffectsCounter, - isStaticCall, - isDelegateCall + isStaticCall ) } @@ -175,8 +173,7 @@ unconstrained fn oracle_assert_private_call_fails( function_selector: FunctionSelector, argsHash: Field, sideEffectsCounter: Field, - isStaticCall: bool, - isDelegateCall: bool + isStaticCall: bool ) {} #[oracle(addNullifiers)] diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index 09b36efade8..b9b13fc92a1 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -183,8 +183,7 @@ impl TestEnvironment { call_interface.get_selector(), hash_args(call_interface.get_args()), cheatcodes::get_side_effects_counter() as Field, - call_interface.get_is_static(), - false + call_interface.get_is_static() ); } diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index 2abc3ddb90a..f4700540621 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -15,8 +15,6 @@ members = [ "contracts/contract_instance_deployer_contract", "contracts/counter_contract", "contracts/crowdfunding_contract", - "contracts/delegator_contract", - "contracts/delegated_on_contract", "contracts/docs_example_contract", "contracts/easy_private_token_contract", "contracts/easy_private_voting_contract", diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr index dbdcf349ca8..87ac7c518d0 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr @@ -63,16 +63,14 @@ impl DAppPayload { call.target_address, call.function_selector, call.args_hash, - call.is_static, - false + call.is_static ); } else { let _result = context.call_private_function_with_packed_args( call.target_address, call.function_selector, call.args_hash, - call.is_static, - false + call.is_static ); } } diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 5077d304543..0beac70ca72 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -311,11 +311,6 @@ contract AvmTest { context.this_address() } - #[public] - fn get_storage_address() -> AztecAddress { - context.storage_address() - } - #[public] fn get_sender() -> AztecAddress { context.msg_sender() @@ -419,19 +414,19 @@ contract AvmTest { // Use the standard context interface to check for a nullifier #[public] fn nullifier_exists(nullifier: Field) -> bool { - context.nullifier_exists(nullifier, context.storage_address()) + context.nullifier_exists(nullifier, context.this_address()) } #[public] fn assert_nullifier_exists(nullifier: Field) { - assert(context.nullifier_exists(nullifier, context.storage_address()), "Nullifier doesn't exist!"); + assert(context.nullifier_exists(nullifier, context.this_address()), "Nullifier doesn't exist!"); } // Use the standard context interface to emit a new nullifier #[public] fn emit_nullifier_and_check(nullifier: Field) { context.push_nullifier(nullifier); - let exists = context.nullifier_exists(nullifier, context.storage_address()); + let exists = context.nullifier_exists(nullifier, context.this_address()); assert(exists, "Nullifier was just created, but its existence wasn't detected!"); } @@ -542,8 +537,6 @@ contract AvmTest { test_get_contract_instance(); dep::aztec::oracle::debug_log::debug_log("get_address"); let _ = get_address(); - dep::aztec::oracle::debug_log::debug_log("get_storage_address"); - let _ = get_storage_address(); dep::aztec::oracle::debug_log::debug_log("get_sender"); let _ = get_sender(); dep::aztec::oracle::debug_log::debug_log("get_function_selector"); diff --git a/noir-projects/noir-contracts/contracts/delegated_on_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/delegated_on_contract/Nargo.toml deleted file mode 100644 index d26264990ad..00000000000 --- a/noir-projects/noir-contracts/contracts/delegated_on_contract/Nargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "delegated_on_contract" -type = "contract" -authors = [""] -compiler_version = ">=0.25.0" - -[dependencies] -aztec = { path = "../../../aztec-nr/aztec" } -value_note = { path = "../../../aztec-nr/value-note" } \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr deleted file mode 100644 index 30a4ab02771..00000000000 --- a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr +++ /dev/null @@ -1,47 +0,0 @@ -// A contract used along with `Parent` contract to test nested calls. -use dep::aztec::macros::aztec; - -#[aztec] -contract DelegatedOn { - use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, PublicMutable, PrivateSet, Map}; - use dep::aztec::{ - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - keys::getters::get_public_keys, utils::comparison::Comparator, - macros::{storage::storage, functions::{private, public}} - }; - use dep::value_note::value_note::ValueNote; - - #[storage] - struct Storage { - current_value: PublicMutable, - a_map_with_private_values: Map, Context>, - } - - #[private] - fn private_set_value(new_value: Field, owner: AztecAddress) -> Field { - let msg_sender_keys = get_public_keys(context.msg_sender()); - let owner_keys = get_public_keys(owner); - - let mut note = ValueNote::new(new_value, owner_keys.npk_m.hash()); - storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note(&mut context, msg_sender_keys.ovpk_m, owner_keys.ivpk_m, owner)); - new_value - } - - #[public] - fn public_set_value(new_value: Field) -> Field { - storage.current_value.write(new_value); - new_value - } - - #[private] - fn get_private_value(amount: Field, owner: AztecAddress) -> pub Field { - let mut options = NoteGetterOptions::new(); - options = options.select(ValueNote::properties().value, Comparator.EQ, amount).set_limit(1); - let notes = storage.a_map_with_private_values.at(owner).get_notes(options); - notes.get(0).value - } - - unconstrained fn view_public_value() -> Field { - storage.current_value.read() - } -} diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml deleted file mode 100644 index 1aad229b828..00000000000 --- a/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "delegator_contract" -type = "contract" -authors = [""] -compiler_version = ">=0.25.0" - -[dependencies] -aztec = { path = "../../../aztec-nr/aztec" } -value_note = { path = "../../../aztec-nr/value-note" } -delegated_on = { path = "../delegated_on_contract"} \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr deleted file mode 100644 index 80e095d0e43..00000000000 --- a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr +++ /dev/null @@ -1,43 +0,0 @@ -// A contract used along with `Parent` contract to test nested calls. -use dep::aztec::macros::aztec; - -#[aztec] -contract Delegator { - use dep::aztec::prelude::{AztecAddress, PublicMutable, PrivateSet, Map, NoteGetterOptions}; - use dep::value_note::value_note::ValueNote; - use dep::delegated_on::DelegatedOn; - use dep::aztec::{utils::comparison::Comparator, macros::{storage::storage, functions::{private, public}}}; - - #[storage] - struct Storage { - current_value: PublicMutable, - a_map_with_private_values: Map, Context>, - } - #[private] - fn private_delegate_set_value( - target_contract: AztecAddress, - value: Field, - owner: AztecAddress - ) -> Field { - // Call the target private function - DelegatedOn::at(target_contract).private_set_value(value, owner).delegate_call(&mut context) - } - #[private] - fn enqueued_delegate_set_value(target_contract: AztecAddress, value: Field) { - DelegatedOn::at(target_contract).public_set_value(value).delegate_enqueue(&mut context) - } - #[public] - fn public_delegate_set_value(target_contract: AztecAddress, value: Field) -> Field { - DelegatedOn::at(target_contract).public_set_value(value).delegate_call(&mut context) - } - #[private] - fn get_private_value(amount: Field, owner: AztecAddress) -> Field { - let mut options = NoteGetterOptions::new(); - options = options.select(ValueNote::properties().value, Comparator.EQ, amount).set_limit(1); - let notes = storage.a_map_with_private_values.at(owner).get_notes(options); - notes.get_unchecked(0).value - } - unconstrained fn view_public_value() -> Field { - storage.current_value.read() - } -} diff --git a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr index 2d3a33b808d..c15aef6208b 100644 --- a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr @@ -204,13 +204,13 @@ contract PendingNoteHashes { ) { // nested call to create/insert note let _res = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, insert_fn_selector, [amount, owner.to_field(), outgoing_viewer.to_field()] ); // nested call to read and nullify that note let _res = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, get_then_nullify_fn_selector, [amount, owner.to_field()] ); @@ -231,29 +231,29 @@ contract PendingNoteHashes { // nested call to create/insert note let _callStackItem1 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, insert_fn_selector, insertArgs ); let _callStackItem2 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, insert_fn_selector, insertArgs ); // nested call to read and nullify that note let _callStackItem3 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs ); let _callStackItem4 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs ); // nested call to confirm that balance is zero // TODO(dbanks12): once > 4 nested calls is supported, can confirm 0 balance: - //let _callStackItem5 = context.call_private_function(inputs.call_context.storage_contract_address, get_note_zero_fn_selector, [owner]); + //let _callStackItem5 = context.call_private_function(inputs.call_context.contract_address, get_note_zero_fn_selector, [owner]); } // same test as above, but insert 2, get 1, nullify 1 @@ -271,18 +271,18 @@ contract PendingNoteHashes { // nested call to create/insert note let _callStackItem1 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, insert_fn_selector, insertArgs ); let _callStackItem2 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, insert_fn_selector, insertArgs ); // nested call to read and nullify that note let _callStackItem3 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs ); @@ -305,18 +305,18 @@ contract PendingNoteHashes { // nested call to create/insert note let _callStackItem1 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, insert_fn_selector, insertArgs ); // nested call to read and nullify that note let _callStackItem2 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs ); let _callStackItem3 = context.call_private_function( - inputs.call_context.storage_contract_address, + inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs ); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr index 63a3eb7f5c6..ca5ca3013a3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr @@ -17,26 +17,10 @@ use dep::types::{ utils::arrays::find_index_hint }; -fn validate_call_context( - target_contract: AztecAddress, - target_context: CallContext, - this_context: CallContext -) { - if target_context.is_delegate_call { - assert_eq( - target_context.msg_sender, this_context.msg_sender, "incorrect msg_sender for delegate call request" - ); - assert_eq( - target_context.storage_contract_address, this_context.storage_contract_address, "incorrect storage_contract_address for delegate call request" - ); - } else { - assert_eq( - target_context.msg_sender, this_context.storage_contract_address, "incorrect msg_sender for call request" - ); - assert_eq( - target_context.storage_contract_address, target_contract, "incorrect storage_contract_address for call request" - ); - } +fn validate_call_context(target_context: CallContext, this_context: CallContext) { + assert_eq( + target_context.msg_sender, this_context.contract_address, "incorrect msg_sender for call request" + ); if !target_context.is_static_call { assert(this_context.is_static_call == false, "static call cannot make non-static calls"); } @@ -94,7 +78,7 @@ pub struct PrivateCallDataValidator { impl PrivateCallDataValidator { pub fn new(data: PrivateCallData) -> Self { - let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(data.call_stack_item.public_inputs); + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(data.public_inputs); PrivateCallDataValidator { data, array_lengths } } @@ -113,9 +97,8 @@ impl PrivateCallDataValidator { } pub fn validate_as_first_call(self) { - let public_inputs = self.data.call_stack_item.public_inputs; + let public_inputs = self.data.public_inputs; let call_context = public_inputs.call_context; - assert(call_context.is_delegate_call == false, "Users cannot make a delegatecall"); assert(call_context.is_static_call == false, "Users cannot make a static call"); assert( call_context.msg_sender == AztecAddress::from_field(MAX_FIELD_VALUE), "Users cannot set msg_sender in first call" @@ -124,68 +107,47 @@ impl PrivateCallDataValidator { // Confirm that the TxRequest (user's intent) matches the private call being executed. pub fn validate_against_tx_request(self, tx_request: TxRequest) { - let call_stack_item = self.data.call_stack_item; + let public_inputs = self.data.public_inputs; assert_eq( - tx_request.origin, call_stack_item.contract_address, "origin address does not match call stack items contract address" + tx_request.origin, public_inputs.call_context.contract_address, "contract address does not match origin" ); assert_eq( - tx_request.function_data, call_stack_item.function_data, "tx_request function_data must match call_stack_item function_data" + tx_request.function_data.selector, public_inputs.call_context.function_selector, "function_selector in call_context does not match the value in tx_request" + ); + assert( + tx_request.function_data.is_private, "tx_request does not indicate the first function is private" ); assert_eq( - tx_request.args_hash, call_stack_item.public_inputs.args_hash, "noir function args passed to tx_request must match args in the call_stack_item" + tx_request.args_hash, public_inputs.args_hash, "args_hash in private call does not match the value in tx_request" ); assert_eq( - tx_request.tx_context, call_stack_item.public_inputs.tx_context, "tx_context in tx_request must match tx_context in call_stack_item" + tx_request.tx_context, public_inputs.tx_context, "tx_context in private call does not match the value in tx_request" ); } pub fn validate_against_call_request(self, request: PrivateCallRequest) { - let call_stack_item = self.data.call_stack_item; - - assert_eq( - request.contract_address, call_stack_item.contract_address, "contract_address does not match call request" - ); - assert_eq( - request.call_context, call_stack_item.public_inputs.call_context, "call_context does not match call request" - ); + let public_inputs = self.data.public_inputs; + assert_eq(request.call_context, public_inputs.call_context, "call_context does not match call request"); + assert_eq(request.args_hash, public_inputs.args_hash, "args_hash does not match call request"); + assert_eq(request.returns_hash, public_inputs.returns_hash, "returns_hash does not match call request"); assert_eq( - request.args_hash, call_stack_item.public_inputs.args_hash, "args_hash does not match call request" + request.start_side_effect_counter, public_inputs.start_side_effect_counter, "start_side_effect_counter does not match call request" ); assert_eq( - request.returns_hash, call_stack_item.public_inputs.returns_hash, "returns_hash does not match call request" - ); - assert_eq( - request.start_side_effect_counter, call_stack_item.public_inputs.start_side_effect_counter, "start_side_effect_counter does not match call request" - ); - assert_eq( - request.end_side_effect_counter, call_stack_item.public_inputs.end_side_effect_counter, "end_side_effect_counter does not match call request" + request.end_side_effect_counter, public_inputs.end_side_effect_counter, "end_side_effect_counter does not match call request" ); } pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { let constants = previous_kernel.constants; - let public_inputs = self.data.call_stack_item.public_inputs; + let public_inputs = self.data.public_inputs; assert_eq(public_inputs.historical_header, constants.historical_header, "mismatch historical header"); assert_eq(public_inputs.tx_context, constants.tx_context, "mismatch tx context"); // constants.global_variables is not relevant to private functions and is ensured to be empty in PrivateKernelCircuitOutputValidator. } fn validate_call(self) { - let call_context = self.data.call_stack_item.public_inputs.call_context; - - let is_own_storage = call_context.storage_contract_address == self.data.call_stack_item.contract_address; - if call_context.is_delegate_call { - assert( - !is_own_storage, "current contract address must not match storage contract address for delegate calls" - ); - } else { - assert(is_own_storage, "call stack storage address does not match expected contract address"); - } - - assert_eq( - call_context.function_selector, self.data.call_stack_item.function_data.selector, "function selector in call context does not match call stack item" - ); - + let call_context = self.data.public_inputs.call_context; if call_context.is_static_call { // No state changes are allowed for static calls: assert_eq(self.array_lengths.note_hashes, 0, "note_hashes must be empty for static calls"); @@ -204,18 +166,14 @@ impl PrivateCallDataValidator { } fn validate_private_call_requests(self) { - let public_inputs = self.data.call_stack_item.public_inputs; + let public_inputs = self.data.public_inputs; let call_requests = public_inputs.private_call_requests; let num_requests = self.array_lengths.private_call_requests; let mut should_check = true; for i in 0..call_requests.len() { should_check &= i != num_requests; if should_check { - validate_call_context( - call_requests[i].contract_address, - call_requests[i].call_context, - public_inputs.call_context - ); + validate_call_context(call_requests[i].call_context, public_inputs.call_context); } } @@ -244,36 +202,28 @@ impl PrivateCallDataValidator { } fn validate_public_call_requests(self) { - let public_inputs = self.data.call_stack_item.public_inputs; - let call_requests = self.data.call_stack_item.public_inputs.public_call_requests; + let public_inputs = self.data.public_inputs; + let call_requests = public_inputs.public_call_requests; let num_requests = self.array_lengths.public_call_requests; let mut should_check = true; for i in 0..call_requests.len() { should_check &= i != num_requests; if should_check { - validate_call_context( - call_requests[i].contract_address, - call_requests[i].call_context, - public_inputs.call_context - ); + validate_call_context(call_requests[i].call_context, public_inputs.call_context); } } } fn validate_teardown_call_request(self) { - let public_inputs = self.data.call_stack_item.public_inputs; - let request = self.data.call_stack_item.public_inputs.public_teardown_call_request; + let public_inputs = self.data.public_inputs; + let request = public_inputs.public_teardown_call_request; if request.counter != 0 { - validate_call_context( - request.contract_address, - request.call_context, - public_inputs.call_context - ); + validate_call_context(request.call_context, public_inputs.call_context); } } fn validate_counters(self) { - let public_inputs = self.data.call_stack_item.public_inputs; + let public_inputs = self.data.public_inputs; let counter_start = public_inputs.start_side_effect_counter; let counter_end = public_inputs.end_side_effect_counter; @@ -350,9 +300,9 @@ impl PrivateCallDataValidator { } fn validate_note_logs(self, accumulated_note_hashes: [ScopedNoteHash; N]) { - let note_logs = self.data.call_stack_item.public_inputs.note_encrypted_logs_hashes; + let note_logs = self.data.public_inputs.note_encrypted_logs_hashes; let num_logs = self.array_lengths.note_encrypted_logs_hashes; - let storage_contract_address = self.data.call_stack_item.public_inputs.call_context.storage_contract_address; + let contract_address = self.data.public_inputs.call_context.contract_address; let mut should_check = true; for i in 0..note_logs.len() { should_check &= i != num_logs; @@ -370,7 +320,7 @@ impl PrivateCallDataValidator { ); // If the note_index points to an empty note hash, the following check will fail. assert_eq( - accumulated_note_hashes[note_index].contract_address, storage_contract_address, "could not link a note log to a note hash in another contract" + accumulated_note_hashes[note_index].contract_address, contract_address, "could not link a note log to a note hash in another contract" ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr index e3ccbc1aab8..d96536d7766 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr @@ -5,14 +5,14 @@ use dep::types::{ }; pub fn validate_contract_address(private_call_data: PrivateCallData, protocol_contract_tree_root: Field) { - let contract_address = private_call_data.call_stack_item.contract_address; + let contract_address = private_call_data.public_inputs.call_context.contract_address; assert(!contract_address.is_zero(), "contract address cannot be zero"); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3062): Why is this using a hash function from the stdlib::recursion namespace let private_call_vk_hash = stdlib_recursion_verification_key_compress_native_vk(private_call_data.vk); let computed_address = AztecAddress::compute_from_private_function( - private_call_data.call_stack_item.function_data.selector, + private_call_data.public_inputs.call_context.function_selector, private_call_vk_hash, private_call_data.function_leaf_membership_witness, private_call_data.contract_class_artifact_hash, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index f7db6e7b081..9fa956e45f3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -97,7 +97,7 @@ impl PrivateKernelCircuitOutputValidator { self.output.public_teardown_call_request, private_call.public_teardown_call_request, "incorrect initial public_teardown_call_request" ); let initial_fee_payer = if private_call.is_fee_payer { - private_call.call_context.storage_contract_address + private_call.call_context.contract_address } else { AztecAddress::zero() }; @@ -149,7 +149,7 @@ impl PrivateKernelCircuitOutputValidator { assert(!private_call.is_fee_payer, "cannot overwrite fee_payer"); previous_kernel.fee_payer } else if private_call.is_fee_payer { - private_call.call_context.storage_contract_address + private_call.call_context.contract_address } else { AztecAddress::zero() }; @@ -233,48 +233,48 @@ impl PrivateKernelCircuitOutputValidator { offsets: PrivateKernelCircuitPublicInputsArrayLengths, num_popped_call: u32 ) { - let storage_contract_address = private_call.call_context.storage_contract_address; + let contract_address = private_call.call_context.contract_address; assert_array_appended_scoped( self.output.validation_requests.note_hash_read_requests, private_call.note_hash_read_requests, array_lengths.note_hash_read_requests, offsets.note_hash_read_requests, - storage_contract_address + contract_address ); assert_array_appended_scoped( self.output.validation_requests.nullifier_read_requests, private_call.nullifier_read_requests, array_lengths.nullifier_read_requests, offsets.nullifier_read_requests, - storage_contract_address + contract_address ); assert_array_appended_scoped( self.output.validation_requests.scoped_key_validation_requests_and_generators, private_call.key_validation_requests_and_generators, array_lengths.key_validation_requests_and_generators, offsets.scoped_key_validation_requests_and_generators, - storage_contract_address + contract_address ); assert_array_appended_scoped( self.output.end.note_hashes, private_call.note_hashes, array_lengths.note_hashes, offsets.note_hashes, - storage_contract_address + contract_address ); assert_array_appended_scoped( self.output.end.nullifiers, private_call.nullifiers, array_lengths.nullifiers, offsets.nullifiers, - storage_contract_address + contract_address ); assert_array_appended_scoped( self.output.end.l2_to_l1_msgs, private_call.l2_to_l1_msgs, array_lengths.l2_to_l1_msgs, offsets.l2_to_l1_msgs, - storage_contract_address + contract_address ); assert_array_appended( self.output.end.note_encrypted_logs_hashes, @@ -287,14 +287,14 @@ impl PrivateKernelCircuitOutputValidator { private_call.encrypted_logs_hashes, array_lengths.encrypted_logs_hashes, offsets.encrypted_logs_hashes, - storage_contract_address + contract_address ); assert_array_appended_scoped( self.output.end.unencrypted_logs_hashes, private_call.unencrypted_logs_hashes, array_lengths.unencrypted_logs_hashes, offsets.unencrypted_logs_hashes, - storage_contract_address + contract_address ); assert_array_appended( self.output.end.public_call_requests, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr index cfe96b06f3b..782967e4843 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr @@ -9,12 +9,6 @@ use dep::types::{ utils::arrays::{array_length, array_to_bounded_vec, sort_by_counter_asc, sort_by_counter_desc} }; -pub struct DataSource { - private_call_public_inputs: PrivateCircuitPublicInputs, - contract_address: AztecAddress, - storage_contract_address: AztecAddress, -} - pub fn create_first_nullifier(tx_request: TxRequest) -> ScopedNullifier { Nullifier { value: tx_request.hash(), note_hash: 0, counter: 0 }.scope(AztecAddress::zero()) } @@ -83,16 +77,8 @@ impl PrivateKernelCircuitPublicInputsComposer { *self } - pub fn with_private_call( - &mut self, - private_call_public_inputs: PrivateCircuitPublicInputs, - contract_address: AztecAddress - ) -> Self { - let storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - let source = DataSource { private_call_public_inputs, contract_address, storage_contract_address }; - - self.propagate_from_private_call(source); - + pub fn with_private_call(&mut self, private_call_public_inputs: PrivateCircuitPublicInputs) -> Self { + self.propagate_from_private_call(private_call_public_inputs); *self } @@ -107,115 +93,115 @@ impl PrivateKernelCircuitPublicInputsComposer { self.public_inputs.finish() } - fn propagate_from_private_call(&mut self, source: DataSource) { - self.propagate_max_block_number(source); - self.propagate_note_hash_read_requests(source); - self.propagate_nullifier_read_requests(source); - self.propagate_key_validation_requests(source); - self.propagate_note_hashes(source); - self.propagate_nullifiers(source); - self.propagate_l2_to_l1_messages(source); - self.propagate_logs(source); - self.propagate_private_call_requests(source); - self.propagate_public_call_requests(source); - self.propagate_public_teardown_call_request(source); - self.propagate_fee_payer(source); - self.propagate_min_revertible_side_effect_counter(source); + fn propagate_from_private_call(&mut self, private_call: PrivateCircuitPublicInputs) { + self.propagate_max_block_number(private_call); + self.propagate_note_hash_read_requests(private_call); + self.propagate_nullifier_read_requests(private_call); + self.propagate_key_validation_requests(private_call); + self.propagate_note_hashes(private_call); + self.propagate_nullifiers(private_call); + self.propagate_l2_to_l1_messages(private_call); + self.propagate_logs(private_call); + self.propagate_private_call_requests(private_call); + self.propagate_public_call_requests(private_call); + self.propagate_public_teardown_call_request(private_call); + self.propagate_fee_payer(private_call); + self.propagate_min_revertible_side_effect_counter(private_call); } - fn propagate_min_revertible_side_effect_counter(&mut self, source: DataSource) { + fn propagate_min_revertible_side_effect_counter(&mut self, private_call: PrivateCircuitPublicInputs) { if self.public_inputs.min_revertible_side_effect_counter != 0 { assert( - source.private_call_public_inputs.min_revertible_side_effect_counter == 0, "cannot overwrite non-zero min_revertible_side_effect_counter" + private_call.min_revertible_side_effect_counter == 0, "cannot overwrite non-zero min_revertible_side_effect_counter" ); } else { - self.public_inputs.min_revertible_side_effect_counter = source.private_call_public_inputs.min_revertible_side_effect_counter; + self.public_inputs.min_revertible_side_effect_counter = private_call.min_revertible_side_effect_counter; }; } - fn propagate_max_block_number(&mut self, source: DataSource) { + fn propagate_max_block_number(&mut self, private_call: PrivateCircuitPublicInputs) { // Update the max block number if the private call requested a lower one. - self.public_inputs.validation_requests.max_block_number = MaxBlockNumber::min(self.public_inputs.validation_requests.max_block_number, source.private_call_public_inputs.max_block_number); + self.public_inputs.validation_requests.max_block_number = MaxBlockNumber::min(self.public_inputs.validation_requests.max_block_number, private_call.max_block_number); } - fn propagate_note_hash_read_requests(&mut self, source: DataSource) { - let read_requests = source.private_call_public_inputs.note_hash_read_requests; + fn propagate_note_hash_read_requests(&mut self, private_call: PrivateCircuitPublicInputs) { + let read_requests = private_call.note_hash_read_requests; for i in 0..read_requests.len() { let request = read_requests[i]; if !is_empty(request) { - self.public_inputs.validation_requests.note_hash_read_requests.push(request.scope(source.storage_contract_address)); + self.public_inputs.validation_requests.note_hash_read_requests.push(request.scope(private_call.call_context.contract_address)); } } } - fn propagate_nullifier_read_requests(&mut self, source: DataSource) { - let nullifier_read_requests = source.private_call_public_inputs.nullifier_read_requests; + fn propagate_nullifier_read_requests(&mut self, private_call: PrivateCircuitPublicInputs) { + let nullifier_read_requests = private_call.nullifier_read_requests; for i in 0..nullifier_read_requests.len() { let request = nullifier_read_requests[i]; if !is_empty(request) { - self.public_inputs.validation_requests.nullifier_read_requests.push(request.scope(source.storage_contract_address)); + self.public_inputs.validation_requests.nullifier_read_requests.push(request.scope(private_call.call_context.contract_address)); } } } - fn propagate_key_validation_requests(&mut self, source: DataSource) { - let key_validation_requests_and_generators = source.private_call_public_inputs.key_validation_requests_and_generators; + fn propagate_key_validation_requests(&mut self, private_call: PrivateCircuitPublicInputs) { + let key_validation_requests_and_generators = private_call.key_validation_requests_and_generators; for i in 0..key_validation_requests_and_generators.len() { let request = key_validation_requests_and_generators[i]; if !is_empty(request) { - self.public_inputs.validation_requests.scoped_key_validation_requests_and_generators.push(request.scope(source.storage_contract_address)); + self.public_inputs.validation_requests.scoped_key_validation_requests_and_generators.push(request.scope(private_call.call_context.contract_address)); } } } - fn propagate_note_hashes(&mut self, source: DataSource) { - let note_hashes = source.private_call_public_inputs.note_hashes; + fn propagate_note_hashes(&mut self, private_call: PrivateCircuitPublicInputs) { + let note_hashes = private_call.note_hashes; for i in 0..note_hashes.len() { let note_hash = note_hashes[i]; if note_hash.value != 0 { - self.public_inputs.end.note_hashes.push(note_hash.scope(source.storage_contract_address)); + self.public_inputs.end.note_hashes.push(note_hash.scope(private_call.call_context.contract_address)); } } } - fn propagate_nullifiers(&mut self, source: DataSource) { - let nullifiers = source.private_call_public_inputs.nullifiers; + fn propagate_nullifiers(&mut self, private_call: PrivateCircuitPublicInputs) { + let nullifiers = private_call.nullifiers; for i in 0..nullifiers.len() { let nullifier = nullifiers[i]; if nullifier.value != 0 { - self.public_inputs.end.nullifiers.push(nullifier.scope(source.storage_contract_address)); + self.public_inputs.end.nullifiers.push(nullifier.scope(private_call.call_context.contract_address)); } } } - fn propagate_l2_to_l1_messages(&mut self, source: DataSource) { - let l2_to_l1_msgs = source.private_call_public_inputs.l2_to_l1_msgs; + fn propagate_l2_to_l1_messages(&mut self, private_call: PrivateCircuitPublicInputs) { + let l2_to_l1_msgs = private_call.l2_to_l1_msgs; for i in 0..l2_to_l1_msgs.len() { let msg = l2_to_l1_msgs[i]; if !is_empty(msg) { - self.public_inputs.end.l2_to_l1_msgs.push(msg.scope(source.storage_contract_address)); + self.public_inputs.end.l2_to_l1_msgs.push(msg.scope(private_call.call_context.contract_address)); } } } - fn propagate_logs(&mut self, source: DataSource) { - let encrypted_logs = source.private_call_public_inputs.encrypted_logs_hashes; + fn propagate_logs(&mut self, private_call: PrivateCircuitPublicInputs) { + let encrypted_logs = private_call.encrypted_logs_hashes; for i in 0..encrypted_logs.len() { let log = encrypted_logs[i]; if !is_empty(log) { - self.public_inputs.end.encrypted_logs_hashes.push(log.scope(source.storage_contract_address)); + self.public_inputs.end.encrypted_logs_hashes.push(log.scope(private_call.call_context.contract_address)); } } - let unencrypted_logs = source.private_call_public_inputs.unencrypted_logs_hashes; + let unencrypted_logs = private_call.unencrypted_logs_hashes; for i in 0..unencrypted_logs.len() { let log = unencrypted_logs[i]; if !is_empty(log) { - self.public_inputs.end.unencrypted_logs_hashes.push(log.scope(source.storage_contract_address)); + self.public_inputs.end.unencrypted_logs_hashes.push(log.scope(private_call.call_context.contract_address)); } } - let note_logs = source.private_call_public_inputs.note_encrypted_logs_hashes; + let note_logs = private_call.note_encrypted_logs_hashes; for i in 0..note_logs.len() { if !is_empty(note_logs[i]) { self.public_inputs.end.note_encrypted_logs_hashes.push(note_logs[i]); @@ -223,8 +209,8 @@ impl PrivateKernelCircuitPublicInputsComposer { } } - fn propagate_private_call_requests(&mut self, source: DataSource) { - let call_requests = source.private_call_public_inputs.private_call_requests; + fn propagate_private_call_requests(&mut self, private_call: PrivateCircuitPublicInputs) { + let call_requests = private_call.private_call_requests; let num_requests = array_length(call_requests); for i in 0..call_requests.len() { if i < num_requests { @@ -235,8 +221,8 @@ impl PrivateKernelCircuitPublicInputsComposer { } } - fn propagate_public_call_requests(&mut self, source: DataSource) { - let call_requests = source.private_call_public_inputs.public_call_requests; + fn propagate_public_call_requests(&mut self, private_call: PrivateCircuitPublicInputs) { + let call_requests = private_call.public_call_requests; for i in 0..call_requests.len() { if !is_empty(call_requests[i]) { self.public_inputs.end.public_call_requests.push(call_requests[i]); @@ -244,8 +230,8 @@ impl PrivateKernelCircuitPublicInputsComposer { } } - fn propagate_public_teardown_call_request(&mut self, source: DataSource) { - let call_request = source.private_call_public_inputs.public_teardown_call_request; + fn propagate_public_teardown_call_request(&mut self, private_call: PrivateCircuitPublicInputs) { + let call_request = private_call.public_teardown_call_request; if !is_empty(call_request) { assert( is_empty(self.public_inputs.public_teardown_call_request), "Public teardown call request already set" @@ -254,10 +240,10 @@ impl PrivateKernelCircuitPublicInputsComposer { } } - fn propagate_fee_payer(&mut self, source: DataSource) { - if (source.private_call_public_inputs.is_fee_payer) { + fn propagate_fee_payer(&mut self, private_call: PrivateCircuitPublicInputs) { + if (private_call.is_fee_payer) { assert(self.public_inputs.fee_payer.is_zero(), "Cannot overwrite non-empty fee_payer"); - self.public_inputs.fee_payer = source.storage_contract_address; + self.public_inputs.fee_payer = private_call.call_context.contract_address; } } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 07804226eda..e915a6c3a62 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -39,16 +39,13 @@ impl PrivateKernelInitCircuitPrivateInputs { } unconstrained fn generate_output(self) -> PrivateKernelCircuitPublicInputs { - let private_call_public_inputs = self.private_call.call_stack_item.public_inputs; + let private_call_public_inputs = self.private_call.public_inputs; PrivateKernelCircuitPublicInputsComposer::new_from_tx_request( self.tx_request, private_call_public_inputs, self.vk_tree_root, self.protocol_contract_tree_root - ).with_private_call( - private_call_public_inputs, - self.private_call.call_stack_item.contract_address - ).finish() + ).with_private_call(private_call_public_inputs).finish() } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { @@ -67,7 +64,7 @@ impl PrivateKernelInitCircuitPrivateInputs { if dep::types::validate::should_validate_output() { PrivateKernelCircuitOutputValidator::new(output).validate_as_first_call( self.tx_request, - self.private_call.call_stack_item.public_inputs, + self.private_call.public_inputs, private_call_data_validator.array_lengths, self.vk_tree_root, self.protocol_contract_tree_root diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index af0f502bee5..ab95790123f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -41,10 +41,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { } unconstrained fn generate_output(self) -> PrivateKernelCircuitPublicInputs { - PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).pop_top_call_request().with_private_call( - self.private_call.call_stack_item.public_inputs, - self.private_call.call_stack_item.contract_address - ).finish() + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).pop_top_call_request().with_private_call(self.private_call.public_inputs).finish() } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { @@ -73,7 +70,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( self.previous_kernel.public_inputs, previous_kernel_array_lengths, - self.private_call.call_stack_item.public_inputs, + self.private_call.public_inputs, private_call_data_validator.array_lengths ); } @@ -107,8 +104,7 @@ mod tests { pub fn execute(&mut self) -> PrivateKernelCircuitPublicInputs { let private_call = self.private_call.to_private_call_data(); - // Update the previous_kernel's private_call_stack with the current call_stack_item. - self.previous_kernel.add_private_call_from_call_stack_item(private_call.call_stack_item); + self.previous_kernel.add_private_call_request_for_private_call(private_call); let previous_kernel = self.previous_kernel.to_private_kernel_data(); let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call }; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr index 640a8061686..07828f8beac 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr @@ -36,11 +36,6 @@ impl PrivateCallDataValidatorBuilder { PrivateCallDataValidatorBuilder { private_call, previous_note_hashes } } - pub fn is_delegate_call(&mut self) -> Self { - let _ = self.private_call.is_delegate_call(); - *self - } - pub fn is_static_call(&mut self) -> Self { let _ = self.private_call.is_static_call(); *self diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr index 18fd98b68f0..96c00667a6d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr @@ -9,15 +9,6 @@ fn validate_against_call_request_succeeds() { builder.validate_against_call_request(request); } -#[test] -fn validate_against_call_request_delegate_call_succeeds() { - let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - - let request = builder.private_call.build_private_call_request(); - - builder.validate_against_call_request(request); -} - #[test] fn validate_against_call_request_static_call_succeeds() { let builder = PrivateCallDataValidatorBuilder::new().is_static_call(); @@ -27,24 +18,13 @@ fn validate_against_call_request_static_call_succeeds() { builder.validate_against_call_request(request); } -#[test(should_fail_with = "contract_address does not match call request")] -fn validate_against_call_request_mismatch_contract_address_fails() { - let builder = PrivateCallDataValidatorBuilder::new(); - - let mut request = builder.private_call.build_private_call_request(); - // Tweak the contract_address to be a different value. - request.contract_address.inner += 1; - - builder.validate_against_call_request(request); -} - #[test(should_fail_with = "call_context does not match call request")] -fn validate_against_call_request_mismatch_call_context_storage_contract_address_fails() { +fn validate_against_call_request_mismatch_call_context_contract_address_fails() { let builder = PrivateCallDataValidatorBuilder::new(); let mut request = builder.private_call.build_private_call_request(); - // Tweak the storage_contract_address to be a different value. - request.call_context.storage_contract_address.inner += 1; + // Tweak the contract_address to be a different value. + request.call_context.contract_address.inner += 1; builder.validate_against_call_request(request); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_tx_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_tx_request.nr index 7833fa33d8e..efcfe126dd6 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_tx_request.nr @@ -9,7 +9,7 @@ fn validate_against_tx_request_succeeds() { builder.validate_against_tx_request(request); } -#[test(should_fail_with = "origin address does not match call stack items contract address")] +#[test(should_fail_with = "contract address does not match origin")] fn validate_against_tx_request_mismatch_contract_address_fails() { let builder = PrivateCallDataValidatorBuilder::new(); @@ -20,7 +20,7 @@ fn validate_against_tx_request_mismatch_contract_address_fails() { builder.validate_against_tx_request(request); } -#[test(should_fail_with = "tx_request function_data must match call_stack_item function_data")] +#[test(should_fail_with = "function_selector in call_context does not match the value in tx_request")] fn validate_against_tx_request_mismatch_function_data_fails() { let builder = PrivateCallDataValidatorBuilder::new(); @@ -31,7 +31,18 @@ fn validate_against_tx_request_mismatch_function_data_fails() { builder.validate_against_tx_request(request); } -#[test(should_fail_with = "noir function args passed to tx_request must match args in the call_stack_item")] +#[test(should_fail_with = "tx_request does not indicate the first function is private")] +fn validate_against_tx_request_public_function_data_fails() { + let builder = PrivateCallDataValidatorBuilder::new(); + + let mut request = builder.private_call.build_tx_request(); + // Tweak the function to be public. + request.function_data.is_private = false; + + builder.validate_against_tx_request(request); +} + +#[test(should_fail_with = "args_hash in private call does not match the value in tx_request")] fn validate_against_tx_request_mismatch_args_hash_fails() { let builder = PrivateCallDataValidatorBuilder::new(); @@ -42,7 +53,7 @@ fn validate_against_tx_request_mismatch_args_hash_fails() { builder.validate_against_tx_request(request); } -#[test(should_fail_with = "tx_context in tx_request must match tx_context in call_stack_item")] +#[test(should_fail_with = "tx_context in private call does not match the value in tx_request")] fn validate_against_tx_request_mismatch_chain_id_fails() { let builder = PrivateCallDataValidatorBuilder::new(); @@ -53,7 +64,7 @@ fn validate_against_tx_request_mismatch_chain_id_fails() { builder.validate_against_tx_request(request); } -#[test(should_fail_with = "tx_context in tx_request must match tx_context in call_stack_item")] +#[test(should_fail_with = "tx_context in private call does not match the value in tx_request")] fn validate_against_tx_request_mismatch_version_fails() { let builder = PrivateCallDataValidatorBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr index c4f40540eef..0ceb0d08072 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr @@ -12,12 +12,6 @@ fn validate_as_first_call_static_call_fails() { builder.validate_as_first_call(); } -#[test(should_fail_with = "Users cannot make a delegatecall")] -fn validate_as_first_call_delegate_call_fails() { - let builder = PrivateCallDataValidatorBuilder::new().is_first_call().is_delegate_call(); - builder.validate_as_first_call(); -} - #[test(should_fail_with = "Users cannot set msg_sender in first call")] fn validate_as_first_call_msg_sender_fails() { let builder = PrivateCallDataValidatorBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr index 6033c3a2450..22504557f46 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr @@ -6,65 +6,12 @@ fn validate_call_is_regular_succeeds() { builder.validate(); } -#[test(should_fail_with = "call stack storage address does not match expected contract address")] -fn validate_call_is_regular_mismatch_storage_contract_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - // Change the storage contract address to be a different value. - builder.private_call.storage_contract_address.inner += 1; - - builder.validate(); -} - -#[test] -fn validate_call_is_delegate_succeeds() { - let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - builder.validate(); -} - -#[test] -fn validate_call_is_delegate_static_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new().is_delegate_call().is_static_call(); - builder.validate(); -} - -#[test(should_fail_with = "current contract address must not match storage contract address for delegate calls")] -fn validate_call_is_delegate_call_from_same_contract_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - - // Change the caller's storage contract address to be the same as the contract address. - builder.private_call.storage_contract_address = builder.private_call.contract_address; - - builder.validate(); -} - -#[test(should_fail_with = "function selector in call context does not match call stack item")] -fn validate_call_mismatch_function_selector_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - let mut data = builder.get_private_call_data(); - // Tweak the function selector in the call context to be different to the one in call stack item. - data.call_stack_item.public_inputs.call_context.function_selector.inner += 1; - - builder.validate_with_private_call_data(data); -} - #[test] fn validate_call_is_static_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); builder.validate(); } -#[test(should_fail_with = "call stack storage address does not match expected contract address")] -fn validate_call_is_static_mismatch_storage_contract_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - - // Change the storage contract address to be a different value. - builder.private_call.storage_contract_address.inner += 1; - - builder.validate(); -} - #[test(should_fail_with = "note_hashes must be empty for static calls")] fn validate_call_is_static_creating_note_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr index ce5bfa52a33..42246ff5b14 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr @@ -12,56 +12,11 @@ fn validate_public_call_requests_succeeds() { builder.validate(); } -#[test] -fn validate_public_call_requests_delegate_call_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_public_call_requests_delegate(2); - - builder.validate(); -} - -#[test] -fn validate_public_call_requests_mix_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_public_call_requests(1); - builder.private_call.append_public_call_requests_delegate(1); - builder.private_call.append_public_call_requests(1); - - builder.validate(); -} - #[test] fn validate_public_call_requests_from_static_call_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.append_public_call_requests(1); - builder.private_call.append_public_call_requests_delegate(1); - builder.private_call.append_public_call_requests(1); - - builder.validate(); -} - -#[test(should_fail_with = "incorrect msg_sender for delegate call request")] -fn validate_public_call_requests_incorrect_msg_sender_for_delegate_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_public_call_requests_delegate(1); - // Change the msg_sender to be the contract address. - builder.private_call.public_call_requests.storage[0].call_context.msg_sender = builder.private_call.contract_address; - - builder.validate(); -} - -#[test(should_fail_with = "incorrect storage_contract_address for delegate call request")] -fn validate_public_call_requests_incorrect_storage_contract_address_for_delegate_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_public_call_requests_delegate(1); - // Change the storage_contract_address to be the target contract address. - let target_contract = builder.private_call.public_call_requests.storage[0].contract_address; - builder.private_call.public_call_requests.storage[0].call_context.storage_contract_address = target_contract; + builder.private_call.append_public_call_requests(2); builder.validate(); } @@ -77,17 +32,6 @@ fn validate_public_call_requests_incorrect_msg_sender_for_regular_call_fails() { builder.validate(); } -#[test(should_fail_with = "incorrect storage_contract_address for call request")] -fn validate_public_call_requests_incorrect_storage_contract_address_for_regular_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_public_call_requests(1); - // Change the storage_contract_address to be the caller's storage contract address. - builder.private_call.public_call_requests.storage[0].call_context.storage_contract_address = builder.private_call.storage_contract_address; - - builder.validate(); -} - #[test(should_fail_with = "static call cannot make non-static calls")] fn validate_public_call_requests_static_call_regular_call_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); @@ -111,15 +55,6 @@ fn validate_teardown_call_request_succeeds() { builder.validate(); } -#[test] -fn validate_teardown_call_request_delegate_call_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.set_public_teardown_call_request_delegate(); - - builder.validate(); -} - #[test] fn validate_teardown_call_request_from_static_call_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); @@ -129,38 +64,6 @@ fn validate_teardown_call_request_from_static_call_succeeds() { builder.validate(); } -#[test] -fn validate_teardown_call_request_delegate_from_static_call_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - - builder.private_call.set_public_teardown_call_request_delegate(); - - builder.validate(); -} - -#[test(should_fail_with = "incorrect msg_sender for delegate call request")] -fn validate_teardown_call_request_incorrect_msg_sender_for_delegate_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.set_public_teardown_call_request_delegate(); - // Change the msg_sender to be the contract address. - builder.private_call.public_teardown_call_request.call_context.msg_sender = builder.private_call.contract_address; - - builder.validate(); -} - -#[test(should_fail_with = "incorrect storage_contract_address for delegate call request")] -fn validate_teardown_call_request_incorrect_storage_contract_address_for_delegate_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.set_public_teardown_call_request_delegate(); - // Change the storage_contract_address to be the target contract address. - let target_contract = builder.private_call.public_teardown_call_request.contract_address; - builder.private_call.public_teardown_call_request.call_context.storage_contract_address = target_contract; - - builder.validate(); -} - #[test(should_fail_with = "incorrect msg_sender for call request")] fn validate_teardown_call_request_incorrect_msg_sender_for_regular_call_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); @@ -172,17 +75,6 @@ fn validate_teardown_call_request_incorrect_msg_sender_for_regular_call_fails() builder.validate(); } -#[test(should_fail_with = "incorrect storage_contract_address for call request")] -fn validate_teardown_call_request_incorrect_storage_contract_address_for_regular_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.set_public_teardown_call_request(); - // Change the storage_contract_address to be the caller's storage contract address. - builder.private_call.public_teardown_call_request.call_context.storage_contract_address = builder.private_call.storage_contract_address; - - builder.validate(); -} - #[test(should_fail_with = "static call cannot make non-static calls")] fn validate_teardown_call_request_static_call_regular_call_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr index 6df1567d3da..5272049cbf3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr @@ -16,12 +16,11 @@ impl PrivateCallDataValidatorBuilder { } #[test(should_fail_with = "contract address cannot be zero")] -fn validate_contract_address_zero_storage_contract_address_fails() { +fn validate_contract_address_zero_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); - // Set (storage) contract_address to 0 + // Set the contract_address to 0. builder.private_call.contract_address = AztecAddress::zero(); - builder.private_call.storage_contract_address = AztecAddress::zero(); builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr index e6f3ca46491..b4d2ecbf1a2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr @@ -28,56 +28,11 @@ fn validate_private_call_requests_succeeds() { builder.validate(); } -#[test] -fn validate_private_call_requests_delegate_call_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests_delegate(2); - - builder.validate(); -} - -#[test] -fn validate_private_call_requests_mix_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(1); - builder.private_call.append_private_call_requests_delegate(1); - builder.private_call.append_private_call_requests(1); - - builder.validate(); -} - #[test] fn validate_private_call_requests_from_static_call_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.append_private_call_requests(1); - builder.private_call.append_private_call_requests_delegate(1); - builder.private_call.append_private_call_requests(1); - - builder.validate(); -} - -#[test(should_fail_with = "incorrect msg_sender for delegate call request")] -fn validate_private_call_requests_incorrect_msg_sender_for_delegate_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests_delegate(1); - // Change the msg_sender to be the contract address. - builder.private_call.private_call_requests.storage[0].call_context.msg_sender = builder.private_call.contract_address; - - builder.validate(); -} - -#[test(should_fail_with = "incorrect storage_contract_address for delegate call request")] -fn validate_private_call_requests_incorrect_storage_contract_address_for_delegate_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests_delegate(1); - // Change the storage_contract_address to be the target contract address. - let target_contract = builder.private_call.private_call_requests.storage[0].contract_address; - builder.private_call.private_call_requests.storage[0].call_context.storage_contract_address = target_contract; + builder.private_call.append_private_call_requests(2); builder.validate(); } @@ -93,17 +48,6 @@ fn validate_private_call_requests_incorrect_msg_sender_for_regular_call_fails() builder.validate(); } -#[test(should_fail_with = "incorrect storage_contract_address for call request")] -fn validate_private_call_requests_incorrect_storage_contract_address_for_regular_call_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(1); - // Change the storage_contract_address to be the caller's storage contract address. - builder.private_call.private_call_requests.storage[0].call_context.storage_contract_address = builder.private_call.storage_contract_address; - - builder.validate(); -} - #[test(should_fail_with = "static call cannot make non-static calls")] fn validate_private_call_requests_static_call_regular_call_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr index 31adcefa0bd..d806bd4e0dc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr @@ -54,11 +54,11 @@ impl PrivateKernelCircuitOutputValidatorBuilder { pub fn validate_as_first_call(self) { let private_call = self.private_call.to_private_call_data(); - let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.public_inputs); let output = self.output.to_private_kernel_circuit_public_inputs(); PrivateKernelCircuitOutputValidator::new(output).validate_as_first_call( self.tx_request, - private_call.call_stack_item.public_inputs, + private_call.public_inputs, array_lengths, FixtureBuilder::vk_tree_root(), self.private_call.protocol_contract_tree_root @@ -74,12 +74,12 @@ impl PrivateKernelCircuitOutputValidatorBuilder { let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(previous_kernel); let private_call = self.private_call.to_private_call_data(); - let private_call_array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); + let private_call_array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.public_inputs); let output = self.output.to_private_kernel_circuit_public_inputs(); PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( previous_kernel, previous_kernel_array_lengths, - private_call.call_stack_item.public_inputs, + private_call.public_inputs, private_call_array_lengths ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr index a61407d9819..9eb024dcb70 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr @@ -274,7 +274,8 @@ fn validate_aggregated_values_fee_payer_from_private_call_mismatch_fails() { fn validate_aggregated_values_fee_payer_random_output_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.output.set_fee_payer(builder.private_call.storage_contract_address); + // Set the fee payer while the private call is not made the fee payer. + builder.output.set_fee_payer(builder.private_call.contract_address); builder.validate_as_inner_call(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr index a87989e010d..424f2eada3e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr @@ -46,10 +46,7 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { pub fn compose_from_tx_request(self) -> PrivateKernelCircuitPublicInputs { let private_call = self.private_call.to_private_call_data(); - self.new_from_tx_request().with_private_call( - private_call.call_stack_item.public_inputs, - private_call.call_stack_item.contract_address - ).finish() + self.new_from_tx_request().with_private_call(private_call.public_inputs).finish() } pub fn compose_from_previous_kernel(self) -> PrivateKernelCircuitPublicInputs { @@ -61,9 +58,6 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { let private_call = self.private_call.to_private_call_data(); - PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel).pop_top_call_request().with_private_call( - private_call.call_stack_item.public_inputs, - private_call.call_stack_item.contract_address - ).finish() + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel).pop_top_call_request().with_private_call(private_call.public_inputs).finish() } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr index 3859b81383e..3e8725df2e1 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr @@ -21,18 +21,18 @@ impl PreviousKernelValidator { pub fn validate_phase(self, phase: u8) { let public_inputs = self.previous_kernel.public_inputs; - let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0].contract_address.is_zero(); + let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0].call_context.contract_address.is_zero(); if phase == PublicKernelPhase.SETUP { assert_eq(needs_setup, true, "Cannot run unnecessary setup circuit"); } - let needs_app_logic = !public_inputs.end.public_call_stack[0].contract_address.is_zero(); + let needs_app_logic = !public_inputs.end.public_call_stack[0].call_context.contract_address.is_zero(); if phase == PublicKernelPhase.APP_LOGIC { assert_eq(needs_setup, false, "Cannot run app logic circuit before setup circuit"); assert_eq(needs_app_logic, true, "Cannot run unnecessary app logic circuit"); } - let needs_teardown = !public_inputs.public_teardown_call_request.contract_address.is_zero(); + let needs_teardown = !public_inputs.public_teardown_call_request.call_context.contract_address.is_zero(); if phase == PublicKernelPhase.TEARDOWN { assert_eq(needs_setup, false, "Cannot run teardown circuit before setup circuit"); assert_eq(needs_app_logic, false, "Cannot run teardown circuit before app logic circuit"); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_call_data_validator.nr deleted file mode 100644 index 0969265f3dd..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_call_data_validator.nr +++ /dev/null @@ -1,186 +0,0 @@ -use crate::public_kernel_phase::PublicKernelPhase; -use dep::types::{ - abis::{ - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, public_call_data::PublicCallData, - public_call_request::PublicCallRequest -}, - constants::MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, utils::arrays::array_length -}; - -pub struct PublicCallDataValidator { - data: PublicCallData, - phase: u8, -} - -impl PublicCallDataValidator { - pub fn new(data: PublicCallData, phase: u8) -> Self { - PublicCallDataValidator { data, phase } - } - - pub fn validate(self) { - self.validate_common_inputs(); - self.validate_revert_code(); - self.validate_call(); - self.validate_call_requests(); - } - - pub fn validate_against_previous_kernel(self, previous_kernel: PublicKernelCircuitPublicInputs) { - self.validate_global_variables(previous_kernel); - self.validate_start_gas(previous_kernel); - self.validate_transaction_fee(previous_kernel); - self.validate_against_call_request(previous_kernel); - } - - fn validate_common_inputs(self) { - let call_stack_item = self.data.call_stack_item; - assert(!call_stack_item.contract_address.is_zero(), "Contract address cannot be zero"); - assert(call_stack_item.function_data.selector.to_field() != 0, "Function signature cannot be zero"); - assert_eq( - call_stack_item.function_data.is_private, false, "Cannot execute a private function with the public kernel circuit" - ); - assert_eq( - call_stack_item.function_data.selector, call_stack_item.public_inputs.call_context.function_selector, "function selector in call context does not match call stack item" - ); - assert(self.data.bytecode_hash != 0, "Bytecode hash cannot be zero"); - } - - fn validate_revert_code(self) { - if self.phase == PublicKernelPhase.SETUP { - assert_eq(self.data.call_stack_item.public_inputs.revert_code, 0, "Public call cannot be reverted"); - } - } - - fn validate_call(self) { - let call_stack_item = self.data.call_stack_item; - let public_inputs = call_stack_item.public_inputs; - - let call_context = public_inputs.call_context; - if call_context.is_delegate_call { - assert( - !call_stack_item.contract_address.eq(call_context.storage_contract_address), "curent contract address must not match storage contract address for delegate calls" - ); - } else { - assert( - call_context.storage_contract_address.eq(call_stack_item.contract_address), "call stack storage address does not match expected contract address" - ); - } - - if call_context.is_static_call { - // No state changes are allowed for static calls: - let note_hashes_length = array_length(public_inputs.note_hashes); - assert(note_hashes_length == 0, "note_hashes must be empty for static calls"); - - let nullifiers_length = array_length(public_inputs.nullifiers); - assert(nullifiers_length == 0, "nullifiers must be empty for static calls"); - - let update_requests_length = array_length(public_inputs.contract_storage_update_requests); - assert( - update_requests_length == 0, "No contract storage update requests are allowed for static calls" - ); - - let l2_to_l1_msgs_length = array_length(public_inputs.l2_to_l1_msgs); - assert(l2_to_l1_msgs_length == 0, "l2_to_l1_msgs must be empty for static calls"); - - let new_unencrypted_logs_length = array_length(public_inputs.unencrypted_logs_hashes); - assert(new_unencrypted_logs_length == 0, "No unencrypted logs are allowed for static calls"); - } - } - - fn validate_call_requests(self) { - let call_requests = self.data.call_stack_item.public_inputs.public_call_requests; - let this_context = self.data.call_stack_item.public_inputs.call_context; - for i in 0..call_requests.len() { - let request = call_requests[i]; - if !request.item.contract_address.is_zero() { - let target_context = request.item.call_context; - let target_contract = request.item.contract_address; - - if target_context.is_delegate_call { - assert_eq( - target_context.msg_sender, this_context.msg_sender, "incorrect msg_sender for delegate call request" - ); - assert_eq( - target_context.storage_contract_address, this_context.storage_contract_address, "incorrect storage_contract_address for delegate call request" - ); - } else { - assert_eq( - target_context.msg_sender, this_context.storage_contract_address, "incorrect msg_sender for call request" - ); - assert_eq( - target_context.storage_contract_address, target_contract, "incorrect storage_contract_address for call request" - ); - } - if !target_context.is_static_call { - assert(this_context.is_static_call == false, "static call cannot make non-static calls"); - } - } - } - } - - fn validate_against_call_request(self, previous_kernel: PublicKernelCircuitPublicInputs) { - let call_stack = if self.phase == PublicKernelPhase.SETUP { - previous_kernel.end_non_revertible.public_call_stack - } else if self.phase == PublicKernelPhase.APP_LOGIC { - previous_kernel.end.public_call_stack - } else if self.phase == PublicKernelPhase.TEARDOWN { - previous_kernel.public_teardown_call_stack - } else { - panic(f"Unknown phase") - }; - - let call_request = call_stack[array_length(call_stack) - 1]; - assert( - self.data.call_stack_item.get_compressed() == call_request.item, "call stack item does not match item at the top of the call stack" - ); - } - - fn validate_global_variables(self, previous_kernel: PublicKernelCircuitPublicInputs) { - let prev_global_variables = previous_kernel.constants.global_variables; - if !prev_global_variables.is_empty() { // It's empty when the previous kernel is from private_kernel_tail_to_pubic. - let public_call_globals = self.data.call_stack_item.public_inputs.global_variables; - assert_eq( - public_call_globals, prev_global_variables, "Global variables injected into the public call do not match constants" - ); - } - } - - // Validates that the start gas injected into the app circuit matches the remaining gas. - fn validate_start_gas(self, previous_kernel: PublicKernelCircuitPublicInputs) { - // If this is a nested call (not an execution request), the start gas is correct as long as the - // call being processed by this kernel iteration matches the call at the top of the callstack - // as per the previous kernel's outputs. - // An execution request's start gas is the remaining gas left in the transaction after the previous kernel. - // A nested call's start gas is the gas allocated to it by its caller and placed in the callstack. - if self.data.call_stack_item.is_execution_request { - let public_call_start_gas = self.data.call_stack_item.public_inputs.start_gas_left; - if self.phase != PublicKernelPhase.TEARDOWN { - let tx_gas_limits = previous_kernel.constants.tx_context.gas_settings.gas_limits; - let computed_start_gas = tx_gas_limits.sub(previous_kernel.end.gas_used).sub(previous_kernel.end_non_revertible.gas_used); - assert_eq( - public_call_start_gas, computed_start_gas, "Start gas for public phase does not match transaction gas left" - ); - } else { - let teardown_gas_limit = previous_kernel.constants.tx_context.gas_settings.teardown_gas_limits; - assert_eq( - public_call_start_gas, teardown_gas_limit, "Start gas for teardown phase does not match teardown gas allocation" - ); - } - } - } - - fn validate_transaction_fee(self, previous_kernel: PublicKernelCircuitPublicInputs) { - let transaction_fee = self.data.call_stack_item.public_inputs.transaction_fee; - if self.phase != PublicKernelPhase.TEARDOWN { - assert_eq(transaction_fee, 0, "Transaction fee must be zero on setup and app phases"); - } else { - // Note that teardown_gas is already included in end.gas_used as it was injected by the private kernel - let total_gas_used = previous_kernel.end.gas_used + previous_kernel.end_non_revertible.gas_used; - let block_gas_fees = self.data.call_stack_item.public_inputs.global_variables.gas_fees; - let inclusion_fee = previous_kernel.constants.tx_context.gas_settings.inclusion_fee; - let computed_transaction_fee = total_gas_used.compute_fee(block_gas_fees) + inclusion_fee; - assert( - transaction_fee == computed_transaction_fee, "Transaction fee on teardown phase does not match expected value" - ); - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr index eddc54ea0c2..a982e37d4f6 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr @@ -91,7 +91,7 @@ impl VMCircuitOutputComposer { fn propagate_validation_requests(&mut self, public_call: PublicCircuitPublicInputs) { // Note that the public kernel cannot modify the max block number value - it simply forwards it to the rollup - let storage_contract_address = public_call.call_context.storage_contract_address; + let contract_address = public_call.call_context.contract_address; let note_hash_read_requests = public_call.note_hash_read_requests; for i in 0..note_hash_read_requests.len() { @@ -105,7 +105,7 @@ impl VMCircuitOutputComposer { for i in 0..nullifier_read_requests.len() { let request = nullifier_read_requests[i]; if !is_empty(request) { - self.validation_requests.nullifier_read_requests.push(request.scope(storage_contract_address)); + self.validation_requests.nullifier_read_requests.push(request.scope(contract_address)); } } @@ -113,7 +113,7 @@ impl VMCircuitOutputComposer { for i in 0..nullifier_non_existent_read_requests.len() { let request = nullifier_non_existent_read_requests[i]; if !is_empty(request) { - self.validation_requests.nullifier_non_existent_read_requests.push(request.scope(storage_contract_address)); + self.validation_requests.nullifier_non_existent_read_requests.push(request.scope(contract_address)); } } @@ -129,7 +129,7 @@ impl VMCircuitOutputComposer { for i in 0..read_requests.len() { let read_request = read_requests[i]; if !is_empty(read_request) { - self.validation_requests.public_data_reads.push(PublicDataRead::from_contract_storage_read(storage_contract_address, read_request)); + self.validation_requests.public_data_reads.push(PublicDataRead::from_contract_storage_read(contract_address, read_request)); } } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr index b1d6c05a13b..1c396c03eb8 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr @@ -20,23 +20,23 @@ pub fn propagate_accumulated_data( } fn propagate_note_hashes(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { - let storage_contract_address = public_call.call_context.storage_contract_address; + let contract_address = public_call.call_context.contract_address; let note_hashes = public_call.note_hashes; for i in 0..note_hashes.len() { let note_hash = note_hashes[i]; if note_hash.counter != 0 { - data.note_hashes.push(note_hash.scope(storage_contract_address)); + data.note_hashes.push(note_hash.scope(contract_address)); } } } fn propagate_nullifiers(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { - let storage_contract_address = public_call.call_context.storage_contract_address; + let contract_address = public_call.call_context.contract_address; let nullifiers = public_call.nullifiers; for i in 0..nullifiers.len() { let nullifier = nullifiers[i]; if nullifier.counter != 0 { - let siloed_value = compute_siloed_nullifier(storage_contract_address, nullifier.value); + let siloed_value = compute_siloed_nullifier(contract_address, nullifier.value); data.nullifiers.push( Nullifier { value: siloed_value, counter: nullifier.counter, note_hash: nullifier.note_hash } ); @@ -45,36 +45,34 @@ fn propagate_nullifiers(data: &mut PublicAccumulatedDataBuilder, public_call: Pu } fn propagate_l2_to_l1_messages(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { - let storage_contract_address = public_call.call_context.storage_contract_address; + let contract_address = public_call.call_context.contract_address; let msgs = public_call.l2_to_l1_msgs; for i in 0..msgs.len() { let msg = msgs[i]; if msg.counter != 0 { - data.l2_to_l1_msgs.push(msg.scope(storage_contract_address)); + data.l2_to_l1_msgs.push(msg.scope(contract_address)); } } } fn propagate_unencrypted_logs(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { - let storage_contract_address = public_call.call_context.storage_contract_address; + let contract_address = public_call.call_context.contract_address; let logs = public_call.unencrypted_logs_hashes; for i in 0..logs.len() { let log = logs[i]; if log.counter != 0 { - data.unencrypted_logs_hashes.push(log.scope(storage_contract_address)); + data.unencrypted_logs_hashes.push(log.scope(contract_address)); } } } fn propagate_public_data_writes(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { - let storage_contract_address = public_call.call_context.storage_contract_address; + let contract_address = public_call.call_context.contract_address; let writes = public_call.contract_storage_update_requests; for i in 0..writes.len() { let write = writes[i]; if write.counter != 0 { - data.public_data_update_requests.push( - PublicDataUpdateRequest::from_contract_storage_update_request(storage_contract_address, write) - ); + data.public_data_update_requests.push(PublicDataUpdateRequest::from_contract_storage_update_request(contract_address, write)); } } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr index eaff4176460..228fac8f1fc 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr @@ -14,6 +14,6 @@ pub struct PublicKernelInnerCircuitPrivateInputs { impl PublicKernelInnerCircuitPrivateInputs { fn execute(self) -> VMCircuitPublicInputs { - VMCircuitOutputComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).propagate_from_public_call(self.public_call.call_stack_item.public_inputs).finish() + VMCircuitOutputComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).propagate_from_public_call(self.public_call.public_inputs).finish() } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr index a127809b853..8e8d6344835 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr @@ -36,8 +36,8 @@ impl PublicKernelMergeCircuitPrivateInputs { fn get_phase(self) -> u8 { let public_inputs = self.previous_kernel.public_inputs; - let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0].contract_address.is_zero(); - let needs_app_logic = !public_inputs.end.public_call_stack[0].contract_address.is_zero(); + let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0].call_context.contract_address.is_zero(); + let needs_app_logic = !public_inputs.end.public_call_stack[0].call_context.contract_address.is_zero(); if needs_setup { PublicKernelPhase.SETUP } else if needs_app_logic { diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr index ce2e6b62a9a..1cadbea00b6 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr @@ -275,10 +275,7 @@ mod tests { pub fn read_non_existent_nullifier(&mut self, unsiloed_nullifier: Field) { self.previous_kernel.add_non_existent_read_request_for_nullifier(unsiloed_nullifier); self.sync_counters(); - let siloed_nullifier = compute_siloed_nullifier( - self.previous_kernel.storage_contract_address, - unsiloed_nullifier - ); + let siloed_nullifier = compute_siloed_nullifier(self.previous_kernel.contract_address, unsiloed_nullifier); self.nullifier_non_existent_read_request_hints_builder.add_value_read(siloed_nullifier); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr index 64da68a2ac5..83cddfbd6cb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr @@ -6,9 +6,8 @@ use crate::{ // docs:start:call-context pub struct CallContext { msg_sender: AztecAddress, - storage_contract_address: AztecAddress, + contract_address: AztecAddress, function_selector: FunctionSelector, - is_delegate_call: bool, is_static_call: bool, } // docs:end:call-context @@ -16,9 +15,8 @@ pub struct CallContext { impl Eq for CallContext { fn eq(self, other: CallContext) -> bool { (self.msg_sender == other.msg_sender) - & (self.storage_contract_address == other.storage_contract_address) + & (self.contract_address == other.contract_address) & (self.function_selector == other.function_selector) - & (self.is_delegate_call == other.is_delegate_call) & (self.is_static_call == other.is_static_call) } } @@ -28,9 +26,8 @@ impl Serialize for CallContext { let mut serialized: BoundedVec = BoundedVec::new(); serialized.push(self.msg_sender.to_field()); - serialized.push(self.storage_contract_address.to_field()); + serialized.push(self.contract_address.to_field()); serialized.push(self.function_selector.to_field()); - serialized.push(self.is_delegate_call as Field); serialized.push(self.is_static_call as Field); serialized.storage @@ -42,9 +39,8 @@ impl Deserialize for CallContext { let mut reader = Reader::new(serialized); CallContext { msg_sender: AztecAddress::from_field(reader.read()), - storage_contract_address: AztecAddress::from_field(reader.read()), + contract_address: AztecAddress::from_field(reader.read()), function_selector: FunctionSelector::from_field(reader.read()), - is_delegate_call: reader.read() as bool, is_static_call: reader.read() as bool } } @@ -54,9 +50,8 @@ impl Empty for CallContext { fn empty() -> Self { CallContext { msg_sender: AztecAddress::empty(), - storage_contract_address: AztecAddress::empty(), + contract_address: AztecAddress::empty(), function_selector: FunctionSelector::empty(), - is_delegate_call: false, is_static_call: false } } @@ -75,9 +70,6 @@ fn test_eq() { let mut context1 = CallContext::empty(); let mut context2 = CallContext::empty(); - context1.is_delegate_call = true; - context2.is_delegate_call = true; - let address: AztecAddress = AztecAddress::from_field(69420); context1.msg_sender = address; context2.msg_sender = address; @@ -90,9 +82,6 @@ fn not_eq_test_eq() { let mut context1 = CallContext::empty(); let mut context2 = CallContext::empty(); - context1.is_delegate_call = true; - context2.is_delegate_call = false; - let address1: AztecAddress = AztecAddress::from_field(69420); let address2: AztecAddress = AztecAddress::from_field(42069); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/mod.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/mod.nr index 63bad5f2baa..6669bfeee5c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/mod.nr @@ -35,9 +35,7 @@ mod public_kernel_data; mod public_kernel_inner_data; mod private_call_request; -mod private_call_stack_item; mod public_call_request; -mod public_call_stack_item; mod public_call_stack_item_compressed; mod public_inner_call_request; mod call_context; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr index d682d3be4ff..e9953d474cb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr @@ -1,11 +1,10 @@ use crate::{ - abis::{call_context::CallContext, side_effect::{Ordered, RangeOrdered}}, address::AztecAddress, + abis::{call_context::CallContext, side_effect::{Ordered, RangeOrdered}}, constants::PRIVATE_CALL_REQUEST_LENGTH, traits::{Empty, Serialize, Deserialize}, utils::reader::Reader }; pub struct PrivateCallRequest { - contract_address: AztecAddress, call_context: CallContext, args_hash: Field, returns_hash: Field, @@ -30,8 +29,7 @@ impl RangeOrdered for PrivateCallRequest { impl Eq for PrivateCallRequest { fn eq(self, other: PrivateCallRequest) -> bool { - (self.contract_address == other.contract_address) - & (self.call_context == other.call_context) + (self.call_context == other.call_context) & (self.args_hash == other.args_hash) & (self.returns_hash == other.returns_hash) & (self.start_side_effect_counter == other.start_side_effect_counter) @@ -42,7 +40,6 @@ impl Eq for PrivateCallRequest { impl Empty for PrivateCallRequest { fn empty() -> Self { PrivateCallRequest { - contract_address: AztecAddress::empty(), call_context: CallContext::empty(), args_hash: 0, returns_hash: 0, @@ -56,7 +53,6 @@ impl Serialize for PrivateCallRequest { fn serialize(self) -> [Field; PRIVATE_CALL_REQUEST_LENGTH] { let mut fields: BoundedVec = BoundedVec::new(); - fields.push(self.contract_address.to_field()); fields.extend_from_array(self.call_context.serialize()); fields.push(self.args_hash); fields.push(self.returns_hash); @@ -73,7 +69,6 @@ impl Deserialize for PrivateCallRequest { fn deserialize(fields: [Field; PRIVATE_CALL_REQUEST_LENGTH]) -> PrivateCallRequest { let mut reader = Reader::new(fields); let item = PrivateCallRequest { - contract_address: reader.read_struct(AztecAddress::deserialize), call_context: reader.read_struct(CallContext::deserialize), args_hash: reader.read(), returns_hash: reader.read(), diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr deleted file mode 100644 index fdfd943522d..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr +++ /dev/null @@ -1,83 +0,0 @@ -use crate::{ - abis::{function_data::FunctionData, private_circuit_public_inputs::PrivateCircuitPublicInputs}, - address::AztecAddress, constants::PRIVATE_CALL_STACK_ITEM_LENGTH, - traits::{Deserialize, Serialize, Empty}, utils::reader::Reader -}; - -pub struct PrivateCallStackItem { - // This is the _actual_ contract address relating to where this function's code resides in the - // contract tree. Regardless of whether this is a call or delegatecall, this - // `contract_address` _does not change_. Amongst other things, it's used as a lookup for - // getting the correct code from the tree. There is a separate `storage_contract_address` - // within a CallStackItem which varies depending on whether this is a call or delegatecall. - contract_address: AztecAddress, - function_data: FunctionData, - public_inputs: PrivateCircuitPublicInputs, -} - -pub struct PrivateCallStackItemWithoutPublicInputs { - contract_address: AztecAddress, - function_data: FunctionData, -} - -impl PrivateCallStackItemWithoutPublicInputs { - fn to_private_call_stack_item(self, public_inputs: PrivateCircuitPublicInputs) -> PrivateCallStackItem { - PrivateCallStackItem { contract_address: self.contract_address, function_data: self.function_data, public_inputs } - } -} - -impl Eq for PrivateCallStackItem { - fn eq(self, other: Self) -> bool { - self.contract_address.eq(other.contract_address) - & self.function_data.eq(other.function_data) - & self.public_inputs.eq(other.public_inputs) - } -} - -impl Serialize for PrivateCallStackItem { - fn serialize(self) -> [Field; PRIVATE_CALL_STACK_ITEM_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(); - - fields.push(self.contract_address.to_field()); - fields.extend_from_array(self.function_data.serialize()); - fields.extend_from_array(self.public_inputs.serialize()); - - assert_eq(fields.len(), PRIVATE_CALL_STACK_ITEM_LENGTH); - - fields.storage - } -} - -impl Deserialize for PrivateCallStackItem { - fn deserialize(serialized: [Field; PRIVATE_CALL_STACK_ITEM_LENGTH]) -> Self { - // TODO(#4390): This should accept a reader ^ to avoid copying data. - let mut reader = Reader::new(serialized); - - let item = Self { - contract_address: reader.read_struct(AztecAddress::deserialize), - function_data: reader.read_struct(FunctionData::deserialize), - public_inputs: reader.read_struct(PrivateCircuitPublicInputs::deserialize) - }; - - reader.finish(); - item - } -} - -impl Empty for PrivateCallStackItem { - fn empty() -> Self { - PrivateCallStackItem { - contract_address: AztecAddress::empty(), - function_data: FunctionData::empty(), - public_inputs: PrivateCircuitPublicInputs::empty() - } - } -} - -#[test] -fn serialization_of_empty() { - let item = PrivateCallStackItem::empty(); - let serialized = item.serialize(); - let deserialized = PrivateCallStackItem::deserialize(serialized); - assert(item.eq(deserialized)); -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr index d10c9e98887..d88b790a711 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr @@ -1,15 +1,12 @@ use crate::{ - abis::{ - private_call_stack_item::{PrivateCallStackItemWithoutPublicInputs, PrivateCallStackItem}, - private_circuit_public_inputs::PrivateCircuitPublicInputs -}, - address::{SaltedInitializationHash, PublicKeysHash}, public_keys::PublicKeys, + abis::{private_circuit_public_inputs::PrivateCircuitPublicInputs}, + address::SaltedInitializationHash, public_keys::PublicKeys, constants::{FUNCTION_TREE_HEIGHT, PROTOCOL_CONTRACT_TREE_HEIGHT}, merkle_tree::membership::MembershipWitness, recursion::{verification_key::ClientIVCVerificationKey} }; pub struct PrivateCallData { - call_stack_item: PrivateCallStackItem, + public_inputs: PrivateCircuitPublicInputs, vk: ClientIVCVerificationKey, @@ -24,8 +21,6 @@ pub struct PrivateCallData { } pub struct PrivateCallDataWithoutPublicInputs { - call_stack_item: PrivateCallStackItemWithoutPublicInputs, - vk: ClientIVCVerificationKey, salted_initialization_hash: SaltedInitializationHash, @@ -41,7 +36,7 @@ pub struct PrivateCallDataWithoutPublicInputs { impl PrivateCallDataWithoutPublicInputs { pub fn to_private_call_data(self, public_inputs: PrivateCircuitPublicInputs) -> PrivateCallData { PrivateCallData { - call_stack_item: self.call_stack_item.to_private_call_stack_item(public_inputs), + public_inputs, vk: self.vk, salted_initialization_hash: self.salted_initialization_hash, public_keys: self.public_keys, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_data.nr index 16a1099a399..1404e3ba1e9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_data.nr @@ -1,11 +1,11 @@ -use crate::abis::public_call_stack_item::PublicCallStackItem; +use crate::abis::public_circuit_public_inputs::PublicCircuitPublicInputs; // Mocked here as the only remaining non-recursive proof pub struct Proof {} // TODO(#7124): To be deprecated. pub struct PublicCallData { - call_stack_item: PublicCallStackItem, + public_inputs: PublicCircuitPublicInputs, proof: Proof, bytecode_hash: Field, } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr index 7a1eaf96265..f7a12a6c949 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr @@ -5,7 +5,6 @@ use crate::{ }; pub struct PublicCallRequest { - contract_address: AztecAddress, call_context: CallContext, args_hash: Field, counter: u32, @@ -19,8 +18,7 @@ impl Ordered for PublicCallRequest { impl Eq for PublicCallRequest { fn eq(self, other: PublicCallRequest) -> bool { - (self.contract_address == other.contract_address) - & (self.call_context == other.call_context) + (self.call_context == other.call_context) & (self.args_hash == other.args_hash) & (self.counter == other.counter) } @@ -28,18 +26,13 @@ impl Eq for PublicCallRequest { impl Empty for PublicCallRequest { fn empty() -> Self { - PublicCallRequest { contract_address: AztecAddress::empty(), call_context: CallContext::empty(), args_hash: 0, counter: 0 } + PublicCallRequest { call_context: CallContext::empty(), args_hash: 0, counter: 0 } } } impl PublicCallRequest { pub fn expose_to_public(self) -> Self { - PublicCallRequest { - contract_address: self.contract_address, - call_context: self.call_context, - args_hash: self.args_hash, - counter: 0 - } + PublicCallRequest { call_context: self.call_context, args_hash: self.args_hash, counter: 0 } } } @@ -47,7 +40,6 @@ impl Serialize for PublicCallRequest { fn serialize(self) -> [Field; PUBLIC_CALL_REQUEST_LENGTH] { let mut fields: BoundedVec = BoundedVec::new(); - fields.push(self.contract_address.to_field()); fields.extend_from_array(self.call_context.serialize()); fields.push(self.args_hash); fields.push(self.counter as Field); @@ -63,7 +55,6 @@ impl Deserialize for PublicCallRequest { let mut reader = Reader::new(fields); let request = PublicCallRequest { - contract_address: reader.read_struct(AztecAddress::deserialize), call_context: reader.read_struct(CallContext::deserialize), args_hash: reader.read(), counter: reader.read_u32() diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr deleted file mode 100644 index 5a8d9301233..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr +++ /dev/null @@ -1,9 +0,0 @@ -use crate::abis::{function_data::FunctionData, public_circuit_public_inputs::PublicCircuitPublicInputs}; -use crate::address::AztecAddress; - -// TODO(#7124): To be deprecated. -pub struct PublicCallStackItem { - contract_address: AztecAddress, - public_inputs: PublicCircuitPublicInputs, - function_data: FunctionData, -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 673e442514f..c67be9e038a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -226,7 +226,7 @@ global AZTEC_ADDRESS_LENGTH: u32 = 1; global GAS_FEES_LENGTH: u32 = 2; global GAS_LENGTH: u32 = 2; global GAS_SETTINGS_LENGTH: u32 = GAS_LENGTH * 2 + GAS_FEES_LENGTH + /* inclusion_fee */ 1; -global CALL_CONTEXT_LENGTH: u32 = 5; +global CALL_CONTEXT_LENGTH: u32 = 4; global CONTENT_COMMITMENT_LENGTH: u32 = 4; global CONTRACT_INSTANCE_LENGTH: u32 = 16; global CONTRACT_STORAGE_READ_LENGTH: u32 = 3; @@ -256,8 +256,8 @@ global SCOPED_NOTE_HASH_LENGTH: u32 = NOTE_HASH_LENGTH + 1; global NULLIFIER_LENGTH: u32 = 3; global SCOPED_NULLIFIER_LENGTH: u32 = NULLIFIER_LENGTH + 1; global PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH: u32 = AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + 3 + 2 * GAS_LENGTH; -global PRIVATE_CALL_REQUEST_LENGTH: u32 = AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + 4; -global PUBLIC_CALL_REQUEST_LENGTH: u32 = AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + 1 /* args_hash */ + 1 /* counter */; +global PRIVATE_CALL_REQUEST_LENGTH: u32 = CALL_CONTEXT_LENGTH + 4; +global PUBLIC_CALL_REQUEST_LENGTH: u32 = CALL_CONTEXT_LENGTH + 1 /* args_hash */ + 1 /* counter */; global PUBLIC_INNER_CALL_REQUEST_LENGTH: u32 = PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH + 1 /* counter */; global ROLLUP_VALIDATION_REQUESTS_LENGTH: u32 = MAX_BLOCK_NUMBER_LENGTH; global STATE_REFERENCE_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; @@ -267,7 +267,6 @@ global TOTAL_FEES_LENGTH: u32 = 1; global HEADER_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH + TOTAL_FEES_LENGTH; global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + 4 + MAX_BLOCK_NUMBER_LENGTH + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH * MAX_KEY_VALIDATION_REQUESTS_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_CALL) + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL) + (PUBLIC_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) + PUBLIC_CALL_REQUEST_LENGTH + (L2_TO_L1_MESSAGE_LENGTH * MAX_L2_TO_L1_MSGS_PER_CALL) + 2 + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) + (ENCRYPTED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + HEADER_LENGTH + TX_CONTEXT_LENGTH; global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + /*argsHash + returnsHash*/ 2 + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL) + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL) + (PUBLIC_INNER_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_CALL) + (L2_TO_L1_MESSAGE_LENGTH * MAX_L2_TO_L1_MSGS_PER_CALL) + 2 + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + AZTEC_ADDRESS_LENGTH + /* revert_code */ 1 + 2 * GAS_LENGTH + /* transaction_fee */ 1; -global PRIVATE_CALL_STACK_ITEM_LENGTH: u32 = AZTEC_ADDRESS_LENGTH + FUNCTION_DATA_LENGTH + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH; global PRIVATE_CONTEXT_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + HEADER_LENGTH + TX_CONTEXT_LENGTH + 1; global PUBLIC_CONTEXT_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + GAS_LENGTH + 2; global FEE_RECIPIENT_LENGTH: u32 = 2; @@ -416,10 +415,7 @@ global MEM_TAG_U128 = 6; // AVM CIRCUIT - PUBLIC KERNEL INPUTS COLUMN OFFSETS // Keep the number of offsets aligned with KERNEL_INPUTS_LENGTH defined in constants.hpp global SENDER_KERNEL_INPUTS_COL_OFFSET: u32 = 0; -// "address" actually does not exist in PublicCircuitPublicInputs, -// so this is just an alias to "storage address" for now global ADDRESS_KERNEL_INPUTS_COL_OFFSET: u32 = 1; -global STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET: u32 = ADDRESS_KERNEL_INPUTS_COL_OFFSET; global FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET: u32 = 2; global IS_STATIC_CALL_KERNEL_INPUTS_COL_OFFSET: u32 = 3; // Global Variables @@ -493,7 +489,6 @@ global AVM_SENDL2TOL1MSG_BASE_L2_GAS: u32 = 26 + L2_GAS_PER_L2_TO_L1_MSG; // On CALL, AVM performs nullifier checks for contract address & contract class ID global AVM_CALL_BASE_L2_GAS: u32 = 45 + (2 * L2_GAS_PER_NULLIFIER_READ_REQUEST); global AVM_STATICCALL_BASE_L2_GAS: u32 = 45 + (2 * L2_GAS_PER_NULLIFIER_READ_REQUEST); -global AVM_DELEGATECALL_BASE_L2_GAS: u32 = 45 + (2 * L2_GAS_PER_NULLIFIER_READ_REQUEST); global AVM_RETURN_BASE_L2_GAS: u32 = 28; global AVM_REVERT_BASE_L2_GAS: u32 = 28; global AVM_DEBUGLOG_BASE_L2_GAS: u32 = 12; // Must be equal to AVM_JUMP_BASE_L2_GAS as long as circuit implements debugLog as a jump @@ -513,7 +508,6 @@ global AVM_CALLDATACOPY_DYN_L2_GAS: u32 = 6; global AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS: u32 = 18 + (DA_BYTES_PER_FIELD * L2_GAS_PER_LOG_BYTE); global AVM_CALL_DYN_L2_GAS: u32 = 4; global AVM_STATICCALL_DYN_L2_GAS: u32 = 4; -global AVM_DELEGATECALL_DYN_L2_GAS: u32 = 4; global AVM_RETURN_DYN_L2_GAS: u32 = 6; global AVM_REVERT_DYN_L2_GAS: u32 = 6; global AVM_KECCAK_DYN_L2_GAS: u32 = 100; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 1fe3ef45961..70047797421 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -5,7 +5,7 @@ use crate::{ CombinedAccumulatedData, PrivateAccumulatedData, PrivateAccumulatedDataBuilder, PublicAccumulatedData, PublicAccumulatedDataArrayLengths, PublicAccumulatedDataBuilder }, - function_data::FunctionData, global_variables::GlobalVariables, + function_data::FunctionData, function_selector::FunctionSelector, global_variables::GlobalVariables, combined_constant_data::CombinedConstantData, enqueued_call_data::{EnqueuedCallData, Proof}, kernel_circuit_public_inputs::{ KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, @@ -14,13 +14,11 @@ use crate::{ kernel_data::KernelData, public_kernel_data::PublicKernelData, max_block_number::MaxBlockNumber, private_kernel_data::PrivateKernelData, note_hash::{NoteHash, ScopedNoteHash}, nullifier::{Nullifier, ScopedNullifier}, private_call_request::PrivateCallRequest, - private_call_stack_item::PrivateCallStackItem, private_circuit_public_inputs::PrivateCircuitPublicInputs, private_kernel::private_call_data::PrivateCallData, public_call_data::{Proof as PublicCallDataProof, PublicCallData}, - public_call_request::PublicCallRequest, public_call_stack_item::PublicCallStackItem, - public_circuit_public_inputs::PublicCircuitPublicInputs, public_data_read::PublicDataRead, - public_data_update_request::PublicDataUpdateRequest, + public_call_request::PublicCallRequest, public_circuit_public_inputs::PublicCircuitPublicInputs, + public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, public_inner_call_request::PublicInnerCallRequest, read_request::{ReadRequest, ScopedReadRequest}, tree_leaf_read_request::TreeLeafReadRequest, log_hash::{LogHash, NoteLogHash, ScopedLogHash, EncryptedLogHash, ScopedEncryptedLogHash}, @@ -91,9 +89,7 @@ fn vec_reverse(vec: BoundedVec) -> BoundedVec { pub struct FixtureBuilder { contract_address: AztecAddress, - storage_contract_address: AztecAddress, msg_sender: AztecAddress, - is_delegate_call: bool, is_static_call: bool, // Fees. @@ -204,7 +200,6 @@ impl FixtureBuilder { pub fn as_parent_contract(&mut self) -> Self { self.contract_address = fixtures::contracts::parent_contract.address; - self.storage_contract_address = fixtures::contracts::parent_contract.address; self.msg_sender = fixtures::MSG_SENDER; *self } @@ -242,14 +237,12 @@ impl FixtureBuilder { let _ = self.use_contract(contract_data); self.contract_address = AztecAddress::from_field(contract_index as Field); - self.storage_contract_address = self.contract_address; self.use_function(function_data) } pub fn use_contract(&mut self, contract_data: ContractData) -> Self { self.contract_address = contract_data.address; - self.storage_contract_address = self.contract_address; self.salted_initialization_hash = contract_data.salted_initialization_hash; self.public_keys = contract_data.public_keys; self.contract_class_artifact_hash = contract_data.artifact_hash; @@ -272,13 +265,6 @@ impl FixtureBuilder { *self } - pub fn is_delegate_call(&mut self) -> Self { - self.is_delegate_call = true; - self.storage_contract_address = fixtures::contracts::parent_contract.address; - self.msg_sender = fixtures::MSG_SENDER; - *self - } - pub fn is_static_call(&mut self) -> Self { self.is_static_call = true; *self @@ -311,16 +297,14 @@ impl FixtureBuilder { pub fn build_call_context(self) -> CallContext { CallContext { msg_sender: self.msg_sender, - storage_contract_address: self.storage_contract_address, + contract_address: self.contract_address, function_selector: self.function_data.selector, - is_delegate_call: self.is_delegate_call, is_static_call: self.is_static_call } } pub fn build_private_call_request(self) -> PrivateCallRequest { PrivateCallRequest { - contract_address: self.contract_address, call_context: self.build_call_context(), args_hash: self.args_hash, returns_hash: self.returns_hash, @@ -358,17 +342,9 @@ impl FixtureBuilder { } } - pub fn to_private_call_stack_item(self) -> PrivateCallStackItem { - PrivateCallStackItem { - contract_address: self.contract_address, - function_data: self.function_data, - public_inputs: self.to_private_circuit_public_inputs() - } - } - pub fn to_private_call_data(self) -> PrivateCallData { PrivateCallData { - call_stack_item: self.to_private_call_stack_item(), + public_inputs: self.to_private_circuit_public_inputs(), vk: self.client_ivc_vk, function_leaf_membership_witness: self.function_leaf_membership_witness, salted_initialization_hash: self.salted_initialization_hash, @@ -398,12 +374,7 @@ impl FixtureBuilder { } pub fn to_public_call_request(self) -> PublicCallRequest { - PublicCallRequest { - contract_address: self.contract_address, - call_context: self.build_call_context(), - args_hash: self.args_hash, - counter: 0 - } + PublicCallRequest { call_context: self.build_call_context(), args_hash: self.args_hash, counter: 0 } } pub fn to_public_accumulated_data_builder(self) -> PublicAccumulatedDataBuilder { @@ -527,17 +498,9 @@ impl FixtureBuilder { } } - pub fn to_public_call_stack_item(self) -> PublicCallStackItem { - PublicCallStackItem { - contract_address: self.contract_address, - function_data: self.function_data, - public_inputs: self.to_public_circuit_public_inputs() - } - } - pub fn to_public_call_data(self) -> PublicCallData { PublicCallData { - call_stack_item: self.to_public_call_stack_item(), + public_inputs: self.to_public_circuit_public_inputs(), proof: PublicCallDataProof {}, bytecode_hash: self.bytecode_hash } @@ -637,14 +600,14 @@ impl FixtureBuilder { } pub fn add_new_note_hash(&mut self, value: Field) { - self.note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope(self.storage_contract_address)); + self.note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope(self.contract_address)); } pub fn add_siloed_note_hash(&mut self, value: Field) { // First nullifier is tx hash. let tx_hash = self.nullifiers.get(0).value(); let index = self.note_hashes.len(); - let note_hash_to_silo = NoteHash { value, counter: 0 }.scope(self.storage_contract_address); + let note_hash_to_silo = NoteHash { value, counter: 0 }.scope(self.contract_address); let siloed_value = silo_note_hash(note_hash_to_silo, tx_hash, index); self.note_hashes.push(NoteHash { value: siloed_value, counter: self.next_counter() }.scope(AztecAddress::zero())); } @@ -694,9 +657,7 @@ impl FixtureBuilder { } pub fn add_nullifier_for_note_hash(&mut self, value: Field, note_hash: Field) { - self.nullifiers.push( - Nullifier { value, counter: self.next_counter(), note_hash }.scope(self.storage_contract_address) - ); + self.nullifiers.push(Nullifier { value, counter: self.next_counter(), note_hash }.scope(self.contract_address)); } pub fn add_siloed_nullifier(&mut self, value: Field) { @@ -705,7 +666,7 @@ impl FixtureBuilder { } pub fn add_siloed_nullifier_for_note_hash(&mut self, value: Field, note_hash: Field) { - let siloed_value = compute_siloed_nullifier(self.storage_contract_address, value); + let siloed_value = compute_siloed_nullifier(self.contract_address, value); self.nullifiers.push( Nullifier { value: siloed_value, counter: self.next_counter(), note_hash }.scope(AztecAddress::zero()) ); @@ -733,17 +694,17 @@ impl FixtureBuilder { pub fn add_l2_to_l1_message(&mut self, content: Field, recipient: EthAddress) { self.l2_to_l1_msgs.push( - L2ToL1Message { recipient, content, counter: self.next_counter() }.scope(self.storage_contract_address) + L2ToL1Message { recipient, content, counter: self.next_counter() }.scope(self.contract_address) ); } pub fn add_exposed_l2_to_l1_message(&mut self, content: Field, recipient: EthAddress) { - self.l2_to_l1_msgs.push(L2ToL1Message { recipient, content, counter: 0 }.scope(self.storage_contract_address)); + self.l2_to_l1_msgs.push(L2ToL1Message { recipient, content, counter: 0 }.scope(self.contract_address)); } pub fn add_siloed_l2_to_l1_message(&mut self, content: Field, recipient: EthAddress) { let siloed_content = compute_l2_to_l1_hash( - self.storage_contract_address, + self.contract_address, recipient, content, self.tx_context.version, @@ -833,7 +794,7 @@ impl FixtureBuilder { pub fn add_read_request_for_pending_note_hash(&mut self, note_hash_index: u32) -> u32 { let read_request_index = self.note_hash_read_requests.len(); let value = self.mock_note_hash_value(note_hash_index); - let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.storage_contract_address); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); self.note_hash_read_requests.push(read_request); read_request_index } @@ -843,7 +804,7 @@ impl FixtureBuilder { for i in 0..self.note_hash_read_requests.max_len() { if i < num_reads { let value = self.mock_note_hash_read_value(index_offset + i); - let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.storage_contract_address); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); self.note_hash_read_requests.push(read_request); } } @@ -867,13 +828,13 @@ impl FixtureBuilder { pub fn add_read_request_for_pending_nullifier(&mut self, nullifier_index: u32) -> u32 { let read_request_index = self.nullifier_read_requests.len(); let nullifier = self.mock_nullifier_value(nullifier_index); - let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.storage_contract_address); + let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.contract_address); self.nullifier_read_requests.push(read_request); read_request_index } pub fn add_non_existent_read_request_for_nullifier(&mut self, nullifier: Field) { - let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.storage_contract_address); + let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.contract_address); self.nullifier_non_existent_read_requests.push(read_request); } @@ -882,7 +843,7 @@ impl FixtureBuilder { for i in 0..self.nullifier_read_requests.max_len() { if i < num_reads { let value = self.mock_nullifier_read_value(index_offset + i); - let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.storage_contract_address); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); self.nullifier_read_requests.push(read_request); } } @@ -902,7 +863,7 @@ impl FixtureBuilder { let new_request_index = self.scoped_key_validation_requests_and_generators.len(); let request = KeyValidationRequest { pk_m, sk_app }; let request_and_generator = KeyValidationRequestAndGenerator { request, sk_app_generator }; - let scoped_key_validation_request_and_generator = request_and_generator.scope(self.storage_contract_address); + let scoped_key_validation_request_and_generator = request_and_generator.scope(self.contract_address); self.scoped_key_validation_requests_and_generators.push(scoped_key_validation_request_and_generator); new_request_index @@ -913,7 +874,7 @@ impl FixtureBuilder { for i in 0..self.scoped_key_validation_requests_and_generators.max_len() { if i < num_requests { let request = self.mock_key_validation_request(index_offset + i); - self.scoped_key_validation_requests_and_generators.push(request.scope(self.storage_contract_address)); + self.scoped_key_validation_requests_and_generators.push(request.scope(self.contract_address)); } } } @@ -936,12 +897,12 @@ impl FixtureBuilder { pub fn add_encrypted_log_hash(&mut self, hash: Field, length: Field) { let log_hash = EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }; - self.encrypted_logs_hashes.push(log_hash.scope(self.storage_contract_address)); + self.encrypted_logs_hashes.push(log_hash.scope(self.contract_address)); self.encrypted_log_preimages_length += length; } pub fn add_masked_encrypted_log_hash(&mut self, hash: Field, length: Field) { - let mut log_hash = EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }.scope(self.storage_contract_address); + let mut log_hash = EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }.scope(self.contract_address); log_hash.contract_address = mask_encrypted_log_hash(log_hash); log_hash.log_hash.randomness = 0; self.encrypted_logs_hashes.push(log_hash); @@ -966,7 +927,7 @@ impl FixtureBuilder { pub fn add_unencrypted_log_hash(&mut self, hash: Field, length: Field) { let log_hash = LogHash { value: hash, counter: self.next_counter(), length }; - self.unencrypted_logs_hashes.push(log_hash.scope(self.storage_contract_address)); + self.unencrypted_logs_hashes.push(log_hash.scope(self.contract_address)); self.unencrypted_log_preimages_length += length; } @@ -1001,33 +962,32 @@ impl FixtureBuilder { self.unencrypted_log_preimages_length = preimages_length; } - pub fn add_private_call_from_call_stack_item(&mut self, item: PrivateCallStackItem) { - let start_counter = item.public_inputs.start_side_effect_counter; - let end_counter = item.public_inputs.end_side_effect_counter; + pub fn add_private_call_request_for_private_call(&mut self, private_call: PrivateCallData) { + let public_inputs = private_call.public_inputs; + let start_counter = public_inputs.start_side_effect_counter; + let end_counter = public_inputs.end_side_effect_counter; self.counter = end_counter + 1; self.private_call_requests.push( PrivateCallRequest { - contract_address: item.contract_address, - call_context: item.public_inputs.call_context, - args_hash: item.public_inputs.args_hash, - returns_hash: item.public_inputs.returns_hash, + call_context: public_inputs.call_context, + args_hash: public_inputs.args_hash, + returns_hash: public_inputs.returns_hash, start_side_effect_counter: start_counter, end_side_effect_counter: end_counter } ); } - pub fn add_private_call_request(&mut self, is_delegate_call: bool) { + pub fn add_private_call_request(&mut self) { let index_offset = self.private_call_requests.len(); let mut request = self.mock_private_call_request(index_offset); - request.call_context = self.generate_call_context(request.contract_address, is_delegate_call); let start_counter = self.next_counter(); let end_counter = start_counter + 10; - self.counter = end_counter + 1; request.start_side_effect_counter = start_counter; request.end_side_effect_counter = end_counter; + self.counter = end_counter + 1; self.private_call_requests.push(request); } @@ -1035,15 +995,7 @@ impl FixtureBuilder { pub fn append_private_call_requests(&mut self, num: u32) { for i in 0..self.private_call_requests.max_len() { if i < num { - self.add_private_call_request(false); - } - } - } - - pub fn append_private_call_requests_delegate(&mut self, num: u32) { - for i in 0..self.private_call_requests.max_len() { - if i < num { - self.add_private_call_request(true); + self.add_private_call_request(); } } } @@ -1056,18 +1008,7 @@ impl FixtureBuilder { let index_offset = self.public_call_requests.len(); for i in 0..self.public_call_requests.max_len() { if i < num { - let mut request = self.mock_public_call_request(index_offset + i, false); - request.counter = self.next_counter(); - self.add_public_call_request(request); - } - } - } - - pub fn append_public_call_requests_delegate(&mut self, num: u32) { - let index_offset = self.public_call_requests.len(); - for i in 0..self.public_call_requests.max_len() { - if i < num { - let mut request = self.mock_public_call_request(index_offset + i, true); + let mut request = self.mock_public_call_request(index_offset + i); request.counter = self.next_counter(); self.add_public_call_request(request); } @@ -1080,18 +1021,12 @@ impl FixtureBuilder { pub fn make_fee_payer(&mut self) -> AztecAddress { self.is_fee_payer = true; - self.set_fee_payer(self.storage_contract_address); - self.storage_contract_address + self.set_fee_payer(self.contract_address); + self.contract_address } pub fn set_public_teardown_call_request(&mut self) { - let mut request = self.mock_public_teardown_call_request(false); - request.counter = self.next_counter(); - self.public_teardown_call_request = request; - } - - pub fn set_public_teardown_call_request_delegate(&mut self) { - let mut request = self.mock_public_teardown_call_request(true); + let mut request = self.mock_public_teardown_call_request(); request.counter = self.next_counter(); self.public_teardown_call_request = request; } @@ -1181,42 +1116,32 @@ impl FixtureBuilder { for i in 0..fields.len() { fields[i] = value_offset + i as Field; } - PrivateCallRequest::deserialize(fields) + let mut request = PrivateCallRequest::deserialize(fields); + request.call_context.msg_sender = self.contract_address; + request.call_context.is_static_call = self.is_static_call; + request } - fn mock_public_call_request(self, index: u32, is_delegate_call: bool) -> PublicCallRequest { + fn mock_public_call_request(self, index: u32) -> PublicCallRequest { let value_offset = 636363 + self.value_offset + index as Field; let mut fields = [0; PUBLIC_CALL_REQUEST_LENGTH]; for i in 0..fields.len() { fields[i] = value_offset + i as Field; } let mut request = PublicCallRequest::deserialize(fields); - request.call_context = self.generate_call_context(request.contract_address, is_delegate_call); + request.call_context.msg_sender = self.contract_address; + request.call_context.is_static_call = self.is_static_call; request } - fn mock_public_teardown_call_request(self, is_delegate_call: bool) -> PublicCallRequest { - self.mock_public_call_request(54345, is_delegate_call) + fn mock_public_teardown_call_request(self) -> PublicCallRequest { + self.mock_public_call_request(54345) } fn mock_fee_payer(self) -> AztecAddress { AztecAddress::from_field(900900 + self.value_offset) } - fn generate_call_context(self, target_contract_address: AztecAddress, is_delegate_call: bool) -> CallContext { - let mut call_context = CallContext::empty(); - call_context.is_delegate_call = is_delegate_call; - call_context.is_static_call = self.is_static_call; - if is_delegate_call { - call_context.msg_sender = self.msg_sender; - call_context.storage_contract_address = self.storage_contract_address; - } else { - call_context.msg_sender = self.storage_contract_address; - call_context.storage_contract_address = target_contract_address; - } - call_context - } - fn next_counter(&mut self) -> u32 { let counter = self.counter; self.counter += 1; @@ -1232,9 +1157,7 @@ impl Empty for FixtureBuilder { fn empty() -> Self { FixtureBuilder { contract_address: AztecAddress::zero(), - storage_contract_address: AztecAddress::zero(), msg_sender: AztecAddress::zero(), - is_delegate_call: false, is_static_call: false, is_fee_payer: false, fee_payer: AztecAddress::zero(), diff --git a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts index 10de7f6617e..34ce3848390 100644 --- a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts +++ b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts @@ -33,7 +33,7 @@ import { FunctionSelector, GrumpkinScalar, Point, - PrivateCallStackItem, + PrivateCircuitPublicInputs, PublicKeys, } from '@aztec/circuits.js'; import { NoteSelector } from '@aztec/foundation/abi'; @@ -80,8 +80,8 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false) NullifierMembershipWitness, TxSimulationResult, TxProvingResult, + PrivateCircuitPublicInputs, PrivateExecutionResult, - PrivateCallStackItem, CountedPublicExecutionRequest, CountedNoteLog, Tx, diff --git a/yarn-project/circuit-types/src/mocks.ts b/yarn-project/circuit-types/src/mocks.ts index f3c3f50aff6..c99a6af0a83 100644 --- a/yarn-project/circuit-types/src/mocks.ts +++ b/yarn-project/circuit-types/src/mocks.ts @@ -13,7 +13,7 @@ import { MAX_UNENCRYPTED_LOGS_PER_TX, Nullifier, PartialPrivateTailPublicInputsForPublic, - PrivateCallStackItem, + PrivateCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, PublicAccumulatedDataBuilder, ScopedLogHash, @@ -68,26 +68,20 @@ export const mockPrivateExecutionResult = ( const request = publicCallRequests.shift()!; const args = publicFunctionArgs.shift()!; publicTeardownFunctionCall = new PublicExecutionRequest( - request.contractAddress, CallContext.fromFields(request.callContext.toFields()), args, ); } enqueuedPublicFunctionCalls = publicCallRequests.map( - (r, i) => - new PublicExecutionRequest( - r.contractAddress, - CallContext.fromFields(r.callContext.toFields()), - publicFunctionArgs[i], - ), + (r, i) => new PublicExecutionRequest(CallContext.fromFields(r.callContext.toFields()), publicFunctionArgs[i]), ); } return new PrivateExecutionResult( Buffer.from(''), Buffer.from(''), new Map(), - PrivateCallStackItem.empty(), + PrivateCircuitPublicInputs.empty(), new Map(), [], new Map(), @@ -156,19 +150,13 @@ export const mockTx = ( data.forPublic.publicTeardownCallRequest = request; const args = publicFunctionArgs.shift()!; publicTeardownFunctionCall = new PublicExecutionRequest( - request.contractAddress, CallContext.fromFields(request.callContext.toFields()), args, ); } enqueuedPublicFunctionCalls = publicCallRequests.map( - (r, i) => - new PublicExecutionRequest( - r.contractAddress, - CallContext.fromFields(r.callContext.toFields()), - publicFunctionArgs[i], - ), + (r, i) => new PublicExecutionRequest(CallContext.fromFields(r.callContext.toFields()), publicFunctionArgs[i]), ); const nonRevertibleNullifiers = makeTuple(MAX_NULLIFIERS_PER_TX, Nullifier.empty); diff --git a/yarn-project/circuit-types/src/private_execution_result.test.ts b/yarn-project/circuit-types/src/private_execution_result.test.ts index d8fb428b30b..82b316137af 100644 --- a/yarn-project/circuit-types/src/private_execution_result.test.ts +++ b/yarn-project/circuit-types/src/private_execution_result.test.ts @@ -1,5 +1,5 @@ import { PublicExecutionRequest } from '@aztec/circuit-types'; -import { Fr, PrivateCallStackItem } from '@aztec/circuits.js'; +import { Fr, PrivateCircuitPublicInputs } from '@aztec/circuits.js'; import { PrivateExecutionResult, @@ -13,7 +13,7 @@ function emptyExecutionResult(): PrivateExecutionResult { Buffer.from(''), Buffer.from(''), new Map(), - PrivateCallStackItem.empty(), + PrivateCircuitPublicInputs.empty(), new Map(), [], new Map(), @@ -121,13 +121,13 @@ describe('execution_result', () => { }); it('returns the actual counter', () => { - executionResult.callStackItem.publicInputs.minRevertibleSideEffectCounter = new Fr(123); + executionResult.publicInputs.minRevertibleSideEffectCounter = new Fr(123); const res = getFinalMinRevertibleSideEffectCounter(executionResult); expect(res).toBe(123); }); it('returns the actual counter in a nested call', () => { - executionResult.nestedExecutions[1].callStackItem.publicInputs.minRevertibleSideEffectCounter = new Fr(123); + executionResult.nestedExecutions[1].publicInputs.minRevertibleSideEffectCounter = new Fr(123); const res = getFinalMinRevertibleSideEffectCounter(executionResult); expect(res).toBe(123); }); diff --git a/yarn-project/circuit-types/src/private_execution_result.ts b/yarn-project/circuit-types/src/private_execution_result.ts index e24d2cacc59..71854395dbe 100644 --- a/yarn-project/circuit-types/src/private_execution_result.ts +++ b/yarn-project/circuit-types/src/private_execution_result.ts @@ -8,7 +8,7 @@ import { UnencryptedFunctionL2Logs, UnencryptedL2Log, } from '@aztec/circuit-types'; -import { type IsEmpty, PrivateCallStackItem, sortByCounter } from '@aztec/circuits.js'; +import { type IsEmpty, PrivateCircuitPublicInputs, sortByCounter } from '@aztec/circuits.js'; import { NoteSelector } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; @@ -104,7 +104,7 @@ export class PrivateExecutionResult { public partialWitness: Map, // Needed for the verifier (kernel) /** The call stack item. */ - public callStackItem: PrivateCallStackItem, + public publicInputs: PrivateCircuitPublicInputs, /** Mapping of note hash to its index in the note hash tree. Used for building hints for note hash read requests. */ public noteHashLeafIndexMap: Map, /** The notes created in the executed function. */ @@ -141,7 +141,7 @@ export class PrivateExecutionResult { acir: this.acir.toString('hex'), vk: this.vk.toString('hex'), partialWitness: Array.from(this.partialWitness.entries()), - callStackItem: this.callStackItem.toJSON(), + publicInputs: this.publicInputs.toJSON(), noteHashLeafIndexMap: Array.from(this.noteHashLeafIndexMap.entries()).map(([key, value]) => [ key.toString(), value.toString(), @@ -171,7 +171,7 @@ export class PrivateExecutionResult { Array.isArray(json.partialWitness) ? new Map(json.partialWitness.map(([key, value]: any[]) => [Number(key), value as string])) : new Map(), - PrivateCallStackItem.fromJSON(json.callStackItem), + PrivateCircuitPublicInputs.fromJSON(json.publicInputs), Array.isArray(json.noteHashLeafIndexMap) ? new Map(json.noteHashLeafIndexMap.map(([key, value]: any[]) => [BigInt(key), BigInt(value)])) : new Map(), @@ -340,7 +340,7 @@ export function getFinalMinRevertibleSideEffectCounter(execResult: PrivateExecut return execResult.nestedExecutions.reduce((counter, exec) => { const nestedCounter = getFinalMinRevertibleSideEffectCounter(exec); return nestedCounter ? nestedCounter : counter; - }, execResult.callStackItem.publicInputs.minRevertibleSideEffectCounter.toNumber()); + }, execResult.publicInputs.minRevertibleSideEffectCounter.toNumber()); } export function collectNested( diff --git a/yarn-project/circuit-types/src/public_execution_request.ts b/yarn-project/circuit-types/src/public_execution_request.ts index e9a1e19621c..2344054e7b6 100644 --- a/yarn-project/circuit-types/src/public_execution_request.ts +++ b/yarn-project/circuit-types/src/public_execution_request.ts @@ -1,6 +1,5 @@ import { CallContext, type PublicCallRequest, Vector } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; -import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; @@ -12,10 +11,8 @@ import { inspect } from 'util'; */ export class PublicExecutionRequest { constructor( - public contractAddress: AztecAddress, /** * Context of the public call. - * TODO(#3417): Check if all fields of CallContext are actually needed. */ public callContext: CallContext, /** @@ -29,16 +26,12 @@ export class PublicExecutionRequest { } toBuffer() { - return serializeToBuffer(this.contractAddress, this.callContext, new Vector(this.args)); + return serializeToBuffer(this.callContext, new Vector(this.args)); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new PublicExecutionRequest( - new AztecAddress(reader.readBytes(32)), - CallContext.fromBuffer(reader), - reader.readVector(Fr), - ); + return new PublicExecutionRequest(CallContext.fromBuffer(reader), reader.readVector(Fr)); } static from(fields: FieldsOf): PublicExecutionRequest { @@ -46,28 +39,25 @@ export class PublicExecutionRequest { } static getFields(fields: FieldsOf) { - return [fields.contractAddress, fields.callContext, fields.args] as const; + return [fields.callContext, fields.args] as const; } static empty() { - return new PublicExecutionRequest(AztecAddress.ZERO, CallContext.empty(), []); + return new PublicExecutionRequest(CallContext.empty(), []); } isEmpty(): boolean { - return this.contractAddress.isZero() && this.callContext.isEmpty() && this.args.length === 0; + return this.callContext.isEmpty() && this.args.length === 0; } isForCallRequest(callRequest: PublicCallRequest) { return ( - this.contractAddress.equals(callRequest.contractAddress) && - this.callContext.equals(callRequest.callContext) && - computeVarArgsHash(this.args).equals(callRequest.argsHash) + this.callContext.equals(callRequest.callContext) && computeVarArgsHash(this.args).equals(callRequest.argsHash) ); } [inspect.custom]() { return `PublicExecutionRequest { - contractAddress: ${this.contractAddress} callContext: ${this.callContext} args: ${this.args} }`; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index a9515614501..66ded9b9322 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -135,7 +135,7 @@ export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; export const GAS_LENGTH = 2; export const GAS_SETTINGS_LENGTH = 7; -export const CALL_CONTEXT_LENGTH = 5; +export const CALL_CONTEXT_LENGTH = 4; export const CONTENT_COMMITMENT_LENGTH = 4; export const CONTRACT_INSTANCE_LENGTH = 16; export const CONTRACT_STORAGE_READ_LENGTH = 3; @@ -164,21 +164,20 @@ export const NOTE_HASH_LENGTH = 2; export const SCOPED_NOTE_HASH_LENGTH = 3; export const NULLIFIER_LENGTH = 3; export const SCOPED_NULLIFIER_LENGTH = 4; -export const PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH = 13; -export const PRIVATE_CALL_REQUEST_LENGTH = 10; -export const PUBLIC_CALL_REQUEST_LENGTH = 8; -export const PUBLIC_INNER_CALL_REQUEST_LENGTH = 14; +export const PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH = 12; +export const PRIVATE_CALL_REQUEST_LENGTH = 8; +export const PUBLIC_CALL_REQUEST_LENGTH = 6; +export const PUBLIC_INNER_CALL_REQUEST_LENGTH = 13; export const ROLLUP_VALIDATION_REQUESTS_LENGTH = 2; export const STATE_REFERENCE_LENGTH = 8; export const TX_CONTEXT_LENGTH = 9; export const TX_REQUEST_LENGTH = 13; export const TOTAL_FEES_LENGTH = 1; export const HEADER_LENGTH = 24; -export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 544; -export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 691; -export const PRIVATE_CALL_STACK_ITEM_LENGTH = 547; -export const PRIVATE_CONTEXT_INPUTS_LENGTH = 39; -export const PUBLIC_CONTEXT_INPUTS_LENGTH = 42; +export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 501; +export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 674; +export const PRIVATE_CONTEXT_INPUTS_LENGTH = 38; +export const PUBLIC_CONTEXT_INPUTS_LENGTH = 41; export const FEE_RECIPIENT_LENGTH = 2; export const AGGREGATION_OBJECT_LENGTH = 16; export const SCOPED_READ_REQUEST_LEN = 3; @@ -189,12 +188,12 @@ export const PUBLIC_VALIDATION_REQUESTS_LENGTH = 834; export const PUBLIC_DATA_UPDATE_REQUEST_LENGTH = 3; export const COMBINED_ACCUMULATED_DATA_LENGTH = 610; export const COMBINED_CONSTANT_DATA_LENGTH = 44; -export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1144; -export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1970; -export const PUBLIC_ACCUMULATED_DATA_LENGTH = 1119; +export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1064; +export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1888; +export const PUBLIC_ACCUMULATED_DATA_LENGTH = 1055; export const NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS = 8; -export const PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3127; -export const VM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2472; +export const PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2997; +export const VM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2374; export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 664; export const CONSTANT_ROLLUP_DATA_LENGTH = 13; export const BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 30; @@ -219,7 +218,7 @@ export const CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS = 145; export const AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 86; export const AVM_PROOF_LENGTH_IN_FIELDS = 3848; export const AVM_PUBLIC_COLUMN_MAX_SIZE = 1024; -export const AVM_PUBLIC_INPUTS_FLATTENED_SIZE = 2739; +export const AVM_PUBLIC_INPUTS_FLATTENED_SIZE = 2722; export const MEM_TAG_FF = 0; export const MEM_TAG_U1 = 1; export const MEM_TAG_U8 = 2; @@ -229,7 +228,6 @@ export const MEM_TAG_U64 = 5; export const MEM_TAG_U128 = 6; export const SENDER_KERNEL_INPUTS_COL_OFFSET = 0; export const ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; -export const STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; export const FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET = 2; export const IS_STATIC_CALL_KERNEL_INPUTS_COL_OFFSET = 3; export const CHAIN_ID_KERNEL_INPUTS_COL_OFFSET = 4; @@ -288,7 +286,6 @@ export const AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS = 18; export const AVM_SENDL2TOL1MSG_BASE_L2_GAS = 226; export const AVM_CALL_BASE_L2_GAS = 2445; export const AVM_STATICCALL_BASE_L2_GAS = 2445; -export const AVM_DELEGATECALL_BASE_L2_GAS = 2445; export const AVM_RETURN_BASE_L2_GAS = 28; export const AVM_REVERT_BASE_L2_GAS = 28; export const AVM_DEBUGLOG_BASE_L2_GAS = 12; @@ -306,7 +303,6 @@ export const AVM_CALLDATACOPY_DYN_L2_GAS = 6; export const AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS = 146; export const AVM_CALL_DYN_L2_GAS = 4; export const AVM_STATICCALL_DYN_L2_GAS = 4; -export const AVM_DELEGATECALL_DYN_L2_GAS = 4; export const AVM_RETURN_DYN_L2_GAS = 6; export const AVM_REVERT_DYN_L2_GAS = 6; export const AVM_KECCAK_DYN_L2_GAS = 100; diff --git a/yarn-project/circuits.js/src/scripts/constants.in.ts b/yarn-project/circuits.js/src/scripts/constants.in.ts index a4783b95183..6933b39b4b2 100644 --- a/yarn-project/circuits.js/src/scripts/constants.in.ts +++ b/yarn-project/circuits.js/src/scripts/constants.in.ts @@ -57,7 +57,6 @@ const CPP_CONSTANTS = [ 'START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET', 'SENDER_KERNEL_INPUTS_COL_OFFSET', 'ADDRESS_KERNEL_INPUTS_COL_OFFSET', - 'STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET', 'FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET', 'CHAIN_ID_KERNEL_INPUTS_COL_OFFSET', 'VERSION_KERNEL_INPUTS_COL_OFFSET', @@ -107,7 +106,6 @@ const PIL_CONSTANTS = [ 'START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET', 'SENDER_KERNEL_INPUTS_COL_OFFSET', 'ADDRESS_KERNEL_INPUTS_COL_OFFSET', - 'STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET', 'FUNCTION_SELECTOR_KERNEL_INPUTS_COL_OFFSET', 'CHAIN_ID_KERNEL_INPUTS_COL_OFFSET', 'VERSION_KERNEL_INPUTS_COL_OFFSET', @@ -308,27 +306,54 @@ function parseNoirFile(fileContent: string): ParsedContent { const constantsExpressions: [string, string][] = []; const generatorIndexEnum: { [key: string]: number } = {}; + const emptyExpression = (): { name: string; content: string[] } => ({ name: '', content: [] }); + let expression = emptyExpression(); fileContent.split('\n').forEach(l => { const line = l.trim(); - if (!line || line.match(/^\/\/|^\s*\/?\*/)) { + + if (!line) { + // Empty line. + return; + } + + if (line.match(/^\/\/|^\s*\/?\*/)) { + // Comment. return; } - const [, name, _type, value] = line.match(/global\s+(\w+)(\s*:\s*\w+)?\s*=\s*(.+?);/) || []; + { + const [, name, _type, value, end] = line.match(/global\s+(\w+)(\s*:\s*\w+)?\s*=\s*([^;]+)(;)?/) || []; + if (name && value) { + const [, indexName] = name.match(/GENERATOR_INDEX__(\w+)/) || []; + if (indexName) { + // Generator index. + generatorIndexEnum[indexName] = +value; + } else if (end) { + // A single line of expression. + constantsExpressions.push([name, value]); + } else { + // The first line of an expression. + expression = { name, content: [value] }; + } + return; + } + } - if (!name || !value) { - if (!line.includes('use crate')) { - // eslint-disable-next-line no-console - console.warn(`Unknown content: ${line}`); + if (expression.name) { + // The expression continues... + const [, content, end] = line.match(/\s*([^;]+)(;)?/) || []; + expression.content.push(content); + if (end) { + // The last line of an expression. + constantsExpressions.push([expression.name, expression.content.join('')]); + expression = emptyExpression(); } return; } - const [, indexName] = name.match(/GENERATOR_INDEX__(\w+)/) || []; - if (indexName) { - generatorIndexEnum[indexName] = +value; - } else { - constantsExpressions.push([name, value]); + if (!line.includes('use crate')) { + // eslint-disable-next-line no-console + console.warn(`Unknown content: ${line}`); } }); diff --git a/yarn-project/circuits.js/src/structs/call_context.ts b/yarn-project/circuits.js/src/structs/call_context.ts index 992b66ed92b..b5df33acc0a 100644 --- a/yarn-project/circuits.js/src/structs/call_context.ts +++ b/yarn-project/circuits.js/src/structs/call_context.ts @@ -16,19 +16,13 @@ export class CallContext { */ public msgSender: AztecAddress, /** - * The contract address against which all state changes will be stored. Not called `contractAddress` because during - * delegate call the contract whose code is being executed may be different from the contract whose state is being - * modified. + * The contract address being called. */ - public storageContractAddress: AztecAddress, + public contractAddress: AztecAddress, /** * Function selector of the function being called. */ public functionSelector: FunctionSelector, - /** - * Determines whether the call is a delegate call (see Ethereum's delegate call opcode for more information). - */ - public isDelegateCall: boolean, /** * Determines whether the call is modifying state. */ @@ -40,16 +34,12 @@ export class CallContext { * @returns A new instance of CallContext with zero msg sender, storage contract address. */ public static empty(): CallContext { - return new CallContext(AztecAddress.ZERO, AztecAddress.ZERO, FunctionSelector.empty(), false, false); + return new CallContext(AztecAddress.ZERO, AztecAddress.ZERO, FunctionSelector.empty(), false); } isEmpty() { return ( - this.msgSender.isZero() && - this.storageContractAddress.isZero() && - this.functionSelector.isEmpty() && - !this.isDelegateCall && - !this.isStaticCall + this.msgSender.isZero() && this.contractAddress.isZero() && this.functionSelector.isEmpty() && !this.isStaticCall ); } @@ -58,13 +48,7 @@ export class CallContext { } static getFields(fields: FieldsOf) { - return [ - fields.msgSender, - fields.storageContractAddress, - fields.functionSelector, - fields.isDelegateCall, - fields.isStaticCall, - ] as const; + return [fields.msgSender, fields.contractAddress, fields.functionSelector, fields.isStaticCall] as const; } /** @@ -97,7 +81,6 @@ export class CallContext { reader.readObject(AztecAddress), reader.readObject(FunctionSelector), reader.readBoolean(), - reader.readBoolean(), ); } @@ -108,16 +91,14 @@ export class CallContext { reader.readObject(AztecAddress), reader.readObject(FunctionSelector), reader.readBoolean(), - reader.readBoolean(), ); } equals(callContext: CallContext) { return ( callContext.msgSender.equals(this.msgSender) && - callContext.storageContractAddress.equals(this.storageContractAddress) && + callContext.contractAddress.equals(this.contractAddress) && callContext.functionSelector.equals(this.functionSelector) && - callContext.isDelegateCall === this.isDelegateCall && callContext.isStaticCall === this.isStaticCall ); } diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index ea548e3e4ce..611652fe46e 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -56,12 +56,10 @@ export * from './parity/root_parity_input.js'; export * from './parity/root_parity_inputs.js'; export * from './partial_state_reference.js'; export * from './private_call_request.js'; -export * from './private_call_stack_item.js'; export * from './private_circuit_public_inputs.js'; export * from './private_validation_requests.js'; export * from './proof.js'; export * from './public_call_request.js'; -export * from './public_call_stack_item.js'; export * from './public_call_stack_item_compressed.js'; export * from './public_circuit_public_inputs.js'; export * from './public_data_hint.js'; diff --git a/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts index c347d674ed7..e46fec69cd1 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts @@ -5,7 +5,7 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { FUNCTION_TREE_HEIGHT, PROTOCOL_CONTRACT_TREE_HEIGHT } from '../../constants.gen.js'; import { PublicKeys } from '../../types/public_keys.js'; import { MembershipWitness } from '../membership_witness.js'; -import { PrivateCallStackItem } from '../private_call_stack_item.js'; +import { PrivateCircuitPublicInputs } from '../private_circuit_public_inputs.js'; import { VerificationKeyAsFields } from '../verification_key.js'; /** @@ -14,9 +14,9 @@ import { VerificationKeyAsFields } from '../verification_key.js'; export class PrivateCallData { constructor( /** - * The call stack item currently being processed. + * Public inputs of the private function circuit. */ - public callStackItem: PrivateCallStackItem, + public publicInputs: PrivateCircuitPublicInputs, /** * The verification key for the function being invoked. */ @@ -55,7 +55,7 @@ export class PrivateCallData { */ static getFields(fields: FieldsOf) { return [ - fields.callStackItem, + fields.publicInputs, fields.vk, fields.contractClassArtifactHash, fields.contractClassPublicBytecodeCommitment, @@ -87,7 +87,7 @@ export class PrivateCallData { static fromBuffer(buffer: Buffer | BufferReader): PrivateCallData { const reader = BufferReader.asReader(buffer); return new PrivateCallData( - reader.readObject(PrivateCallStackItem), + reader.readObject(PrivateCircuitPublicInputs), reader.readObject(VerificationKeyAsFields), reader.readObject(Fr), reader.readObject(Fr), diff --git a/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts b/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts index 3f15a2e5903..bf8d7f9a2e1 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts @@ -2,7 +2,7 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { Proof } from '../proof.js'; -import { PublicCallStackItem } from '../public_call_stack_item.js'; +import { PublicCircuitPublicInputs } from '../public_circuit_public_inputs.js'; /** * Public calldata assembled from the kernel execution result and proof. @@ -10,9 +10,9 @@ import { PublicCallStackItem } from '../public_call_stack_item.js'; export class PublicCallData { constructor( /** - * Call stack item being processed by the current iteration of the kernel. + * Public inputs of the public function. */ - public readonly callStackItem: PublicCallStackItem, + public publicInputs: PublicCircuitPublicInputs, /** * Proof of the call stack item execution. */ @@ -24,11 +24,15 @@ export class PublicCallData { ) {} toBuffer() { - return serializeToBuffer(this.callStackItem, this.proof, this.bytecodeHash); + return serializeToBuffer(this.publicInputs, this.proof, this.bytecodeHash); } static fromBuffer(buffer: BufferReader | Buffer) { const reader = BufferReader.asReader(buffer); - return new PublicCallData(reader.readObject(PublicCallStackItem), reader.readObject(Proof), reader.readObject(Fr)); + return new PublicCallData( + reader.readObject(PublicCircuitPublicInputs), + reader.readObject(Proof), + reader.readObject(Fr), + ); } } diff --git a/yarn-project/circuits.js/src/structs/private_call_request.ts b/yarn-project/circuits.js/src/structs/private_call_request.ts index 880cf2b8dc4..e98c7555ae9 100644 --- a/yarn-project/circuits.js/src/structs/private_call_request.ts +++ b/yarn-project/circuits.js/src/structs/private_call_request.ts @@ -1,16 +1,10 @@ -import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; import { CallContext } from './call_context.js'; -import { type PrivateCallStackItem } from './index.js'; export class PrivateCallRequest { constructor( - /** - * The address of the contract being called. - */ - public contractAddress: AztecAddress, /** * The call context of the call. */ @@ -35,7 +29,6 @@ export class PrivateCallRequest { toFields(): Fr[] { return serializeToFields([ - this.contractAddress, this.callContext, this.argsHash, this.returnsHash, @@ -47,7 +40,6 @@ export class PrivateCallRequest { static fromFields(fields: Fr[] | FieldReader) { const reader = FieldReader.asReader(fields); return new PrivateCallRequest( - reader.readObject(AztecAddress), reader.readObject(CallContext), reader.readField(), reader.readField(), @@ -58,7 +50,6 @@ export class PrivateCallRequest { toBuffer() { return serializeToBuffer( - this.contractAddress, this.callContext, this.argsHash, this.returnsHash, @@ -70,7 +61,6 @@ export class PrivateCallRequest { public static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new PrivateCallRequest( - reader.readObject(AztecAddress), reader.readObject(CallContext), Fr.fromBuffer(reader), Fr.fromBuffer(reader), @@ -81,7 +71,6 @@ export class PrivateCallRequest { isEmpty() { return ( - this.contractAddress.isZero() && this.callContext.isEmpty() && this.argsHash.isZero() && this.returnsHash.isZero() && @@ -91,12 +80,11 @@ export class PrivateCallRequest { } public static empty() { - return new PrivateCallRequest(AztecAddress.ZERO, CallContext.empty(), Fr.ZERO, Fr.ZERO, 0, 0); + return new PrivateCallRequest(CallContext.empty(), Fr.ZERO, Fr.ZERO, 0, 0); } equals(callRequest: PrivateCallRequest) { return ( - callRequest.contractAddress.equals(this.contractAddress) && callRequest.callContext.equals(this.callContext) && callRequest.argsHash.equals(this.argsHash) && callRequest.returnsHash.equals(this.returnsHash) && @@ -106,17 +94,6 @@ export class PrivateCallRequest { } toString() { - return `PrivateCallRequest(target: ${this.contractAddress}, callContext: ${this.callContext}, argsHash: ${this.argsHash}, returnsHash: ${this.returnsHash}, startSideEffectCounter: ${this.startSideEffectCounter}, endSideEffectCounter: ${this.endSideEffectCounter})`; - } - - matchesStackItem(stackItem: PrivateCallStackItem) { - return ( - stackItem.contractAddress.equals(this.contractAddress) && - stackItem.publicInputs.callContext.equals(this.callContext) && - stackItem.publicInputs.argsHash.equals(this.argsHash) && - stackItem.publicInputs.returnsHash.equals(this.returnsHash) && - stackItem.publicInputs.startSideEffectCounter.equals(new Fr(this.startSideEffectCounter)) && - stackItem.publicInputs.endSideEffectCounter.equals(new Fr(this.endSideEffectCounter)) - ); + return `PrivateCallRequest(callContext: ${this.callContext}, argsHash: ${this.argsHash}, returnsHash: ${this.returnsHash}, startSideEffectCounter: ${this.startSideEffectCounter}, endSideEffectCounter: ${this.endSideEffectCounter})`; } } diff --git a/yarn-project/circuits.js/src/structs/private_call_stack_item.test.ts b/yarn-project/circuits.js/src/structs/private_call_stack_item.test.ts deleted file mode 100644 index 801e761699e..00000000000 --- a/yarn-project/circuits.js/src/structs/private_call_stack_item.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { randomInt } from '@aztec/foundation/crypto'; -import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; - -import { PRIVATE_CALL_STACK_ITEM_LENGTH } from '../constants.gen.js'; -import { makePrivateCallStackItem } from '../tests/factories.js'; -import { PrivateCallStackItem } from './private_call_stack_item.js'; - -describe('PrivateCallStackItem', () => { - let item: PrivateCallStackItem; - - beforeAll(() => { - setupCustomSnapshotSerializers(expect); - item = makePrivateCallStackItem(randomInt(1000)); - }); - - it('serializes to buffer and deserializes it back', () => { - const buffer = item.toBuffer(); - const res = PrivateCallStackItem.fromBuffer(buffer); - expect(res).toEqual(item); - }); - - it('serializes to field array and deserializes it back', () => { - const fieldArray = item.toFields(); - const res = PrivateCallStackItem.fromFields(fieldArray); - expect(res).toEqual(item); - }); - - it('number of fields matches constant', () => { - const fields = item.toFields(); - expect(fields.length).toBe(PRIVATE_CALL_STACK_ITEM_LENGTH); - }); -}); diff --git a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts deleted file mode 100644 index 7479d26aa81..00000000000 --- a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { type Fr } from '@aztec/foundation/fields'; -import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; -import { type FieldsOf } from '@aztec/foundation/types'; - -import { PRIVATE_CALL_STACK_ITEM_LENGTH } from '../constants.gen.js'; -import { FunctionData } from './function_data.js'; -import { PrivateCircuitPublicInputs } from './private_circuit_public_inputs.js'; - -/** - * Call stack item on a private call. - */ -export class PrivateCallStackItem { - constructor( - /** - * Address of the contract on which the function is invoked. - */ - public contractAddress: AztecAddress, - /** - * Data identifying the function being called. - */ - public functionData: FunctionData, - /** - * Public inputs to the private kernel circuit. - */ - public publicInputs: PrivateCircuitPublicInputs, - ) {} - - static getFields(fields: FieldsOf) { - return [fields.contractAddress, fields.functionData, fields.publicInputs] as const; - } - - toBuffer() { - return serializeToBuffer(...PrivateCallStackItem.getFields(this)); - } - - toFields(): Fr[] { - const fields = serializeToFields(...PrivateCallStackItem.getFields(this)); - if (fields.length !== PRIVATE_CALL_STACK_ITEM_LENGTH) { - throw new Error( - `Invalid number of fields for PrivateCallStackItem. Expected ${PRIVATE_CALL_STACK_ITEM_LENGTH}, got ${fields.length}`, - ); - } - return fields; - } - - /** - * Deserializes from a buffer or reader. - * @param buffer - Buffer or reader to read from. - * @returns The deserialized instance. - */ - static fromBuffer(buffer: Buffer | BufferReader): PrivateCallStackItem { - const reader = BufferReader.asReader(buffer); - return new PrivateCallStackItem( - reader.readObject(AztecAddress), - reader.readObject(FunctionData), - reader.readObject(PrivateCircuitPublicInputs), - ); - } - - static fromFields(fields: Fr[] | FieldReader): PrivateCallStackItem { - const reader = FieldReader.asReader(fields); - return new PrivateCallStackItem( - AztecAddress.fromFields(reader), - FunctionData.fromFields(reader), - PrivateCircuitPublicInputs.fromFields(reader), - ); - } - - /** - * Returns a new instance of PrivateCallStackItem with zero contract address, function data and public inputs. - * @returns A new instance of PrivateCallStackItem with zero contract address, function data and public inputs. - */ - public static empty(): PrivateCallStackItem { - return new PrivateCallStackItem( - AztecAddress.ZERO, - FunctionData.empty({ isPrivate: true }), - PrivateCircuitPublicInputs.empty(), - ); - } - - public toJSON() { - return { - contractAddress: this.contractAddress.toString(), - functionData: this.functionData.toJSON(), - publicInputs: this.publicInputs.toBuffer().toString('hex'), - }; - } - - public static fromJSON(value: any) { - return new PrivateCallStackItem( - AztecAddress.fromString(value.contractAddress), - FunctionData.fromJSON(value.functionData), - PrivateCircuitPublicInputs.fromBuffer(Buffer.from(value.publicInputs, 'hex')), - ); - } - - isEmpty() { - return this.contractAddress.isZero() && this.functionData.isEmpty() && this.publicInputs.isEmpty(); - } -} diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 9b277dc9b4f..108ca3ff850 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -320,4 +320,12 @@ export class PrivateCircuitPublicInputs { } return fields; } + + public toJSON() { + return this.toBuffer().toString('hex'); + } + + public static fromJSON(value: any) { + return PrivateCircuitPublicInputs.fromBuffer(Buffer.from(value, 'hex')); + } } diff --git a/yarn-project/circuits.js/src/structs/public_call_request.ts b/yarn-project/circuits.js/src/structs/public_call_request.ts index bd66f913f7f..c11e4975556 100644 --- a/yarn-project/circuits.js/src/structs/public_call_request.ts +++ b/yarn-project/circuits.js/src/structs/public_call_request.ts @@ -1,4 +1,3 @@ -import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; @@ -11,12 +10,7 @@ import { CallContext } from './call_context.js'; * Represents a request to call a public function. */ export class PublicCallRequest { - constructor( - public contractAddress: AztecAddress, - public callContext: CallContext, - public argsHash: Fr, - public counter: number, - ) {} + constructor(public callContext: CallContext, public argsHash: Fr, public counter: number) {} getSize() { return this.isEmpty() ? 0 : this.toBuffer().length; @@ -27,7 +21,7 @@ export class PublicCallRequest { * @returns The buffer. */ toBuffer() { - return serializeToBuffer(this.contractAddress, this.callContext, this.argsHash, this.counter); + return serializeToBuffer(this.callContext, this.argsHash, this.counter); } /** @@ -37,12 +31,7 @@ export class PublicCallRequest { */ static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new PublicCallRequest( - reader.readObject(AztecAddress), - reader.readObject(CallContext), - reader.readObject(Fr), - reader.readNumber(), - ); + return new PublicCallRequest(reader.readObject(CallContext), reader.readObject(Fr), reader.readNumber()); } /** @@ -60,34 +49,28 @@ export class PublicCallRequest { * @returns The array. */ static getFields(fields: FieldsOf) { - return [fields.contractAddress, fields.callContext, fields.argsHash, fields.counter] as const; + return [fields.callContext, fields.argsHash, fields.counter] as const; } toFields(): Fr[] { - return serializeToFields([this.contractAddress, this.callContext, this.argsHash, this.counter]); + return serializeToFields([this.callContext, this.argsHash, this.counter]); } static fromFields(fields: Fr[] | FieldReader): PublicCallRequest { const reader = FieldReader.asReader(fields); - return new PublicCallRequest( - AztecAddress.fromFields(reader), - CallContext.fromFields(reader), - reader.readField(), - reader.readU32(), - ); + return new PublicCallRequest(CallContext.fromFields(reader), reader.readField(), reader.readU32()); } static empty() { - return new PublicCallRequest(AztecAddress.ZERO, CallContext.empty(), Fr.ZERO, 0); + return new PublicCallRequest(CallContext.empty(), Fr.ZERO, 0); } isEmpty(): boolean { - return this.contractAddress.isZero() && this.callContext.isEmpty() && this.argsHash.isEmpty() && this.counter == 0; + return this.callContext.isEmpty() && this.argsHash.isEmpty() && this.counter == 0; } [inspect.custom]() { return `PublicCallRequest { - contractAddress: ${this.contractAddress} callContext: ${this.callContext} argsHash: ${this.argsHash} counter: ${this.counter} diff --git a/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts b/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts deleted file mode 100644 index b8e6c4cc1b6..00000000000 --- a/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { randomInt } from '@aztec/foundation/crypto'; - -import { makePublicCallStackItem } from '../tests/factories.js'; -import { PublicCallStackItem } from './public_call_stack_item.js'; - -describe('PublicCallStackItem', () => { - it('serializes to buffer and deserializes it back', () => { - const expected = makePublicCallStackItem(randomInt(1000)); - const buffer = expected.toBuffer(); - const res = PublicCallStackItem.fromBuffer(buffer); - expect(res).toEqual(expected); - }); -}); diff --git a/yarn-project/circuits.js/src/structs/public_call_stack_item.ts b/yarn-project/circuits.js/src/structs/public_call_stack_item.ts deleted file mode 100644 index 79d5d2ab29e..00000000000 --- a/yarn-project/circuits.js/src/structs/public_call_stack_item.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { type Fr } from '@aztec/foundation/fields'; -import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type FieldsOf } from '@aztec/foundation/types'; - -import { FunctionData } from './function_data.js'; -import { PublicCircuitPublicInputs } from './public_circuit_public_inputs.js'; - -/** - * Call stack item on a public call. - */ -export class PublicCallStackItem { - constructor( - /** - * Address of the contract on which the function is invoked. - */ - public contractAddress: AztecAddress, - /** - * Data identifying the function being called. - */ - public functionData: FunctionData, - /** - * Public inputs to the public kernel circuit. - */ - public publicInputs: PublicCircuitPublicInputs, - ) {} - - static getFields(fields: FieldsOf) { - return [fields.contractAddress, fields.functionData, fields.publicInputs] as const; - } - - toBuffer() { - return serializeToBuffer(...PublicCallStackItem.getFields(this)); - } - - /** - * Deserializes from a buffer or reader. - * @param buffer - Buffer or reader to read from. - * @returns The deserialized instance. - */ - static fromBuffer(buffer: Buffer | BufferReader): PublicCallStackItem { - const reader = BufferReader.asReader(buffer); - return new PublicCallStackItem( - reader.readObject(AztecAddress), - reader.readObject(FunctionData), - reader.readObject(PublicCircuitPublicInputs), - ); - } - - static fromFields(fields: Fr[] | FieldReader): PublicCallStackItem { - const reader = FieldReader.asReader(fields); - - const contractAddress = AztecAddress.fromFields(reader); - const functionData = FunctionData.fromFields(reader); - const publicInputs = PublicCircuitPublicInputs.fromFields(reader); - - return new PublicCallStackItem(contractAddress, functionData, publicInputs); - } - - /** - * Returns a new instance of PublicCallStackItem with zero contract address, function data and public inputs. - * @returns A new instance of PublicCallStackItem with zero contract address, function data and public inputs. - */ - public static empty(): PublicCallStackItem { - return new PublicCallStackItem( - AztecAddress.ZERO, - FunctionData.empty({ isPrivate: false }), - PublicCircuitPublicInputs.empty(), - ); - } - - isEmpty() { - return this.contractAddress.isZero() && this.functionData.isEmpty() && this.publicInputs.isEmpty(); - } -} diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 5b65b215483..7d07a1a6d3e 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -98,14 +98,12 @@ import { Point, PreviousRollupData, PrivateCallRequest, - PrivateCallStackItem, PrivateCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, Proof, PublicAccumulatedData, PublicCallData, PublicCallRequest, - PublicCallStackItem, PublicCallStackItemCompressed, PublicCircuitPublicInputs, PublicDataHint, @@ -423,16 +421,14 @@ function makePublicAccumulatedDataArrayLengths(seed = 1) { /** * Creates arbitrary call context. * @param seed - The seed to use for generating the call context. - * @param storageContractAddress - The storage contract address set on the call context. * @returns A call context. */ export function makeCallContext(seed = 0, overrides: Partial> = {}): CallContext { return CallContext.from({ msgSender: makeAztecAddress(seed), - storageContractAddress: makeAztecAddress(seed + 1), + contractAddress: makeAztecAddress(seed + 1), functionSelector: makeSelector(seed + 3), isStaticCall: false, - isDelegateCall: false, ...overrides, }); } @@ -440,18 +436,18 @@ export function makeCallContext(seed = 0, overrides: Partial { }); it('PXE processes failed assertions and fills in the error message with the expression (even complex ones)', async () => { await expect(avmContract.methods.assert_nullifier_exists(123).simulate()).rejects.toThrow( - "Assertion failed: Nullifier doesn't exist! 'context.nullifier_exists(nullifier, context.storage_address())'", + "Assertion failed: Nullifier doesn't exist! 'context.nullifier_exists(nullifier, context.this_address())'", ); }); }); diff --git a/yarn-project/end-to-end/src/e2e_delegate_calls/delegate.test.ts b/yarn-project/end-to-end/src/e2e_delegate_calls/delegate.test.ts deleted file mode 100644 index 3e7d77aeff8..00000000000 --- a/yarn-project/end-to-end/src/e2e_delegate_calls/delegate.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { DelegateCallsTest } from './delegate_calls_test.js'; - -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6423): delegate call not implemented. -describe.skip('e2e_delegate_calls', () => { - const t = new DelegateCallsTest('delegate_calls'); - let { delegatorContract, delegatedOnContract, wallet } = t; - - beforeAll(async () => { - await t.applyBaseSnapshots(); - await t.setup(); - // Have to destructure again to ensure we have latest refs. - ({ delegatorContract, delegatedOnContract, wallet } = t); - }); - - afterAll(async () => { - await t.teardown(); - }); - - describe('delegates on another contract', () => { - it("runs another contract's private function on delegator's storage", async () => { - const sentValue = 42n; - await delegatorContract.methods - .private_delegate_set_value(delegatedOnContract.address, sentValue, wallet.getCompleteAddress().address) - .send() - .wait(); - - const delegatorValue = await delegatorContract.methods - .get_private_value(sentValue, wallet.getCompleteAddress().address) - .simulate(); - - await expect( - delegatedOnContract.methods.get_private_value(sentValue, wallet.getCompleteAddress().address).simulate(), - ).rejects.toThrow(`Assertion failed: Attempted to read past end of BoundedVec 'num_notes != 0'`); - - expect(delegatorValue).toEqual(sentValue); - }); - - it("runs another contract's enqueued public function on delegator's storage", async () => { - const sentValue = 42n; - await delegatorContract.methods.enqueued_delegate_set_value(delegatedOnContract.address, sentValue).send().wait(); - - const delegatorValue = await delegatorContract.methods.view_public_value().simulate(); - const delegatedOnValue = await delegatedOnContract.methods.view_public_value().simulate(); - - expect(delegatedOnValue).toEqual(0n); - expect(delegatorValue).toEqual(sentValue); - }); - - it("runs another contract's public function on delegator's storage", async () => { - const sentValue = 42n; - await delegatorContract.methods.public_delegate_set_value(delegatedOnContract.address, sentValue).send().wait(); - - const delegatorValue = await delegatorContract.methods.view_public_value().simulate(); - const delegatedOnValue = await delegatedOnContract.methods.view_public_value().simulate(); - - expect(delegatedOnValue).toEqual(0n); - expect(delegatorValue).toEqual(sentValue); - }); - }); -}); diff --git a/yarn-project/end-to-end/src/e2e_delegate_calls/delegate_calls_test.ts b/yarn-project/end-to-end/src/e2e_delegate_calls/delegate_calls_test.ts deleted file mode 100644 index 0911bd0bc80..00000000000 --- a/yarn-project/end-to-end/src/e2e_delegate_calls/delegate_calls_test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { getSchnorrAccount } from '@aztec/accounts/schnorr'; -import { type AccountWallet, type DebugLogger, createDebugLogger } from '@aztec/aztec.js'; -import { DelegatedOnContract, DelegatorContract } from '@aztec/noir-contracts.js'; - -import { - type ISnapshotManager, - type SubsystemsContext, - addAccounts, - createSnapshotManager, -} from '../fixtures/snapshot_manager.js'; - -const { E2E_DATA_PATH: dataPath } = process.env; - -export class DelegateCallsTest { - private snapshotManager: ISnapshotManager; - logger: DebugLogger; - wallet!: AccountWallet; - delegatorContract!: DelegatorContract; - delegatedOnContract!: DelegatedOnContract; - - constructor(testName: string) { - this.logger = createDebugLogger(`aztec:e2e_delegate_calls:${testName}`); - this.snapshotManager = createSnapshotManager(`e2e_delegate_calls/${testName}`, dataPath); - } - - /** - * Adds two state shifts to snapshot manager. - * 1. Add 3 accounts. - * 2. Publicly deploy accounts, deploy token contract and a "bad account". - */ - async applyBaseSnapshots() { - await this.snapshotManager.snapshot('accounts', addAccounts(1, this.logger), async ({ accountKeys }, { pxe }) => { - const accountManager = getSchnorrAccount(pxe, accountKeys[0][0], accountKeys[0][1], 1); - this.wallet = await accountManager.getWallet(); - this.logger.verbose(`Wallet address: ${this.wallet.getAddress()}`); - }); - - await this.snapshotManager.snapshot( - 'e2e_delegate_calls', - async () => { - this.logger.verbose(`Deploying DelegatorContract...`); - this.delegatorContract = await DelegatorContract.deploy(this.wallet).send().deployed(); - this.logger.verbose(`Delegator deployed to ${this.delegatorContract.address}`); - - this.logger.verbose(`Deploying DelegatedOnContract...`); - this.delegatedOnContract = await DelegatedOnContract.deploy(this.wallet).send().deployed(); - - return { - delegatorContractAddress: this.delegatorContract.address, - delegatedOnContractAddress: this.delegatedOnContract.address, - }; - }, - async ({ delegatorContractAddress, delegatedOnContractAddress }) => { - // Restore the token contract state. - this.delegatorContract = await DelegatorContract.at(delegatorContractAddress, this.wallet); - this.logger.verbose(`Delegator contract address: ${this.delegatorContract.address}`); - - this.delegatedOnContract = await DelegatedOnContract.at(delegatedOnContractAddress, this.wallet); - this.logger.verbose(`DelegatedOn address: ${this.delegatedOnContract.address}`); - }, - ); - } - - async setup() { - await this.snapshotManager.setup(); - } - - snapshot = ( - name: string, - apply: (context: SubsystemsContext) => Promise, - restore: (snapshotData: T, context: SubsystemsContext) => Promise = () => Promise.resolve(), - ): Promise => this.snapshotManager.snapshot(name, apply, restore); - - async teardown() { - await this.snapshotManager.teardown(); - } -} diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index cda46fac68f..6e39f70cb9e 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -132,7 +132,7 @@ export async function executeInit( mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), - mapPrivateCircuitPublicInputsToNoir(privateKernelInitCircuitPrivateInputs.privateCall.callStackItem.publicInputs), + mapPrivateCircuitPublicInputsToNoir(privateKernelInitCircuitPrivateInputs.privateCall.publicInputs), SimulatedClientCircuitArtifacts.PrivateKernelInitArtifact as CompiledCircuit, foreignCallHandler, ); @@ -152,7 +152,7 @@ export async function executeInner( mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), mapPrivateKernelCircuitPublicInputsToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs), mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), - mapPrivateCircuitPublicInputsToNoir(privateKernelInnerCircuitPrivateInputs.privateCall.callStackItem.publicInputs), + mapPrivateCircuitPublicInputsToNoir(privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs), SimulatedClientCircuitArtifacts.PrivateKernelInnerArtifact as CompiledCircuit, foreignCallHandler, ); @@ -246,7 +246,7 @@ export function convertPrivateKernelInitInputsToWitnessMap( protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), private_call: mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInitCircuitPrivateInputs.privateCall.callStackItem.publicInputs, + privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, ), }); return initialWitnessMap; @@ -267,7 +267,7 @@ export function convertPrivateKernelInnerInputsToWitnessMap( ), private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.privateCall.callStackItem.publicInputs, + privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, ), }); return initialWitnessMap; diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 587957a91ac..2e355682fd3 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -83,7 +83,6 @@ import { PrivateAccumulatedData, type PrivateCallData, PrivateCallRequest, - type PrivateCallStackItem, type PrivateCircuitPublicInputs, PrivateKernelCircuitPublicInputs, type PrivateKernelData, @@ -95,7 +94,6 @@ import { PublicAccumulatedDataArrayLengths, type PublicCallData, PublicCallRequest, - type PublicCallStackItem, PublicCallStackItemCompressed, type PublicCircuitPublicInputs, type PublicDataHint, @@ -208,7 +206,6 @@ import type { PrivateAccumulatedData as PrivateAccumulatedDataNoir, PrivateCallDataWithoutPublicInputs as PrivateCallDataWithoutPublicInputsNoir, PrivateCallRequest as PrivateCallRequestNoir, - PrivateCallStackItemWithoutPublicInputs as PrivateCallStackItemWithoutPublicInputsNoir, PrivateCircuitPublicInputs as PrivateCircuitPublicInputsNoir, PrivateKernelCircuitPublicInputs as PrivateKernelCircuitPublicInputsNoir, PrivateKernelDataWithoutPublicInputs as PrivateKernelDataWithoutPublicInputsNoir, @@ -220,7 +217,6 @@ import type { PublicCallData as PublicCallDataNoir, PublicCallRequest as PublicCallRequestNoir, PublicCallStackItemCompressed as PublicCallStackItemCompressedNoir, - PublicCallStackItem as PublicCallStackItemNoir, PublicCircuitPublicInputs as PublicCircuitPublicInputsNoir, PublicDataHint as PublicDataHintNoir, PublicDataLeafHint as PublicDataLeafHintNoir, @@ -492,9 +488,8 @@ export function mapTxRequestToNoir(txRequest: TxRequest): TxRequestNoir { export function mapCallContextFromNoir(callContext: CallContextNoir): CallContext { return new CallContext( mapAztecAddressFromNoir(callContext.msg_sender), - mapAztecAddressFromNoir(callContext.storage_contract_address), + mapAztecAddressFromNoir(callContext.contract_address), mapFunctionSelectorFromNoir(callContext.function_selector), - callContext.is_delegate_call, callContext.is_static_call, ); } @@ -507,9 +502,8 @@ export function mapCallContextFromNoir(callContext: CallContextNoir): CallContex export function mapCallContextToNoir(callContext: CallContext): CallContextNoir { return { msg_sender: mapAztecAddressToNoir(callContext.msgSender), - storage_contract_address: mapAztecAddressToNoir(callContext.storageContractAddress), + contract_address: mapAztecAddressToNoir(callContext.contractAddress), function_selector: mapFunctionSelectorToNoir(callContext.functionSelector), - is_delegate_call: callContext.isDelegateCall, is_static_call: callContext.isStaticCall, }; } @@ -534,7 +528,6 @@ export function mapGasSettingsToNoir(gasSettings: GasSettings): GasSettingsNoir function mapPrivateCallRequestFromNoir(callRequest: PrivateCallRequestNoir) { return new PrivateCallRequest( - mapAztecAddressFromNoir(callRequest.contract_address), mapCallContextFromNoir(callRequest.call_context), mapFieldFromNoir(callRequest.args_hash), mapFieldFromNoir(callRequest.returns_hash), @@ -545,7 +538,6 @@ function mapPrivateCallRequestFromNoir(callRequest: PrivateCallRequestNoir) { function mapPrivateCallRequestToNoir(callRequest: PrivateCallRequest): PrivateCallRequestNoir { return { - contract_address: mapAztecAddressToNoir(callRequest.contractAddress), call_context: mapCallContextToNoir(callRequest.callContext), args_hash: mapFieldToNoir(callRequest.argsHash), returns_hash: mapFieldToNoir(callRequest.returnsHash), @@ -580,28 +572,16 @@ function mapPublicCallStackItemCompressedToNoir( }; } -/** - * Maps a noir call request to a call request. - * @param callRequest - The noir call request. - * @returns The call request. - */ function mapPublicCallRequestFromNoir(request: PublicCallRequestNoir) { return new PublicCallRequest( - mapAztecAddressFromNoir(request.contract_address), mapCallContextFromNoir(request.call_context), mapFieldFromNoir(request.args_hash), mapNumberFromNoir(request.counter), ); } -/** - * Maps a call request to a noir call request. - * @param privateCallStackItem - The call stack item. - * @returns The noir call stack item. - */ function mapPublicCallRequestToNoir(request: PublicCallRequest): PublicCallRequestNoir { return { - contract_address: mapAztecAddressToNoir(request.contractAddress), call_context: mapCallContextToNoir(request.callContext), args_hash: mapFieldToNoir(request.argsHash), counter: mapNumberToNoir(request.counter), @@ -987,20 +967,6 @@ export function mapPrivateCircuitPublicInputsToNoir( }; } -/** - * Maps a private call stack item to a noir private call stack item. - * @param privateCallStackItem - The private call stack item. - * @returns The noir private call stack item. - */ -export function mapPrivateCallStackItemToNoir( - privateCallStackItem: PrivateCallStackItem, -): PrivateCallStackItemWithoutPublicInputsNoir { - return { - contract_address: mapAztecAddressToNoir(privateCallStackItem.contractAddress), - function_data: mapFunctionDataToNoir(privateCallStackItem.functionData), - }; -} - /** * Maps a private call data to a noir private call data. * @param privateCallData - The private call data. @@ -1008,7 +974,6 @@ export function mapPrivateCallStackItemToNoir( */ export function mapPrivateCallDataToNoir(privateCallData: PrivateCallData): PrivateCallDataWithoutPublicInputsNoir { return { - call_stack_item: mapPrivateCallStackItemToNoir(privateCallData.callStackItem), vk: mapVerificationKeyToNoir(privateCallData.vk, CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS), function_leaf_membership_witness: mapMembershipWitnessToNoir(privateCallData.functionLeafMembershipWitness), contract_class_artifact_hash: mapFieldToNoir(privateCallData.contractClassArtifactHash), @@ -2066,19 +2031,6 @@ export function mapBlockRootOrBlockMergePublicInputsToNoir( }; } -/** - * Maps a public call stack item to noir. - * @param publicCallStackItem - The public call stack item. - * @returns The noir public call stack item. - */ -function mapPublicCallStackItemToNoir(publicCallStackItem: PublicCallStackItem): PublicCallStackItemNoir { - return { - contract_address: mapAztecAddressToNoir(publicCallStackItem.contractAddress), - public_inputs: mapPublicCircuitPublicInputsToNoir(publicCallStackItem.publicInputs), - function_data: mapFunctionDataToNoir(publicCallStackItem.functionData), - }; -} - /** * Maps a public call data to noir. * @param publicCall - The public call data. @@ -2086,7 +2038,7 @@ function mapPublicCallStackItemToNoir(publicCallStackItem: PublicCallStackItem): */ function mapPublicCallDataToNoir(publicCall: PublicCallData): PublicCallDataNoir { return { - call_stack_item: mapPublicCallStackItemToNoir(publicCall.callStackItem), + public_inputs: mapPublicCircuitPublicInputsToNoir(publicCall.publicInputs), proof: {}, bytecode_hash: mapFieldToNoir(publicCall.bytecodeHash), }; diff --git a/yarn-project/p2p/src/tx_validator/data_validator.test.ts b/yarn-project/p2p/src/tx_validator/data_validator.test.ts index 11da4394f21..729e7818b66 100644 --- a/yarn-project/p2p/src/tx_validator/data_validator.test.ts +++ b/yarn-project/p2p/src/tx_validator/data_validator.test.ts @@ -30,21 +30,20 @@ describe('TxDataValidator', () => { const goodTxs = mockTxs(3); const badTxs = mockTxs(2); badTxs[0].data.forPublic!.endNonRevertibleData.publicCallStack[0].argsHash = Fr.random(); - badTxs[1].data.forPublic!.endNonRevertibleData.publicCallStack[1].contractAddress = AztecAddress.random(); + badTxs[1].data.forPublic!.endNonRevertibleData.publicCallStack[1].callContext.contractAddress = + AztecAddress.random(); await expect(validator.validateTxs([...goodTxs, ...badTxs])).resolves.toEqual([goodTxs, badTxs]); }); it('rejects txs with mismatch revertible execution requests', async () => { const goodTxs = mockTxs(3); - const badTxs = mockTxs(5); + const badTxs = mockTxs(4); badTxs[0].data.forPublic!.end.publicCallStack[0].callContext.msgSender = AztecAddress.random(); - badTxs[1].data.forPublic!.end.publicCallStack[1].callContext.storageContractAddress = AztecAddress.random(); + badTxs[1].data.forPublic!.end.publicCallStack[1].callContext.contractAddress = AztecAddress.random(); badTxs[2].data.forPublic!.end.publicCallStack[0].callContext.functionSelector = FunctionSelector.random(); - badTxs[3].data.forPublic!.end.publicCallStack[1].callContext.isDelegateCall = - !badTxs[3].enqueuedPublicFunctionCalls[1].callContext.isDelegateCall; - badTxs[4].data.forPublic!.end.publicCallStack[0].callContext.isStaticCall = - !badTxs[4].enqueuedPublicFunctionCalls[0].callContext.isStaticCall; + badTxs[3].data.forPublic!.end.publicCallStack[0].callContext.isStaticCall = + !badTxs[3].enqueuedPublicFunctionCalls[0].callContext.isStaticCall; await expect(validator.validateTxs([...badTxs, ...goodTxs])).resolves.toEqual([goodTxs, badTxs]); }); @@ -52,7 +51,7 @@ describe('TxDataValidator', () => { it('rejects txs with mismatch teardown execution requests', async () => { const goodTxs = mockTxs(3); const badTxs = mockTxs(2); - badTxs[0].data.forPublic!.publicTeardownCallRequest.contractAddress = AztecAddress.random(); + badTxs[0].data.forPublic!.publicTeardownCallRequest.callContext.contractAddress = AztecAddress.random(); badTxs[1].data.forPublic!.publicTeardownCallRequest.callContext.msgSender = AztecAddress.random(); await expect(validator.validateTxs([...goodTxs, ...badTxs])).resolves.toEqual([goodTxs, badTxs]); diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index c3f32861141..222af08400d 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -171,7 +171,7 @@ export class TestContext { ? tx.enqueuedPublicFunctionCalls : [...tx.enqueuedPublicFunctionCalls, tx.publicTeardownFunctionCall]; for (const request of allCalls) { - if (execution.contractAddress.equals(request.contractAddress)) { + if (execution.callContext.equals(request.callContext)) { const result = PublicExecutionResultBuilder.fromPublicExecutionRequest({ request }).build({ startGasLeft: availableGas, endGasLeft: availableGas, diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 9f508e0a962..27648fcca0b 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -1226,7 +1226,7 @@ export class ProvingOrchestrator implements EpochProver { publicFunction.vmRequest!.functionName, publicFunction.vmRequest!.bytecode, publicFunction.vmRequest!.calldata, - publicFunction.vmRequest!.kernelRequest.inputs.publicCall.callStackItem.publicInputs, + publicFunction.vmRequest!.kernelRequest.inputs.publicCall.publicInputs, publicFunction.vmRequest!.avmHints, ); try { diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts index 400bea1d9d8..44caa601b3a 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts @@ -1,5 +1,4 @@ import { PublicExecutionRequest, mockTx } from '@aztec/circuit-types'; -import { AztecAddress } from '@aztec/circuits.js'; import { makeCallContext } from '@aztec/circuits.js/testing'; import { createDebugLogger } from '@aztec/foundation/log'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; @@ -71,7 +70,7 @@ describe('prover/orchestrator/public-functions', () => { const nonRevertibleRequests = tx.getNonRevertiblePublicExecutionRequests(); const revertibleRequests = tx.getRevertiblePublicExecutionRequests(); const teardownRequest = tx.getPublicTeardownExecutionRequest()!; - const mockNestedRequest = () => new PublicExecutionRequest(AztecAddress.random(), makeCallContext(1), []); + const mockNestedRequest = () => new PublicExecutionRequest(makeCallContext(1), []); const simulatorResults: PublicExecutionResult[] = [ // Setup diff --git a/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts b/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts index 14855f80172..0b7bc63a0a0 100644 --- a/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +++ b/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts @@ -48,11 +48,7 @@ function collectNestedReadRequests( return collectNested(executionStack, executionResult => { const nonEmptyReadRequests = getNonEmptyItems(extractReadRequests(executionResult)); return nonEmptyReadRequests.map( - readRequest => - new ScopedReadRequest( - readRequest, - executionResult.callStackItem.publicInputs.callContext.storageContractAddress, - ), + readRequest => new ScopedReadRequest(readRequest, executionResult.publicInputs.callContext.contractAddress), ); }); } @@ -117,7 +113,7 @@ export class PrivateKernelResetPrivateInputsBuilder { MAX_NULLIFIERS_PER_TX, () => new TransientDataIndexHint(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX), ); - this.nextIteration = executionStack[this.executionStack.length - 1]?.callStackItem.publicInputs; + this.nextIteration = executionStack[this.executionStack.length - 1]?.publicInputs; } needsReset(): boolean { @@ -244,10 +240,9 @@ export class PrivateKernelResetPrivateInputsBuilder { } const futureNoteHashes = collectNested(this.executionStack, executionResult => { - const nonEmptyNoteHashes = getNonEmptyItems(executionResult.callStackItem.publicInputs.noteHashes); + const nonEmptyNoteHashes = getNonEmptyItems(executionResult.publicInputs.noteHashes); return nonEmptyNoteHashes.map( - noteHash => - new ScopedNoteHash(noteHash, executionResult.callStackItem.publicInputs.callContext.storageContractAddress), + noteHash => new ScopedNoteHash(noteHash, executionResult.publicInputs.callContext.contractAddress), ); }); @@ -297,10 +292,9 @@ export class PrivateKernelResetPrivateInputsBuilder { } const futureNullifiers = collectNested(this.executionStack, executionResult => { - const nonEmptyNullifiers = getNonEmptyItems(executionResult.callStackItem.publicInputs.nullifiers); + const nonEmptyNullifiers = getNonEmptyItems(executionResult.publicInputs.nullifiers); return nonEmptyNullifiers.map( - nullifier => - new ScopedNullifier(nullifier, executionResult.callStackItem.publicInputs.callContext.storageContractAddress), + nullifier => new ScopedNullifier(nullifier, executionResult.publicInputs.callContext.contractAddress), ); }); @@ -376,11 +370,11 @@ export class PrivateKernelResetPrivateInputsBuilder { const futureNoteHashReads = collectNestedReadRequests( this.executionStack, - executionResult => executionResult.callStackItem.publicInputs.noteHashReadRequests, + executionResult => executionResult.publicInputs.noteHashReadRequests, ); const futureNullifierReads = collectNestedReadRequests( this.executionStack, - executionResult => executionResult.callStackItem.publicInputs.nullifierReadRequests, + executionResult => executionResult.publicInputs.nullifierReadRequests, ); if (this.nextIteration) { // If it's not the final reset, only one dimension will be reset at a time. diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index 9faad730fc1..c34fa969661 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -7,13 +7,11 @@ import { } from '@aztec/circuit-types'; import { CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, - FunctionData, FunctionSelector, MAX_NOTE_HASHES_PER_CALL, MAX_NOTE_HASHES_PER_TX, MembershipWitness, NoteHash, - PrivateCallStackItem, PrivateCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, @@ -62,13 +60,12 @@ describe('Kernel Prover', () => { : NoteHash.empty(), 0, ); - const functionData = FunctionData.empty(); - functionData.selector = new FunctionSelector(fnName.charCodeAt(0)); + publicInputs.callContext.functionSelector = new FunctionSelector(fnName.charCodeAt(0)); return new PrivateExecutionResult( Buffer.alloc(0), VerificationKey.makeFake().toBuffer(), new Map(), - new PrivateCallStackItem(AztecAddress.ZERO, functionData, publicInputs), + publicInputs, new Map(), newNoteIndices.map(idx => notesAndSlots[idx]), new Map(), @@ -124,10 +121,10 @@ describe('Kernel Prover', () => { const expectExecution = (fns: string[]) => { const callStackItemsInit = proofCreator.simulateProofInit.mock.calls.map(args => - String.fromCharCode(args[0].privateCall.callStackItem.functionData.selector.value), + String.fromCharCode(args[0].privateCall.publicInputs.callContext.functionSelector.value), ); const callStackItemsInner = proofCreator.simulateProofInner.mock.calls.map(args => - String.fromCharCode(args[0].privateCall.callStackItem.functionData.selector.value), + String.fromCharCode(args[0].privateCall.publicInputs.callContext.functionSelector.value), ); expect(proofCreator.simulateProofInit).toHaveBeenCalledTimes(Math.min(1, fns.length)); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index a99fd2cd662..bc21a78ceea 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -114,8 +114,8 @@ export class KernelProver { executionStack.push(...[...currentExecution.nestedExecutions].reverse()); const functionName = await this.oracle.getDebugFunctionName( - currentExecution.callStackItem.contractAddress, - currentExecution.callStackItem.functionData.selector, + currentExecution.publicInputs.callContext.contractAddress, + currentExecution.publicInputs.callContext.functionSelector, ); const appVk = await this.proofCreator.computeAppCircuitVerificationKey(currentExecution.acir, functionName); @@ -201,12 +201,12 @@ export class KernelProver { return tailOutput; } - private async createPrivateCallData({ callStackItem }: PrivateExecutionResult, vk: VerificationKeyAsFields) { - const { contractAddress, functionData } = callStackItem; + private async createPrivateCallData({ publicInputs }: PrivateExecutionResult, vk: VerificationKeyAsFields) { + const { contractAddress, functionSelector } = publicInputs.callContext; const functionLeafMembershipWitness = await this.oracle.getFunctionMembershipWitness( contractAddress, - functionData.selector, + functionSelector, ); const { contractClassId, publicKeys, saltedInitializationHash } = await this.oracle.getContractAddressPreimage( contractAddress, @@ -223,7 +223,7 @@ export class KernelProver { : makeTuple(PROTOCOL_CONTRACT_TREE_HEIGHT, Fr.zero); return PrivateCallData.from({ - callStackItem, + publicInputs, vk, publicKeys, contractClassArtifactHash, diff --git a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts index 0e3c9a0caa7..7f1f814278b 100644 --- a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts +++ b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts @@ -26,7 +26,7 @@ import { UnencryptedL2Log, UniqueNote, } from '@aztec/circuit-types'; -import { FunctionSelector, PrivateCallStackItem, PublicKeys } from '@aztec/circuits.js'; +import { FunctionSelector, PrivateCircuitPublicInputs, PublicKeys } from '@aztec/circuits.js'; import { NoteSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Buffer32 } from '@aztec/foundation/buffer'; @@ -74,8 +74,8 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer { NullifierMembershipWitness, TxSimulationResult, TxProvingResult, + PrivateCircuitPublicInputs, PrivateExecutionResult, - PrivateCallStackItem, CountedPublicExecutionRequest, CountedNoteLog, Tx, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 3b13593cb29..c85ec7075ee 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -821,8 +821,7 @@ export class PXEService implements PXE { privateExecutionResult: PrivateExecutionResult, ): Promise> { // use the block the tx was simulated against - const block = - privateExecutionResult.callStackItem.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber(); + const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber(); const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block); const kernelProver = new KernelProver(kernelOracle, proofCreator); this.log.debug(`Executing kernel prover...`); diff --git a/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts b/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts index 705a9fce7f3..7d4683f0226 100644 --- a/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts +++ b/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts @@ -61,14 +61,13 @@ export class GasTxValidator implements TxValidator { const setupFns = EnqueuedCallsProcessor.getExecutionRequestsByPhase(tx, PublicKernelPhase.SETUP); const claimFunctionCall = setupFns.find( fn => - fn.contractAddress.equals(this.#feeJuiceAddress) && + fn.callContext.contractAddress.equals(this.#feeJuiceAddress) && fn.callContext.msgSender.equals(this.#feeJuiceAddress) && fn.args.length > 2 && // Public functions get routed through the dispatch function, whose first argument is the target function selector. fn.args[0].equals(FunctionSelector.fromSignature('_increase_public_balance((Field),Field)').toField()) && fn.args[1].equals(feePayer) && - !fn.callContext.isStaticCall && - !fn.callContext.isDelegateCall, + !fn.callContext.isStaticCall, ); const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[2]) : initialBalance; diff --git a/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts b/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts index 57d42d5213b..ccc8931e731 100644 --- a/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts +++ b/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts @@ -50,7 +50,7 @@ export class PhasesTxValidator implements TxValidator { if (!(await this.isOnAllowList(setupFn, this.setupAllowList))) { this.#log.warn( `Rejecting tx ${Tx.getHash(tx)} because it calls setup function not on allow list: ${ - setupFn.contractAddress + setupFn.callContext.contractAddress }:${setupFn.callContext.functionSelector}`, ); @@ -66,10 +66,7 @@ export class PhasesTxValidator implements TxValidator { return true; } - const { - contractAddress, - callContext: { functionSelector }, - } = publicCall; + const { contractAddress, functionSelector } = publicCall.callContext; // do these checks first since they don't require the contract class for (const entry of allowList) { @@ -88,7 +85,7 @@ export class PhasesTxValidator implements TxValidator { const contractClass = await this.contractDataSource.getContractInstance(contractAddress); if (!contractClass) { - throw new Error(`Contract not found: ${publicCall.contractAddress.toString()}`); + throw new Error(`Contract not found: ${contractAddress}`); } if ('classId' in entry && !('selector' in entry)) { diff --git a/yarn-project/sequencer-client/src/tx_validator/test_utils.ts b/yarn-project/sequencer-client/src/tx_validator/test_utils.ts index 1ac09efd7df..f28b80cdbc0 100644 --- a/yarn-project/sequencer-client/src/tx_validator/test_utils.ts +++ b/yarn-project/sequencer-client/src/tx_validator/test_utils.ts @@ -25,20 +25,20 @@ function patchFn( overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress }, ): { address: AztecAddress; selector: FunctionSelector } { const fn = tx.enqueuedPublicFunctionCalls.at(-1 * index - 1)!; - fn.contractAddress = overrides.address ?? fn.contractAddress; + fn.callContext.contractAddress = overrides.address ?? fn.callContext.contractAddress; fn.callContext.functionSelector = overrides.selector; fn.args = overrides.args ?? fn.args; fn.callContext.msgSender = overrides.msgSender ?? fn.callContext.msgSender; tx.enqueuedPublicFunctionCalls[index] = fn; const request = tx.data.forPublic![where].publicCallStack[index]; - request.contractAddress = fn.contractAddress; + request.callContext.contractAddress = fn.callContext.contractAddress; request.callContext = fn.callContext; request.argsHash = computeVarArgsHash(fn.args); tx.data.forPublic![where].publicCallStack[index] = request; return { - address: fn.contractAddress, + address: fn.callContext.contractAddress, selector: fn.callContext.functionSelector, }; } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index a2b53d7987d..103ac0a8f55 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -360,7 +360,6 @@ export class Oracle { [argsHash]: ACVMField[], [sideEffectCounter]: ACVMField[], [isStaticCall]: ACVMField[], - [isDelegateCall]: ACVMField[], ): Promise { const { endSideEffectCounter, returnsHash } = await this.typedOracle.callPrivateFunction( AztecAddress.fromField(fromACVMField(contractAddress)), @@ -368,7 +367,6 @@ export class Oracle { fromACVMField(argsHash), frToNumber(fromACVMField(sideEffectCounter)), frToBoolean(fromACVMField(isStaticCall)), - frToBoolean(fromACVMField(isDelegateCall)), ); return [endSideEffectCounter, returnsHash].map(toACVMField); } @@ -379,7 +377,6 @@ export class Oracle { [argsHash]: ACVMField[], [sideEffectCounter]: ACVMField[], [isStaticCall]: ACVMField[], - [isDelegateCall]: ACVMField[], ): Promise { const newArgsHash = await this.typedOracle.enqueuePublicFunctionCall( AztecAddress.fromString(contractAddress), @@ -387,7 +384,6 @@ export class Oracle { fromACVMField(argsHash), frToNumber(fromACVMField(sideEffectCounter)), frToBoolean(fromACVMField(isStaticCall)), - frToBoolean(fromACVMField(isDelegateCall)), ); return toACVMField(newArgsHash); } @@ -398,7 +394,6 @@ export class Oracle { [argsHash]: ACVMField[], [sideEffectCounter]: ACVMField[], [isStaticCall]: ACVMField[], - [isDelegateCall]: ACVMField[], ): Promise { const newArgsHash = await this.typedOracle.setPublicTeardownFunctionCall( AztecAddress.fromString(contractAddress), @@ -406,7 +401,6 @@ export class Oracle { fromACVMField(argsHash), frToNumber(fromACVMField(sideEffectCounter)), frToBoolean(fromACVMField(isStaticCall)), - frToBoolean(fromACVMField(isDelegateCall)), ); return toACVMField(newArgsHash); } diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index f8b25629a83..ed3eb107b0c 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -221,7 +221,6 @@ export abstract class TypedOracle { _argsHash: Fr, _sideEffectCounter: number, _isStaticCall: boolean, - _isDelegateCall: boolean, ): Promise<{ endSideEffectCounter: Fr; returnsHash: Fr }> { throw new OracleMethodNotAvailableError('callPrivateFunction'); } @@ -232,7 +231,6 @@ export abstract class TypedOracle { _argsHash: Fr, _sideEffectCounter: number, _isStaticCall: boolean, - _isDelegateCall: boolean, ): Promise { throw new OracleMethodNotAvailableError('enqueuePublicFunctionCall'); } @@ -243,7 +241,6 @@ export abstract class TypedOracle { _argsHash: Fr, _sideEffectCounter: number, _isStaticCall: boolean, - _isDelegateCall: boolean, ): Promise { throw new OracleMethodNotAvailableError('setPublicTeardownFunctionCall'); } diff --git a/yarn-project/simulator/src/avm/avm_context.test.ts b/yarn-project/simulator/src/avm/avm_context.test.ts index 0c58acee4cb..573adcb7eb1 100644 --- a/yarn-project/simulator/src/avm/avm_context.test.ts +++ b/yarn-project/simulator/src/avm/avm_context.test.ts @@ -15,7 +15,6 @@ describe('Avm Context', () => { expect(newContext.environment).toEqual( allSameExcept(context.environment, { address: newAddress, - storageAddress: newAddress, contractCallDepth: Fr.ONE, calldata: newCalldata, isStaticCall: false, @@ -45,7 +44,6 @@ describe('Avm Context', () => { expect(newContext.environment).toEqual( allSameExcept(context.environment, { address: newAddress, - storageAddress: newAddress, contractCallDepth: Fr.ONE, calldata: newCalldata, isStaticCall: true, diff --git a/yarn-project/simulator/src/avm/avm_context.ts b/yarn-project/simulator/src/avm/avm_context.ts index b0ca8d3b2df..50f20239994 100644 --- a/yarn-project/simulator/src/avm/avm_context.ts +++ b/yarn-project/simulator/src/avm/avm_context.ts @@ -30,7 +30,7 @@ export class AvmContext { * - Derive a machine state from the current state * - E.g., gas metering is preserved but pc is reset * - Derive an execution environment from the caller/parent - * - Alter both address and storageAddress + * - Alter address * * @param address - The contract instance to initialize a context for * @param calldata - Data/arguments for nested call diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.test.ts b/yarn-project/simulator/src/avm/avm_execution_environment.test.ts index de9270d0ef0..f6c6f07c688 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.test.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.test.ts @@ -15,28 +15,12 @@ describe('Execution Environment', () => { expect(newExecutionEnvironment).toEqual( allSameExcept(executionEnvironment, { address: newAddress, - storageAddress: newAddress, contractCallDepth: Fr.ONE, calldata: calldata, }), ); }); - // Delegate calls not supported. - it.skip('New delegate call should fork execution environment correctly', () => { - const executionEnvironment = initExecutionEnvironment(); - const newExecutionEnvironment = executionEnvironment.newDelegateCall(newAddress, calldata, selector); - - expect(newExecutionEnvironment).toEqual( - allSameExcept(executionEnvironment, { - address: newAddress, - contractCallDepth: Fr.ONE, - isDelegateCall: true, - calldata: calldata, - }), - ); - }); - it('New static call call should fork execution environment correctly', () => { const executionEnvironment = initExecutionEnvironment(); const newExecutionEnvironment = executionEnvironment.deriveEnvironmentForNestedStaticCall( @@ -48,7 +32,6 @@ describe('Execution Environment', () => { expect(newExecutionEnvironment).toEqual( allSameExcept(executionEnvironment, { address: newAddress, - storageAddress: newAddress, contractCallDepth: Fr.ONE, isStaticCall: true, calldata: calldata, diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index 36592fd7a03..d4ebe69608b 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -9,14 +9,12 @@ import { Fr } from '@aztec/foundation/fields'; export class AvmExecutionEnvironment { constructor( public readonly address: AztecAddress, - public readonly storageAddress: AztecAddress, public readonly sender: AztecAddress, public readonly functionSelector: FunctionSelector, // may be temporary (#7224) public readonly contractCallDepth: Fr, public readonly transactionFee: Fr, public readonly globals: GlobalVariables, public readonly isStaticCall: boolean, - public readonly isDelegateCall: boolean, public readonly calldata: Fr[], ) {} @@ -25,18 +23,15 @@ export class AvmExecutionEnvironment { calldata: Fr[], functionSelector: FunctionSelector, isStaticCall: boolean, - isDelegateCall: boolean, ) { return new AvmExecutionEnvironment( /*address=*/ targetAddress, - /*storageAddress=*/ targetAddress, /*sender=*/ this.address, functionSelector, this.contractCallDepth.add(Fr.ONE), this.transactionFee, this.globals, isStaticCall, - isDelegateCall, calldata, ); } @@ -51,7 +46,6 @@ export class AvmExecutionEnvironment { calldata, functionSelector, /*isStaticCall=*/ false, - /*isDelegateCall=*/ false, ); } @@ -65,15 +59,6 @@ export class AvmExecutionEnvironment { calldata, functionSelector, /*isStaticCall=*/ true, - /*isDelegateCall=*/ false, ); } - - public newDelegateCall( - _targetAddress: AztecAddress, - _calldata: Fr[], - _functionSelector: FunctionSelector, - ): AvmExecutionEnvironment { - throw new Error('Delegate calls not supported!'); - } } diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index fead5ed3320..5af202898e7 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -113,7 +113,6 @@ const BASE_GAS_COSTS: Record = { [Opcode.GETCONTRACTINSTANCE]: makeCost(c.AVM_GETCONTRACTINSTANCE_BASE_L2_GAS, 0), [Opcode.CALL]: makeCost(c.AVM_CALL_BASE_L2_GAS, 0), [Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_BASE_L2_GAS, 0), - [Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_BASE_L2_GAS, 0), [Opcode.RETURN]: makeCost(c.AVM_RETURN_BASE_L2_GAS, 0), [Opcode.REVERT_8]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0), [Opcode.REVERT_16]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0), @@ -134,7 +133,6 @@ const DYNAMIC_GAS_COSTS = new Map([ [Opcode.EMITUNENCRYPTEDLOG, makeCost(c.AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS, c.AVM_EMITUNENCRYPTEDLOG_DYN_DA_GAS)], [Opcode.CALL, makeCost(c.AVM_CALL_DYN_L2_GAS, 0)], [Opcode.STATICCALL, makeCost(c.AVM_STATICCALL_DYN_L2_GAS, 0)], - [Opcode.DELEGATECALL, makeCost(c.AVM_DELEGATECALL_DYN_L2_GAS, 0)], [Opcode.RETURN, makeCost(c.AVM_RETURN_DYN_L2_GAS, 0)], [Opcode.REVERT_8, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)], [Opcode.REVERT_16, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)], diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index a4f36f95f3f..a4c39654a5a 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -355,7 +355,6 @@ describe('AVM simulator: transpiled Noir contracts', () => { describe('Environment getters', () => { const address = AztecAddress.random(); - const storageAddress = AztecAddress.random(); const sender = AztecAddress.random(); const functionSelector = FunctionSelector.random(); const transactionFee = Fr.random(); @@ -375,7 +374,6 @@ describe('AVM simulator: transpiled Noir contracts', () => { }); const env = initExecutionEnvironment({ address, - storageAddress, sender, functionSelector, transactionFee, @@ -388,7 +386,6 @@ describe('AVM simulator: transpiled Noir contracts', () => { it.each([ ['address', address.toField(), 'get_address'], - ['storageAddress', storageAddress.toField(), 'get_storage_address'], ['sender', sender.toField(), 'get_sender'], ['transactionFee', transactionFee.toField(), 'get_transaction_fee'], ['chainId', chainId.toField(), 'get_chain_id'], @@ -424,7 +421,6 @@ describe('AVM simulator: transpiled Noir contracts', () => { describe('Side effects, world state, nested calls', () => { const address = new Fr(1); - const storageAddress = new Fr(2); const sender = new Fr(42); const leafIndex = new Fr(7); const slotNumber = 1; // must update Noir contract if changing this @@ -449,7 +445,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const createContext = (calldata: Fr[] = []) => { return initContext({ persistableState, - env: initExecutionEnvironment({ address, storageAddress, sender, calldata }), + env: initExecutionEnvironment({ address, sender, calldata }), }); }; @@ -479,7 +475,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const expectedValue = results.output[0].toNumber() === 1 ? value0 : Fr.ZERO; expect(trace.traceNoteHashCheck).toHaveBeenCalledTimes(1); expect(trace.traceNoteHashCheck).toHaveBeenCalledWith( - storageAddress, + address, /*noteHash=*/ expectedValue, leafIndex, /*exists=*/ expectFound, @@ -507,7 +503,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { // leafIndex is returned from DB call for nullifiers, so it is absent on DB miss const tracedLeafIndex = exists && !isPending ? leafIndex : Fr.ZERO; expect(trace.traceNullifierCheck).toHaveBeenCalledWith( - storageAddress, + address, /*nullifier=*/ value0, tracedLeafIndex, exists, @@ -565,10 +561,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.output).toEqual([]); expect(trace.traceNewNoteHash).toHaveBeenCalledTimes(1); - expect(trace.traceNewNoteHash).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*noteHash=*/ value0, - ); + expect(trace.traceNewNoteHash).toHaveBeenCalledWith(expect.objectContaining(address), /*noteHash=*/ value0); }); it('Should append a new nullifier correctly', async () => { @@ -581,10 +574,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.output).toEqual([]); expect(trace.traceNewNullifier).toHaveBeenCalledTimes(1); - expect(trace.traceNewNullifier).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*nullifier=*/ value0, - ); + expect(trace.traceNewNullifier).toHaveBeenCalledWith(expect.objectContaining(address), /*nullifier=*/ value0); }); describe('Cached nullifiers', () => { @@ -599,14 +589,11 @@ describe('AVM simulator: transpiled Noir contracts', () => { // New nullifier and nullifier existence check should be traced expect(trace.traceNewNullifier).toHaveBeenCalledTimes(1); - expect(trace.traceNewNullifier).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*nullifier=*/ value0, - ); + expect(trace.traceNewNullifier).toHaveBeenCalledWith(expect.objectContaining(address), /*nullifier=*/ value0); expect(trace.traceNullifierCheck).toHaveBeenCalledTimes(1); // leafIndex is returned from DB call for nullifiers, so it is absent on DB miss expect(trace.traceNullifierCheck).toHaveBeenCalledWith( - storageAddress, + address, /*nullifier=*/ value0, /*leafIndex=*/ Fr.ZERO, /*exists=*/ true, @@ -625,10 +612,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { // Nullifier should be traced exactly once expect(trace.traceNewNullifier).toHaveBeenCalledTimes(1); - expect(trace.traceNewNullifier).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*nullifier=*/ value0, - ); + expect(trace.traceNewNullifier).toHaveBeenCalledWith(expect.objectContaining(address), /*nullifier=*/ value0); }); }); @@ -664,10 +648,10 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - expect(await context.persistableState.peekStorage(storageAddress, slot)).toEqual(value0); + expect(await context.persistableState.peekStorage(address, slot)).toEqual(value0); expect(trace.tracePublicStorageWrite).toHaveBeenCalledTimes(1); - expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, slot, value0); + expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(address, slot, value0); }); it('Should read value in storage (single)', async () => { @@ -682,7 +666,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(trace.tracePublicStorageRead).toHaveBeenCalledTimes(1); expect(trace.tracePublicStorageRead).toHaveBeenCalledWith( - storageAddress, + address, slot, value0, /*exists=*/ true, @@ -701,10 +685,10 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.output).toEqual([value0]); expect(trace.tracePublicStorageWrite).toHaveBeenCalledTimes(1); - expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, slot, value0); + expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(address, slot, value0); expect(trace.tracePublicStorageRead).toHaveBeenCalledTimes(1); expect(trace.tracePublicStorageRead).toHaveBeenCalledWith( - storageAddress, + address, slot, value0, /*exists=*/ true, @@ -721,12 +705,12 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - expect(await context.persistableState.peekStorage(storageAddress, listSlot0)).toEqual(calldata[0]); - expect(await context.persistableState.peekStorage(storageAddress, listSlot1)).toEqual(calldata[1]); + expect(await context.persistableState.peekStorage(address, listSlot0)).toEqual(calldata[0]); + expect(await context.persistableState.peekStorage(address, listSlot1)).toEqual(calldata[1]); expect(trace.tracePublicStorageWrite).toHaveBeenCalledTimes(2); - expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, listSlot0, value0); - expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, listSlot1, value1); + expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(address, listSlot0, value0); + expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(address, listSlot1, value1); }); it('Should read a value in storage (list)', async () => { @@ -744,14 +728,14 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.output).toEqual([value0, value1]); expect(trace.tracePublicStorageRead).toHaveBeenCalledWith( - storageAddress, + address, listSlot0, value0, /*exists=*/ true, /*cached=*/ false, ); expect(trace.tracePublicStorageRead).toHaveBeenCalledWith( - storageAddress, + address, listSlot1, value1, /*exists=*/ true, @@ -760,7 +744,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { }); it('Should set a value in storage (map)', async () => { - const calldata = [storageAddress, value0]; + const calldata = [address, value0]; const context = createContext(calldata); const bytecode = getAvmTestContractBytecode('set_storage_map'); @@ -772,14 +756,14 @@ describe('AVM simulator: transpiled Noir contracts', () => { const mapSlotNumber = results.output[0].toBigInt(); const mapSlot = new Fr(mapSlotNumber); - expect(await context.persistableState.peekStorage(storageAddress, mapSlot)).toEqual(value0); + expect(await context.persistableState.peekStorage(address, mapSlot)).toEqual(value0); expect(trace.tracePublicStorageWrite).toHaveBeenCalledTimes(1); - expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, mapSlot, value0); + expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(address, mapSlot, value0); }); it('Should read-add-set a value in storage (map)', async () => { - const calldata = [storageAddress, value0]; + const calldata = [address, value0]; const context = createContext(calldata); const bytecode = getAvmTestContractBytecode('add_storage_map'); @@ -791,22 +775,22 @@ describe('AVM simulator: transpiled Noir contracts', () => { const mapSlotNumber = results.output[0].toBigInt(); const mapSlot = new Fr(mapSlotNumber); - expect(await context.persistableState.peekStorage(storageAddress, mapSlot)).toEqual(value0); + expect(await context.persistableState.peekStorage(address, mapSlot)).toEqual(value0); expect(trace.tracePublicStorageRead).toHaveBeenCalledTimes(1); expect(trace.tracePublicStorageRead).toHaveBeenCalledWith( - storageAddress, + address, mapSlot, Fr.ZERO, /*exists=*/ false, /*cached=*/ false, ); expect(trace.tracePublicStorageWrite).toHaveBeenCalledTimes(1); - expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, mapSlot, value0); + expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(address, mapSlot, value0); }); it('Should read value in storage (map)', async () => { - const calldata = [storageAddress]; + const calldata = [address]; const context = createContext(calldata); mockStorageRead(worldStateDB, value0); @@ -819,7 +803,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(trace.tracePublicStorageRead).toHaveBeenCalledTimes(1); // slot is the result of a pedersen hash and is therefore not known in the test expect(trace.tracePublicStorageRead).toHaveBeenCalledWith( - storageAddress, + address, expect.anything(), value0, /*exists=*/ true, diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index fb401245b66..f9560cf7f63 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -58,14 +58,12 @@ export function initPersistableStateManager(overrides?: { export function initExecutionEnvironment(overrides?: Partial): AvmExecutionEnvironment { return new AvmExecutionEnvironment( overrides?.address ?? AztecAddress.zero(), - overrides?.storageAddress ?? AztecAddress.zero(), overrides?.sender ?? AztecAddress.zero(), overrides?.functionSelector ?? FunctionSelector.empty(), overrides?.contractCallDepth ?? Fr.zero(), overrides?.transactionFee ?? Fr.zero(), overrides?.globals ?? GlobalVariables.empty(), overrides?.isStaticCall ?? false, - overrides?.isDelegateCall ?? false, overrides?.calldata ?? [], ); } diff --git a/yarn-project/simulator/src/avm/journal/journal.ts b/yarn-project/simulator/src/avm/journal/journal.ts index 81ea9759ac3..c6d2157f501 100644 --- a/yarn-project/simulator/src/avm/journal/journal.ts +++ b/yarn-project/simulator/src/avm/journal/journal.ts @@ -67,44 +67,44 @@ export class AvmPersistableStateManager { /** * Write to public storage, journal/trace the write. * - * @param storageAddress - the address of the contract whose storage is being written to + * @param contractAddress - the address of the contract whose storage is being written to * @param slot - the slot in the contract's storage being written to * @param value - the value being written to the slot */ - public writeStorage(storageAddress: Fr, slot: Fr, value: Fr) { - this.log.debug(`Storage write (address=${storageAddress}, slot=${slot}): value=${value}`); + public writeStorage(contractAddress: Fr, slot: Fr, value: Fr) { + this.log.debug(`Storage write (address=${contractAddress}, slot=${slot}): value=${value}`); // Cache storage writes for later reference/reads - this.publicStorage.write(storageAddress, slot, value); - this.trace.tracePublicStorageWrite(storageAddress, slot, value); + this.publicStorage.write(contractAddress, slot, value); + this.trace.tracePublicStorageWrite(contractAddress, slot, value); } /** * Read from public storage, trace the read. * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param slot - the slot in the contract's storage being read from * @returns the latest value written to slot, or 0 if never written to before */ - public async readStorage(storageAddress: Fr, slot: Fr): Promise { - const { value, exists, cached } = await this.publicStorage.read(storageAddress, slot); + public async readStorage(contractAddress: Fr, slot: Fr): Promise { + const { value, exists, cached } = await this.publicStorage.read(contractAddress, slot); this.log.debug( - `Storage read (address=${storageAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`, + `Storage read (address=${contractAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`, ); - this.trace.tracePublicStorageRead(storageAddress, slot, value, exists, cached); + this.trace.tracePublicStorageRead(contractAddress, slot, value, exists, cached); return Promise.resolve(value); } /** * Read from public storage, don't trace the read. * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param slot - the slot in the contract's storage being read from * @returns the latest value written to slot, or 0 if never written to before */ - public async peekStorage(storageAddress: Fr, slot: Fr): Promise { - const { value, exists, cached } = await this.publicStorage.read(storageAddress, slot); + public async peekStorage(contractAddress: Fr, slot: Fr): Promise { + const { value, exists, cached } = await this.publicStorage.read(contractAddress, slot); this.log.debug( - `Storage peek (address=${storageAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`, + `Storage peek (address=${contractAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`, ); return Promise.resolve(value); } @@ -113,20 +113,20 @@ export class AvmPersistableStateManager { /** * Check if a note hash exists at the given leaf index, trace the check. * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param noteHash - the unsiloed note hash being checked * @param leafIndex - the leaf index being checked * @returns true if the note hash exists at the given leaf index, false otherwise */ - public async checkNoteHashExists(storageAddress: Fr, noteHash: Fr, leafIndex: Fr): Promise { + public async checkNoteHashExists(contractAddress: Fr, noteHash: Fr, leafIndex: Fr): Promise { const gotLeafValue = (await this.worldStateDB.getCommitmentValue(leafIndex.toBigInt())) ?? Fr.ZERO; const exists = gotLeafValue.equals(noteHash); this.log.debug( - `noteHashes(${storageAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`, + `noteHashes(${contractAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`, ); // TODO(8287): We still return exists here, but we need to transmit both the requested noteHash and the gotLeafValue // such that the VM can constrain the equality and decide on exists based on that. - this.trace.traceNoteHashCheck(storageAddress, gotLeafValue, leafIndex, exists); + this.trace.traceNoteHashCheck(contractAddress, gotLeafValue, leafIndex, exists); return Promise.resolve(exists); } @@ -134,37 +134,37 @@ export class AvmPersistableStateManager { * Write a note hash, trace the write. * @param noteHash - the unsiloed note hash to write */ - public writeNoteHash(storageAddress: Fr, noteHash: Fr) { - this.log.debug(`noteHashes(${storageAddress}) += @${noteHash}.`); - this.trace.traceNewNoteHash(storageAddress, noteHash); + public writeNoteHash(contractAddress: Fr, noteHash: Fr) { + this.log.debug(`noteHashes(${contractAddress}) += @${noteHash}.`); + this.trace.traceNewNoteHash(contractAddress, noteHash); } /** * Check if a nullifier exists, trace the check. - * @param storageAddress - address of the contract that the nullifier is associated with + * @param contractAddress - address of the contract that the nullifier is associated with * @param nullifier - the unsiloed nullifier to check * @returns exists - whether the nullifier exists in the nullifier set */ - public async checkNullifierExists(storageAddress: Fr, nullifier: Fr): Promise { - const [exists, isPending, leafIndex] = await this.nullifiers.checkExists(storageAddress, nullifier); + public async checkNullifierExists(contractAddress: Fr, nullifier: Fr): Promise { + const [exists, isPending, leafIndex] = await this.nullifiers.checkExists(contractAddress, nullifier); this.log.debug( - `nullifiers(${storageAddress})@${nullifier} ?? leafIndex: ${leafIndex}, exists: ${exists}, pending: ${isPending}.`, + `nullifiers(${contractAddress})@${nullifier} ?? leafIndex: ${leafIndex}, exists: ${exists}, pending: ${isPending}.`, ); - this.trace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending); + this.trace.traceNullifierCheck(contractAddress, nullifier, leafIndex, exists, isPending); return Promise.resolve(exists); } /** * Write a nullifier to the nullifier set, trace the write. - * @param storageAddress - address of the contract that the nullifier is associated with + * @param contractAddress - address of the contract that the nullifier is associated with * @param nullifier - the unsiloed nullifier to write */ - public async writeNullifier(storageAddress: Fr, nullifier: Fr) { - this.log.debug(`nullifiers(${storageAddress}) += ${nullifier}.`); + public async writeNullifier(contractAddress: Fr, nullifier: Fr) { + this.log.debug(`nullifiers(${contractAddress}) += ${nullifier}.`); // Cache pending nullifiers for later access - await this.nullifiers.append(storageAddress, nullifier); + await this.nullifiers.append(contractAddress, nullifier); // Trace all nullifier creations (even reverted ones) - this.trace.traceNewNullifier(storageAddress, nullifier); + this.trace.traceNewNullifier(contractAddress, nullifier); } /** diff --git a/yarn-project/simulator/src/avm/journal/nullifiers.ts b/yarn-project/simulator/src/avm/journal/nullifiers.ts index a4d23a357e2..d1b3577fffc 100644 --- a/yarn-project/simulator/src/avm/journal/nullifiers.ts +++ b/yarn-project/simulator/src/avm/journal/nullifiers.ts @@ -37,17 +37,17 @@ export class NullifierManager { /** * Get a nullifier's existence in this' cache or parent's (recursively). * DOES NOT CHECK HOST STORAGE! - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param nullifier - the nullifier to check for * @returns exists: whether the nullifier exists in cache here or in parent's */ - private checkExistsHereOrParent(storageAddress: Fr, nullifier: Fr): boolean { + private checkExistsHereOrParent(contractAddress: Fr, nullifier: Fr): boolean { // First check this cache - let existsAsPending = this.cache.exists(storageAddress, nullifier); + let existsAsPending = this.cache.exists(contractAddress, nullifier); // Then try parent's nullifier cache if (!existsAsPending && this.parent) { // Note: this will recurse to grandparent/etc until a cache-hit is encountered. - existsAsPending = this.parent.checkExistsHereOrParent(storageAddress, nullifier); + existsAsPending = this.parent.checkExistsHereOrParent(contractAddress, nullifier); } return existsAsPending; } @@ -59,24 +59,24 @@ export class NullifierManager { * 3. Fall back to the host state. * 4. Not found! Nullifier does not exist. * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param nullifier - the nullifier to check for * @returns exists: whether the nullifier exists at all, * isPending: whether the nullifier was found in a cache, * leafIndex: the nullifier's leaf index if it exists and is not pending (comes from host state). */ public async checkExists( - storageAddress: Fr, + contractAddress: Fr, nullifier: Fr, ): Promise<[/*exists=*/ boolean, /*isPending=*/ boolean, /*leafIndex=*/ Fr]> { // Check this cache and parent's (recursively) - const existsAsPending = this.checkExistsHereOrParent(storageAddress, nullifier); + const existsAsPending = this.checkExistsHereOrParent(contractAddress, nullifier); // Finally try the host's Aztec state (a trip to the database) // If the value is found in the database, it will be associated with a leaf index! let leafIndex: bigint | undefined = undefined; if (!existsAsPending) { // silo the nullifier before checking for its existence in the host - leafIndex = await this.hostNullifiers.getNullifierIndex(siloNullifier(storageAddress, nullifier)); + leafIndex = await this.hostNullifiers.getNullifierIndex(siloNullifier(contractAddress, nullifier)); } const exists = existsAsPending || leafIndex !== undefined; leafIndex = leafIndex === undefined ? BigInt(0) : leafIndex; @@ -86,17 +86,17 @@ export class NullifierManager { /** * Stage a new nullifier (append it to the cache). * - * @param storageAddress - the address of the contract that the nullifier is associated with + * @param contractAddress - the address of the contract that the nullifier is associated with * @param nullifier - the nullifier to stage */ - public async append(storageAddress: Fr, nullifier: Fr) { - const [exists, ,] = await this.checkExists(storageAddress, nullifier); + public async append(contractAddress: Fr, nullifier: Fr) { + const [exists, ,] = await this.checkExists(contractAddress, nullifier); if (exists) { throw new NullifierCollisionError( - `Nullifier ${nullifier} at contract ${storageAddress} already exists in parent cache or host.`, + `Nullifier ${nullifier} at contract ${contractAddress} already exists in parent cache or host.`, ); } - this.cache.append(storageAddress, nullifier); + this.cache.append(contractAddress, nullifier); } /** @@ -135,35 +135,35 @@ export class NullifierCache { /** * Check whether a nullifier exists in the cache. * - * @param storageAddress - the address of the contract that the nullifier is associated with + * @param contractAddress - the address of the contract that the nullifier is associated with * @param nullifier - the nullifier to check existence of * @returns whether the nullifier is found in the cache */ - public exists(storageAddress: Fr, nullifier: Fr): boolean { + public exists(contractAddress: Fr, nullifier: Fr): boolean { const exists = - this.cachePerContract.get(storageAddress.toBigInt())?.has(nullifier.toBigInt()) || - this.siloedNullifiers.has(siloNullifier(AztecAddress.fromField(storageAddress), nullifier).toBigInt()); + this.cachePerContract.get(contractAddress.toBigInt())?.has(nullifier.toBigInt()) || + this.siloedNullifiers.has(siloNullifier(AztecAddress.fromField(contractAddress), nullifier).toBigInt()); return !!exists; } /** * Stage a new nullifier (append it to the cache). * - * @param storageAddress - the address of the contract that the nullifier is associated with + * @param contractAddress - the address of the contract that the nullifier is associated with * @param nullifier - the nullifier to stage */ - public append(storageAddress: Fr, nullifier: Fr) { - if (this.exists(storageAddress, nullifier)) { + public append(contractAddress: Fr, nullifier: Fr) { + if (this.exists(contractAddress, nullifier)) { throw new NullifierCollisionError( - `Nullifier ${nullifier} at contract ${storageAddress} already exists in cache.`, + `Nullifier ${nullifier} at contract ${contractAddress} already exists in cache.`, ); } - let nullifiersForContract = this.cachePerContract.get(storageAddress.toBigInt()); + let nullifiersForContract = this.cachePerContract.get(contractAddress.toBigInt()); // If this contract's nullifier set has no cached nullifiers, create a new Set to store them if (!nullifiersForContract) { nullifiersForContract = new Set(); - this.cachePerContract.set(storageAddress.toBigInt(), nullifiersForContract); + this.cachePerContract.set(contractAddress.toBigInt(), nullifiersForContract); } nullifiersForContract.add(nullifier.toBigInt()); } diff --git a/yarn-project/simulator/src/avm/journal/public_storage.ts b/yarn-project/simulator/src/avm/journal/public_storage.ts index 443717963db..62e32cba671 100644 --- a/yarn-project/simulator/src/avm/journal/public_storage.ts +++ b/yarn-project/simulator/src/avm/journal/public_storage.ts @@ -45,17 +45,17 @@ export class PublicStorage { * Read a storage value from this' cache or parent's (recursively). * DOES NOT CHECK HOST STORAGE! * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param slot - the slot in the contract's storage being read from * @returns value: the latest value written according to this cache or the parent's. undefined on cache miss. */ - public readHereOrParent(storageAddress: Fr, slot: Fr): Fr | undefined { + public readHereOrParent(contractAddress: Fr, slot: Fr): Fr | undefined { // First try check this storage cache - let value = this.cache.read(storageAddress, slot); + let value = this.cache.read(contractAddress, slot); // Then try parent's storage cache if (!value && this.parent) { // Note: this will recurse to grandparent/etc until a cache-hit is encountered. - value = this.parent.readHereOrParent(storageAddress, slot); + value = this.parent.readHereOrParent(contractAddress, slot); } return value; } @@ -67,17 +67,17 @@ export class PublicStorage { * 3. Fall back to the host state. * 4. Not found! Value has never been written to before. Flag it as non-existent and return value zero. * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param slot - the slot in the contract's storage being read from * @returns exists: whether the slot has EVER been written to before, value: the latest value written to slot, or 0 if never written to before */ - public async read(storageAddress: Fr, slot: Fr): Promise { + public async read(contractAddress: Fr, slot: Fr): Promise { let cached = false; // Check this cache and parent's (recursively) - let value = this.readHereOrParent(storageAddress, slot); + let value = this.readHereOrParent(contractAddress, slot); // Finally try the host's Aztec state (a trip to the database) if (!value) { - value = await this.hostPublicStorage.storageRead(storageAddress, slot); + value = await this.hostPublicStorage.storageRead(contractAddress, slot); // TODO(dbanks12): if value retrieved from host storage, we can cache it here // any future reads to the same slot can read from cache instead of more expensive // DB access @@ -93,12 +93,12 @@ export class PublicStorage { /** * Stage a storage write. * - * @param storageAddress - the address of the contract whose storage is being written to + * @param contractAddress - the address of the contract whose storage is being written to * @param slot - the slot in the contract's storage being written to * @param value - the value being written to the slot */ - public write(storageAddress: Fr, slot: Fr, value: Fr) { - this.cache.write(storageAddress, slot, value); + public write(contractAddress: Fr, slot: Fr, value: Fr) { + this.cache.write(contractAddress, slot, value); } /** @@ -114,9 +114,9 @@ export class PublicStorage { * Commits ALL staged writes to the host's state. */ public async commitToDB() { - for (const [storageAddress, cacheAtContract] of this.cache.cachePerContract) { + for (const [contractAddress, cacheAtContract] of this.cache.cachePerContract) { for (const [slot, value] of cacheAtContract) { - await this.hostPublicStorage.storageWrite(AztecAddress.fromBigInt(storageAddress), new Fr(slot), value); + await this.hostPublicStorage.storageWrite(AztecAddress.fromBigInt(contractAddress), new Fr(slot), value); } } } @@ -139,27 +139,27 @@ class PublicStorageCache { /** * Read a staged value from storage, if it has been previously written to. * - * @param storageAddress - the address of the contract whose storage is being read from + * @param contractAddress - the address of the contract whose storage is being read from * @param slot - the slot in the contract's storage being read from * @returns the latest value written to slot, or undefined if no value has been written */ - public read(storageAddress: Fr, slot: Fr): Fr | undefined { - return this.cachePerContract.get(storageAddress.toBigInt())?.get(slot.toBigInt()); + public read(contractAddress: Fr, slot: Fr): Fr | undefined { + return this.cachePerContract.get(contractAddress.toBigInt())?.get(slot.toBigInt()); } /** * Stage a storage write. * - * @param storageAddress - the address of the contract whose storage is being written to + * @param contractAddress - the address of the contract whose storage is being written to * @param slot - the slot in the contract's storage being written to * @param value - the value being written to the slot */ - public write(storageAddress: Fr, slot: Fr, value: Fr) { - let cacheAtContract = this.cachePerContract.get(storageAddress.toBigInt()); + public write(contractAddress: Fr, slot: Fr, value: Fr) { + let cacheAtContract = this.cachePerContract.get(contractAddress.toBigInt()); if (!cacheAtContract) { // If this contract's storage has no staged modifications, create a new inner map to store them cacheAtContract = new Map(); - this.cachePerContract.set(storageAddress.toBigInt(), cacheAtContract); + this.cachePerContract.set(contractAddress.toBigInt(), cacheAtContract); } cacheAtContract.set(slot.toBigInt(), value); } diff --git a/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts b/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts index 93c2ed3b86e..96a7cbb5340 100644 --- a/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts @@ -27,7 +27,6 @@ describe('Accrued Substate', () => { let context: AvmContext; const address = new Fr(1); - const storageAddress = new Fr(2); const sender = new Fr(42); const value0 = new Fr(69); // noteHash or nullifier... const value0Offset = 100; @@ -41,7 +40,7 @@ describe('Accrued Substate', () => { worldStateDB = mock(); trace = mock(); persistableState = initPersistableStateManager({ worldStateDB, trace }); - context = initContext({ persistableState, env: initExecutionEnvironment({ address, storageAddress, sender }) }); + context = initContext({ persistableState, env: initExecutionEnvironment({ address, sender }) }); }); describe('NoteHashExists', () => { @@ -96,7 +95,7 @@ describe('Accrued Substate', () => { const expectedValue = gotExists.toNumber() === 1 ? value0 : Fr.ZERO; expect(trace.traceNoteHashCheck).toHaveBeenCalledTimes(1); expect(trace.traceNoteHashCheck).toHaveBeenCalledWith( - storageAddress, + address, /*noteHash=*/ expectedValue, leafIndex, /*exists=*/ expectFound, @@ -122,10 +121,7 @@ describe('Accrued Substate', () => { context.machineState.memory.set(value0Offset, new Field(value0)); await new EmitNoteHash(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context); expect(trace.traceNewNoteHash).toHaveBeenCalledTimes(1); - expect(trace.traceNewNoteHash).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*noteHash=*/ value0, - ); + expect(trace.traceNewNoteHash).toHaveBeenCalledWith(expect.objectContaining(address), /*noteHash=*/ value0); }); }); @@ -152,18 +148,18 @@ describe('Accrued Substate', () => { describe.each([[/*exists=*/ false], [/*exists=*/ true]])('Nullifier checks', (exists: boolean) => { const existsStr = exists ? 'DOES exist' : 'does NOT exist'; it(`Should return ${exists} (and be traced) when noteHash ${existsStr}`, async () => { - const storageAddressOffset = 1; + const addressOffset = 1; if (exists) { mockNullifierExists(worldStateDB, leafIndex, value0); } context.machineState.memory.set(value0Offset, new Field(value0)); // nullifier - context.machineState.memory.set(storageAddressOffset, new Field(storageAddress)); + context.machineState.memory.set(addressOffset, new Field(address)); await new NullifierExists( /*indirect=*/ 0, /*nullifierOffset=*/ value0Offset, - storageAddressOffset, + addressOffset, existsOffset, ).execute(context); @@ -175,7 +171,7 @@ describe('Accrued Substate', () => { // leafIndex is returned from DB call for nullifiers, so it is absent on DB miss const tracedLeafIndex = exists && !isPending ? leafIndex : Fr.ZERO; expect(trace.traceNullifierCheck).toHaveBeenCalledWith( - storageAddress, + address, /*nullifier=*/ value0, tracedLeafIndex, exists, @@ -202,10 +198,7 @@ describe('Accrued Substate', () => { context.machineState.memory.set(value0Offset, new Field(value0)); await new EmitNullifier(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context); expect(trace.traceNewNullifier).toHaveBeenCalledTimes(1); - expect(trace.traceNewNullifier).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*nullifier=*/ value0, - ); + expect(trace.traceNewNullifier).toHaveBeenCalledWith(expect.objectContaining(address), /*nullifier=*/ value0); }); it('Nullifier collision reverts (same nullifier emitted twice)', async () => { @@ -213,14 +206,11 @@ describe('Accrued Substate', () => { await new EmitNullifier(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context); await expect(new EmitNullifier(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context)).rejects.toThrow( new InstructionExecutionError( - `Attempted to emit duplicate nullifier ${value0} (storage address: ${storageAddress}).`, + `Attempted to emit duplicate nullifier ${value0} (contract address: ${address}).`, ), ); expect(trace.traceNewNullifier).toHaveBeenCalledTimes(1); - expect(trace.traceNewNullifier).toHaveBeenCalledWith( - expect.objectContaining(storageAddress), - /*nullifier=*/ value0, - ); + expect(trace.traceNewNullifier).toHaveBeenCalledWith(expect.objectContaining(address), /*nullifier=*/ value0); }); it('Nullifier collision reverts (nullifier exists in host state)', async () => { @@ -228,7 +218,7 @@ describe('Accrued Substate', () => { context.machineState.memory.set(value0Offset, new Field(value0)); await expect(new EmitNullifier(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context)).rejects.toThrow( new InstructionExecutionError( - `Attempted to emit duplicate nullifier ${value0} (storage address: ${storageAddress}).`, + `Attempted to emit duplicate nullifier ${value0} (contract address: ${address}).`, ), ); expect(trace.traceNewNullifier).toHaveBeenCalledTimes(0); // the only attempt should fail before tracing diff --git a/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts b/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts index a1bfe0a63c4..a7701468dd1 100644 --- a/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts +++ b/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts @@ -39,11 +39,7 @@ export class NoteHashExists extends Instruction { const noteHash = memory.get(noteHashOffset).toFr(); const leafIndex = memory.get(leafIndexOffset).toFr(); - const exists = await context.persistableState.checkNoteHashExists( - context.environment.storageAddress, - noteHash, - leafIndex, - ); + const exists = await context.persistableState.checkNoteHashExists(context.environment.address, noteHash, leafIndex); memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0)); memory.assert({ reads: 2, writes: 1, addressing }); @@ -75,7 +71,7 @@ export class EmitNoteHash extends Instruction { } const noteHash = memory.get(noteHashOffset).toFr(); - context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash); + context.persistableState.writeNoteHash(context.environment.address, noteHash); memory.assert({ reads: 1, addressing }); context.machineState.incrementPc(); @@ -148,12 +144,12 @@ export class EmitNullifier extends Instruction { const nullifier = memory.get(nullifierOffset).toFr(); try { - await context.persistableState.writeNullifier(context.environment.storageAddress, nullifier); + await context.persistableState.writeNullifier(context.environment.address, nullifier); } catch (e) { if (e instanceof NullifierCollisionError) { // Error is known/expected, raise as InstructionExecutionError that the will lead the simulator to revert this call throw new InstructionExecutionError( - `Attempted to emit duplicate nullifier ${nullifier} (storage address: ${context.environment.storageAddress}).`, + `Attempted to emit duplicate nullifier ${nullifier} (contract address: ${context.environment.address}).`, ); } else { throw e; diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts index 8f68d272b9d..6f30a861577 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts @@ -13,7 +13,6 @@ import { EnvironmentVariable, GetEnvVar } from './environment_getters.js'; describe('Environment getters', () => { const address = AztecAddress.random(); - const storageAddress = AztecAddress.random(); const sender = AztecAddress.random(); const functionSelector = FunctionSelectorType.random(); const transactionFee = Fr.random(); @@ -34,7 +33,6 @@ describe('Environment getters', () => { }); const env = initExecutionEnvironment({ address, - storageAddress, sender, functionSelector, transactionFee, @@ -64,7 +62,6 @@ describe('Environment getters', () => { describe.each([ [EnvironmentVariable.ADDRESS, address.toField()], - [EnvironmentVariable.STORAGEADDRESS, storageAddress.toField()], [EnvironmentVariable.SENDER, sender.toField()], [EnvironmentVariable.FUNCTIONSELECTOR, functionSelector.toField(), TypeTag.UINT32], [EnvironmentVariable.TRANSACTIONFEE, transactionFee.toField()], diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts index 1d47b6986aa..5bfb947d732 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts @@ -6,7 +6,6 @@ import { Instruction } from './instruction.js'; export enum EnvironmentVariable { ADDRESS, - STORAGEADDRESS, SENDER, FUNCTIONSELECTOR, TRANSACTIONFEE, @@ -25,8 +24,6 @@ function getValue(e: EnvironmentVariable, ctx: AvmContext) { switch (e) { case EnvironmentVariable.ADDRESS: return new Field(ctx.environment.address.toField()); - case EnvironmentVariable.STORAGEADDRESS: - return new Field(ctx.environment.storageAddress.toField()); case EnvironmentVariable.SENDER: return new Field(ctx.environment.sender.toField()); case EnvironmentVariable.FUNCTIONSELECTOR: diff --git a/yarn-project/simulator/src/avm/opcodes/storage.test.ts b/yarn-project/simulator/src/avm/opcodes/storage.test.ts index 74e55a51d9c..4676771757d 100644 --- a/yarn-project/simulator/src/avm/opcodes/storage.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/storage.test.ts @@ -19,7 +19,7 @@ describe('Storage Instructions', () => { persistableState = mock(); context = initContext({ persistableState: persistableState, - env: initExecutionEnvironment({ address, storageAddress: address }), + env: initExecutionEnvironment({ address }), }); }); @@ -52,7 +52,7 @@ describe('Storage Instructions', () => { it('Should not be able to write to storage in a static call', async () => { context = initContext({ persistableState: persistableState, - env: initExecutionEnvironment({ address, storageAddress: address, isStaticCall: true }), + env: initExecutionEnvironment({ address, isStaticCall: true }), }); const a = new Field(1n); diff --git a/yarn-project/simulator/src/avm/opcodes/storage.ts b/yarn-project/simulator/src/avm/opcodes/storage.ts index 8639d3dd818..77d161030e7 100644 --- a/yarn-project/simulator/src/avm/opcodes/storage.ts +++ b/yarn-project/simulator/src/avm/opcodes/storage.ts @@ -43,7 +43,7 @@ export class SStore extends BaseStorageInstruction { const slot = memory.get(slotOffset).toFr(); const value = memory.get(srcOffset).toFr(); - context.persistableState.writeStorage(context.environment.storageAddress, slot, value); + context.persistableState.writeStorage(context.environment.address, slot, value); memory.assert({ reads: 2, addressing }); context.machineState.incrementPc(); @@ -68,7 +68,7 @@ export class SLoad extends BaseStorageInstruction { memory.checkTag(TypeTag.FIELD, slotOffset); const slot = memory.get(slotOffset).toFr(); - const value = await context.persistableState.readStorage(context.environment.storageAddress, slot); + const value = await context.persistableState.readStorage(context.environment.address, slot); memory.set(dstOffset, new Field(value)); context.machineState.incrementPc(); diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index 879a25279cb..3aa3a3ef733 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -131,7 +131,6 @@ const INSTRUCTION_SET = () => // Control Flow - Contract Calls [Call.opcode, Instruction.deserialize.bind(Call)], [StaticCall.opcode, Instruction.deserialize.bind(StaticCall)], - //[DelegateCall.opcode, Instruction.deserialize.bind(DelegateCall)], [Return.opcode, Instruction.deserialize.bind(Return)], [Opcode.REVERT_8, Revert.as(Revert.wireFormat8).deserialize], [Opcode.REVERT_16, Revert.as(Revert.wireFormat16).deserialize], diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index e9ea67945fd..0bbc75c5303 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -69,7 +69,6 @@ export enum Opcode { // External calls CALL, STATICCALL, - DELEGATECALL, RETURN, REVERT_8, REVERT_16, diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index 6e0c900c5e1..bd729f1dccb 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -68,7 +68,6 @@ export class ClientExecutionContext extends ViewDataOracle { private publicTeardownFunctionCall: PublicExecutionRequest = PublicExecutionRequest.empty(); constructor( - contractAddress: AztecAddress, private readonly argsHash: Fr, private readonly txContext: TxContext, private readonly callContext: CallContext, @@ -84,7 +83,7 @@ export class ClientExecutionContext extends ViewDataOracle { log = createDebugLogger('aztec:simulator:client_execution_context'), scopes?: AztecAddress[], ) { - super(contractAddress, authWitnesses, db, node, log, scopes); + super(callContext.contractAddress, authWitnesses, db, node, log, scopes); } // We still need this function until we can get user-defined ordering of structs for fn arguments @@ -240,10 +239,10 @@ export class ClientExecutionContext extends ViewDataOracle { status: NoteStatus, ): Promise { // Nullified pending notes are already removed from the list. - const pendingNotes = this.noteCache.getNotes(this.callContext.storageContractAddress, storageSlot); + const pendingNotes = this.noteCache.getNotes(this.callContext.contractAddress, storageSlot); - const pendingNullifiers = this.noteCache.getNullifiers(this.callContext.storageContractAddress); - const dbNotes = await this.db.getNotes(this.callContext.storageContractAddress, storageSlot, status, this.scopes); + const pendingNullifiers = this.noteCache.getNullifiers(this.callContext.contractAddress); + const dbNotes = await this.db.getNotes(this.callContext.contractAddress, storageSlot, status, this.scopes); const dbNotesFiltered = dbNotes.filter(n => !pendingNullifiers.has((n.siloedNullifier as Fr).value)); const notes = pickNotes([...dbNotesFiltered, ...pendingNotes], { @@ -261,7 +260,7 @@ export class ClientExecutionContext extends ViewDataOracle { }); this.log.debug( - `Returning ${notes.length} notes for ${this.callContext.storageContractAddress} at ${storageSlot}: ${notes + `Returning ${notes.length} notes for ${this.callContext.contractAddress} at ${storageSlot}: ${notes .map(n => `${n.nonce.toString()}:[${n.note.items.map(i => i.toString()).join(',')}]`) .join(', ')}`, ); @@ -297,7 +296,7 @@ export class ClientExecutionContext extends ViewDataOracle { const note = new Note(noteItems); this.noteCache.addNewNote( { - contractAddress: this.callContext.storageContractAddress, + contractAddress: this.callContext.contractAddress, storageSlot, nonce: Fr.ZERO, // Nonce cannot be known during private execution. note, @@ -317,7 +316,7 @@ export class ClientExecutionContext extends ViewDataOracle { */ public override notifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, counter: number) { const nullifiedNoteHashCounter = this.noteCache.nullifyNote( - this.callContext.storageContractAddress, + this.callContext.contractAddress, innerNullifier, noteHash, ); @@ -391,11 +390,11 @@ export class ClientExecutionContext extends ViewDataOracle { #checkValidStaticCall(childExecutionResult: PrivateExecutionResult) { if ( - childExecutionResult.callStackItem.publicInputs.noteHashes.some(item => !item.isEmpty()) || - childExecutionResult.callStackItem.publicInputs.nullifiers.some(item => !item.isEmpty()) || - childExecutionResult.callStackItem.publicInputs.l2ToL1Msgs.some(item => !item.isEmpty()) || - childExecutionResult.callStackItem.publicInputs.encryptedLogsHashes.some(item => !item.isEmpty()) || - childExecutionResult.callStackItem.publicInputs.unencryptedLogsHashes.some(item => !item.isEmpty()) + childExecutionResult.publicInputs.noteHashes.some(item => !item.isEmpty()) || + childExecutionResult.publicInputs.nullifiers.some(item => !item.isEmpty()) || + childExecutionResult.publicInputs.l2ToL1Msgs.some(item => !item.isEmpty()) || + childExecutionResult.publicInputs.encryptedLogsHashes.some(item => !item.isEmpty()) || + childExecutionResult.publicInputs.unencryptedLogsHashes.some(item => !item.isEmpty()) ) { throw new Error(`Static call cannot update the state, emit L2->L1 messages or generate logs`); } @@ -408,7 +407,6 @@ export class ClientExecutionContext extends ViewDataOracle { * @param argsHash - The packed arguments to pass to the function. * @param sideEffectCounter - The side effect counter at the start of the call. * @param isStaticCall - Whether the call is a static call. - * @param isDelegateCall - Whether the call is a delegate call. * @returns The execution result. */ override async callPrivateFunction( @@ -417,10 +415,9 @@ export class ClientExecutionContext extends ViewDataOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ) { this.log.debug( - `Calling private function ${this.contractAddress}:${functionSelector} from ${this.callContext.storageContractAddress}`, + `Calling private function ${this.contractAddress}:${functionSelector} from ${this.callContext.contractAddress}`, ); isStaticCall = isStaticCall || this.callContext.isStaticCall; @@ -429,15 +426,9 @@ export class ClientExecutionContext extends ViewDataOracle { const derivedTxContext = this.txContext.clone(); - const derivedCallContext = this.deriveCallContext( - targetContractAddress, - targetArtifact, - isDelegateCall, - isStaticCall, - ); + const derivedCallContext = this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall); const context = new ClientExecutionContext( - targetContractAddress, argsHash, derivedTxContext, derivedCallContext, @@ -465,7 +456,7 @@ export class ClientExecutionContext extends ViewDataOracle { this.nestedExecutions.push(childExecutionResult); - const publicInputs = childExecutionResult.callStackItem.publicInputs; + const publicInputs = childExecutionResult.publicInputs; return { endSideEffectCounter: publicInputs.endSideEffectCounter, returnsHash: publicInputs.returnsHash, @@ -473,7 +464,7 @@ export class ClientExecutionContext extends ViewDataOracle { } /** - * Creates a PublicCallStackItem object representing the request to call a public function. + * Creates a PublicExecutionRequest object representing the request to call a public function. * @param targetContractAddress - The address of the contract to call. * @param functionSelector - The function selector of the function to call. * @param argsHash - The packed arguments to pass to the function. @@ -488,15 +479,9 @@ export class ClientExecutionContext extends ViewDataOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ) { const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector); - const derivedCallContext = this.deriveCallContext( - targetContractAddress, - targetArtifact, - isDelegateCall, - isStaticCall, - ); + const derivedCallContext = this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall); const args = this.packedValuesCache.unpack(argsHash); this.log.verbose( @@ -506,7 +491,6 @@ export class ClientExecutionContext extends ViewDataOracle { const request = PublicExecutionRequest.from({ args, callContext: derivedCallContext, - contractAddress: targetContractAddress, }); if (callType === 'enqueued') { @@ -517,7 +501,7 @@ export class ClientExecutionContext extends ViewDataOracle { } /** - * Creates and enqueues a PublicCallStackItem object representing the request to call a public function. No function + * Creates and enqueues a PublicExecutionRequest object representing the request to call a public function. No function * is actually called, since that must happen on the sequencer side. All the fields related to the result * of the execution are empty. * @param targetContractAddress - The address of the contract to call. @@ -533,7 +517,6 @@ export class ClientExecutionContext extends ViewDataOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ): Promise { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this. // WARNING: This is insecure and should be temporary! @@ -552,13 +535,12 @@ export class ClientExecutionContext extends ViewDataOracle { newArgsHash, sideEffectCounter, isStaticCall, - isDelegateCall, ); return newArgsHash; } /** - * Creates a PublicCallStackItem and sets it as the public teardown function. No function + * Creates a PublicExecutionRequest and sets it as the public teardown function. No function * is actually called, since that must happen on the sequencer side. All the fields related to the result * of the execution are empty. * @param targetContractAddress - The address of the contract to call. @@ -574,7 +556,6 @@ export class ClientExecutionContext extends ViewDataOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ): Promise { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this. // WARNING: This is insecure and should be temporary! @@ -593,7 +574,6 @@ export class ClientExecutionContext extends ViewDataOracle { newArgsHash, sideEffectCounter, isStaticCall, - isDelegateCall, ); return newArgsHash; } @@ -606,21 +586,18 @@ export class ClientExecutionContext extends ViewDataOracle { * Derives the call context for a nested execution. * @param targetContractAddress - The address of the contract being called. * @param targetArtifact - The artifact of the function being called. - * @param isDelegateCall - Whether the call is a delegate call. * @param isStaticCall - Whether the call is a static call. * @returns The derived call context. */ private deriveCallContext( targetContractAddress: AztecAddress, targetArtifact: FunctionArtifact, - isDelegateCall = false, isStaticCall = false, ) { return new CallContext( - isDelegateCall ? this.callContext.msgSender : this.contractAddress, - isDelegateCall ? this.contractAddress : targetContractAddress, + this.contractAddress, + targetContractAddress, FunctionSelector.fromNameAndParameters(targetArtifact.name, targetArtifact.parameters), - isDelegateCall, isStaticCall, ); } diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 0b6205a05d8..3d6c21720ef 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -277,7 +277,7 @@ describe('Private Execution test suite', () => { const args = [times(5, () => Fr.random()), owner, outgoingViewer, false]; const result = await runSimulator({ artifact, msgSender: owner, args }); - const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.encryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(result.publicInputs.encryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(1); const functionLogs = collectSortedEncryptedLogs(result); expect(functionLogs.logs).toHaveLength(1); @@ -287,7 +287,10 @@ describe('Private Execution test suite', () => { expect(encryptedLog.length).toEqual(new Fr(functionLogs.getKernelLength())); // 5 is hardcoded in the test contract expect(encryptedLog.randomness).toEqual(new Fr(5)); - const expectedMaskedAddress = poseidon2HashWithSeparator([result.callStackItem.contractAddress, new Fr(5)], 0); + const expectedMaskedAddress = poseidon2HashWithSeparator( + [result.publicInputs.callContext.contractAddress, new Fr(5)], + 0, + ); expect(expectedMaskedAddress).toEqual(functionLogs.logs[0].maskedContractAddress); }); }); @@ -347,13 +350,13 @@ describe('Private Execution test suite', () => { expect(newNote.storageSlot).toEqual(deriveStorageSlotInMap(new Fr(1n), owner)); expect(newNote.noteTypeId).toEqual(valueNoteTypeId); // ValueNote - const noteHashes = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes); + const noteHashes = getNonEmptyItems(result.publicInputs.noteHashes); expect(noteHashes).toHaveLength(1); expect(noteHashes[0].value).toEqual( await acirSimulator.computeNoteHash(contractAddress, newNote.storageSlot, newNote.noteTypeId, newNote.note), ); - const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(result.publicInputs.noteEncryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(1); const [encryptedLog] = newEncryptedLogs; @@ -372,13 +375,13 @@ describe('Private Execution test suite', () => { expect(newNote.storageSlot).toEqual(deriveStorageSlotInMap(new Fr(1n), owner)); expect(newNote.noteTypeId).toEqual(valueNoteTypeId); // ValueNote - const noteHashes = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes); + const noteHashes = getNonEmptyItems(result.publicInputs.noteHashes); expect(noteHashes).toHaveLength(1); expect(noteHashes[0].value).toEqual( await acirSimulator.computeNoteHash(contractAddress, newNote.storageSlot, newNote.noteTypeId, newNote.note), ); - const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(result.publicInputs.noteEncryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(1); const [encryptedLog] = newEncryptedLogs; @@ -419,7 +422,7 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ args, artifact, msgSender: owner }); // The two notes were nullified - const nullifiers = getNonEmptyItems(result.callStackItem.publicInputs.nullifiers).map(n => n.value); + const nullifiers = getNonEmptyItems(result.publicInputs.nullifiers).map(n => n.value); expect(nullifiers).toHaveLength(consumedNotes.length); expect(nullifiers).toEqual(expect.arrayContaining(consumedNotes.map(n => n.innerNullifier))); @@ -428,32 +431,32 @@ describe('Private Execution test suite', () => { expect(recipientNote.storageSlot).toEqual(recipientStorageSlot); expect(recipientNote.noteTypeId).toEqual(valueNoteTypeId); - const noteHashesFromCallStackItem = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes); - expect(noteHashesFromCallStackItem).toHaveLength(2); - const [changeNoteHashFromCallStackItem, recipientNoteHashFromCallStackItem] = noteHashesFromCallStackItem; - const [changeNoteHash, recipientNoteHash] = [ + const noteHashes = getNonEmptyItems(result.publicInputs.noteHashes); + expect(noteHashes).toHaveLength(2); + const [changeNoteHash, recipientNoteHash] = noteHashes; + const [siloedChangeNoteHash, siloedRecipientNoteHash] = [ await acirSimulator.computeNoteHash(contractAddress, storageSlot, valueNoteTypeId, changeNote.note), await acirSimulator.computeNoteHash(contractAddress, recipientStorageSlot, valueNoteTypeId, recipientNote.note), ]; - expect(changeNoteHashFromCallStackItem.value).toEqual(changeNoteHash); - expect(recipientNoteHashFromCallStackItem.value).toEqual(recipientNoteHash); + expect(changeNoteHash.value).toEqual(siloedChangeNoteHash); + expect(recipientNoteHash.value).toEqual(siloedRecipientNoteHash); expect(recipientNote.note.items[0]).toEqual(new Fr(amountToTransfer)); expect(changeNote.note.items[0]).toEqual(new Fr(40n)); - const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(result.publicInputs.noteEncryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(2); const [encryptedChangeLog, encryptedRecipientLog] = newEncryptedLogs; expect(encryptedChangeLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[0].log.hash())); - expect(encryptedChangeLog.noteHashCounter).toEqual(changeNoteHashFromCallStackItem.counter); + expect(encryptedChangeLog.noteHashCounter).toEqual(changeNoteHash.counter); expect(encryptedRecipientLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[1].log.hash())); - expect(encryptedRecipientLog.noteHashCounter).toEqual(recipientNoteHashFromCallStackItem.counter); + expect(encryptedRecipientLog.noteHashCounter).toEqual(recipientNoteHash.counter); expect(encryptedChangeLog.length.add(encryptedRecipientLog.length)).toEqual( new Fr(getEncryptedNoteSerializedLength(result)), ); - const readRequests = getNonEmptyItems(result.callStackItem.publicInputs.noteHashReadRequests).map(r => r.value); + const readRequests = getNonEmptyItems(result.publicInputs.noteHashReadRequests).map(r => r.value); expect(readRequests).toHaveLength(consumedNotes.length); expect(readRequests).toEqual(expect.arrayContaining(consumedNotes.map(n => n.uniqueNoteHash))); }); @@ -490,7 +493,7 @@ describe('Private Execution test suite', () => { const args = [recipient, amountToTransfer]; const result = await runSimulator({ args, artifact, msgSender: owner }); - const nullifiers = getNonEmptyItems(result.callStackItem.publicInputs.nullifiers).map(n => n.value); + const nullifiers = getNonEmptyItems(result.publicInputs.nullifiers).map(n => n.value); expect(nullifiers).toEqual(consumedNotes.map(n => n.innerNullifier)); expect(result.newNotes).toHaveLength(2); @@ -498,13 +501,13 @@ describe('Private Execution test suite', () => { expect(recipientNote.note.items[0]).toEqual(new Fr(amountToTransfer)); expect(changeNote.note.items[0]).toEqual(new Fr(balance - amountToTransfer)); - const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(result.publicInputs.noteEncryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(2); const [encryptedChangeLog, encryptedRecipientLog] = newEncryptedLogs; expect(encryptedChangeLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[0].log.hash())); - expect(encryptedChangeLog.noteHashCounter).toEqual(result.callStackItem.publicInputs.noteHashes[0].counter); + expect(encryptedChangeLog.noteHashCounter).toEqual(result.publicInputs.noteHashes[0].counter); expect(encryptedRecipientLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[1].log.hash())); - expect(encryptedRecipientLog.noteHashCounter).toEqual(result.callStackItem.publicInputs.noteHashes[1].counter); + expect(encryptedRecipientLog.noteHashCounter).toEqual(result.publicInputs.noteHashes[1].counter); expect(encryptedChangeLog.length.add(encryptedRecipientLog.length)).toEqual( new Fr(getEncryptedNoteSerializedLength(result)), ); @@ -542,13 +545,9 @@ describe('Private Execution test suite', () => { expect(oracle.getFunctionArtifact.mock.calls[0]).toEqual([childAddress, childSelector]); expect(result.nestedExecutions).toHaveLength(1); expect(result.nestedExecutions[0].returnValues).toEqual([new Fr(privateIncrement)]); - - // check that Aztec.nr calculated the call stack item hash like cpp does - expect( - result.callStackItem.publicInputs.privateCallRequests[0].matchesStackItem( - result.nestedExecutions[0].callStackItem, - ), - ).toBeTruthy(); + expect(result.publicInputs.privateCallRequests[0].callContext).toEqual( + result.nestedExecutions[0].publicInputs.callContext, + ); }); }); @@ -661,7 +660,7 @@ describe('Private Execution test suite', () => { }); // Check a nullifier has been inserted - const nullifiers = getNonEmptyItems(result.callStackItem.publicInputs.nullifiers); + const nullifiers = getNonEmptyItems(result.publicInputs.nullifiers); expect(nullifiers).toHaveLength(1); }); @@ -824,11 +823,11 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ artifact, args: [secret] }); // Check a nullifier has been inserted. - const nullifiers = getNonEmptyItems(result.callStackItem.publicInputs.nullifiers); + const nullifiers = getNonEmptyItems(result.publicInputs.nullifiers); expect(nullifiers).toHaveLength(1); // Check the commitment read request was created successfully. - const readRequests = getNonEmptyItems(result.callStackItem.publicInputs.noteHashReadRequests); + const readRequests = getNonEmptyItems(result.publicInputs.noteHashReadRequests); expect(readRequests).toHaveLength(1); }); }); @@ -854,13 +853,11 @@ describe('Private Execution test suite', () => { const request = new CountedPublicExecutionRequest( PublicExecutionRequest.from({ - contractAddress: childAddress, args: [childSelector.toField(), new Fr(42n)], callContext: CallContext.from({ msgSender: parentAddress, - storageContractAddress: childAddress, + contractAddress: childAddress, functionSelector: FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)), - isDelegateCall: false, isStaticCall: false, }), }), @@ -890,14 +887,14 @@ describe('Private Execution test suite', () => { const entrypoint = getFunctionArtifact(TestContractArtifact, 'get_this_address'); const contractAddress = AztecAddress.random(); const result = await runSimulator({ artifact: entrypoint, contractAddress }); - expect(result.callStackItem.publicInputs.isFeePayer).toBe(false); + expect(result.publicInputs.isFeePayer).toBe(false); }); it('should be able to set a fee payer', async () => { const entrypoint = getFunctionArtifact(TestContractArtifact, 'test_setting_fee_payer'); const contractAddress = AztecAddress.random(); const result = await runSimulator({ artifact: entrypoint, contractAddress }); - expect(result.callStackItem.publicInputs.isFeePayer).toBe(true); + expect(result.publicInputs.isFeePayer).toBe(true); }); }); @@ -935,10 +932,10 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const noteHashesFromCallStackItem = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes); - expect(noteHashesFromCallStackItem).toHaveLength(1); + const noteHashesFromCall = getNonEmptyItems(result.publicInputs.noteHashes); + expect(noteHashesFromCall).toHaveLength(1); - const noteHashFromCallStackItem = noteHashesFromCallStackItem[0].value; + const noteHashFromCall = noteHashesFromCall[0].value; const storageSlot = deriveStorageSlotInMap( PendingNoteHashesContractArtifact.storageLayout['balances'].slot, owner, @@ -950,23 +947,23 @@ describe('Private Execution test suite', () => { valueNoteTypeId, noteAndSlot.note, ); - expect(noteHashFromCallStackItem).toEqual(derivedNoteHash); + expect(noteHashFromCall).toEqual(derivedNoteHash); - const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(result.publicInputs.noteEncryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(1); const [encryptedLog] = newEncryptedLogs; - expect(encryptedLog.noteHashCounter).toEqual(noteHashesFromCallStackItem[0].counter); + expect(encryptedLog.noteHashCounter).toEqual(noteHashesFromCall[0].counter); expect(encryptedLog.noteHashCounter).toEqual(result.noteEncryptedLogs[0].noteHashCounter); expect(encryptedLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[0].log.hash())); // read request should match a note hash for pending notes (there is no nonce, so can't compute "unique" hash) - const readRequest = getNonEmptyItems(result.callStackItem.publicInputs.noteHashReadRequests)[0]; + const readRequest = getNonEmptyItems(result.publicInputs.noteHashReadRequests)[0]; expect(readRequest.value).toEqual(derivedNoteHash); expect(result.returnValues).toEqual([new Fr(amountToTransfer)]); - const nullifier = result.callStackItem.publicInputs.nullifiers[0]; + const nullifier = result.publicInputs.nullifiers[0]; const expectedNullifier = poseidon2HashWithSeparator( [derivedNoteHash, computeAppNullifierSecretKey(ownerNskM, contractAddress)], GeneratorIndex.NOTE_NULLIFIER, @@ -1023,19 +1020,18 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const noteHashes = getNonEmptyItems(execInsert.callStackItem.publicInputs.noteHashes); + const noteHashes = getNonEmptyItems(execInsert.publicInputs.noteHashes); expect(noteHashes).toHaveLength(1); - const noteHashFromCallStackItem = noteHashes[0].value; const derivedNoteHash = await acirSimulator.computeNoteHash( contractAddress, noteAndSlot.storageSlot, noteAndSlot.noteTypeId, noteAndSlot.note, ); - expect(noteHashFromCallStackItem).toEqual(derivedNoteHash); + expect(noteHashes[0].value).toEqual(derivedNoteHash); - const newEncryptedLogs = getNonEmptyItems(execInsert.callStackItem.publicInputs.noteEncryptedLogsHashes); + const newEncryptedLogs = getNonEmptyItems(execInsert.publicInputs.noteEncryptedLogsHashes); expect(newEncryptedLogs).toHaveLength(1); const [encryptedLog] = newEncryptedLogs; @@ -1044,12 +1040,12 @@ describe('Private Execution test suite', () => { expect(encryptedLog.value).toEqual(Fr.fromBuffer(execInsert.noteEncryptedLogs[0].log.hash())); // read request should match a note hash for pending notes (there is no nonce, so can't compute "unique" hash) - const readRequest = execGetThenNullify.callStackItem.publicInputs.noteHashReadRequests[0]; + const readRequest = execGetThenNullify.publicInputs.noteHashReadRequests[0]; expect(readRequest.value).toEqual(derivedNoteHash); expect(execGetThenNullify.returnValues).toEqual([new Fr(amountToTransfer)]); - const nullifier = execGetThenNullify.callStackItem.publicInputs.nullifiers[0]; + const nullifier = execGetThenNullify.publicInputs.nullifiers[0]; const expectedNullifier = poseidon2HashWithSeparator( [derivedNoteHash, computeAppNullifierSecretKey(ownerNskM, contractAddress)], GeneratorIndex.NOTE_NULLIFIER, diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index 83e2245d21b..662cfd13222 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -2,10 +2,8 @@ import { PrivateExecutionResult } from '@aztec/circuit-types'; import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; import { Fr, - FunctionData, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, PRIVATE_CONTEXT_INPUTS_LENGTH, - PrivateCallStackItem, PrivateCircuitPublicInputs, } from '@aztec/circuits.js'; import { type FunctionArtifact, type FunctionSelector, countArgumentsSize } from '@aztec/foundation/abi'; @@ -64,12 +62,6 @@ export async function executePrivateFunction( const encryptedLogs = context.getEncryptedLogs(); const unencryptedLogs = context.getUnencryptedLogs(); - const callStackItem = new PrivateCallStackItem( - contractAddress, - new FunctionData(functionSelector, true), - publicInputs, - ); - const rawReturnValues = await context.unpackReturns(publicInputs.returnsHash); const noteHashLeafIndexMap = context.getNoteHashLeafIndexMap(); @@ -85,7 +77,7 @@ export async function executePrivateFunction( acir, Buffer.from(artifact.verificationKey!, 'hex'), partialWitness, - callStackItem, + publicInputs, noteHashLeafIndexMap, newNotes, noteHashNullifierCounterMap, diff --git a/yarn-project/simulator/src/client/simulator.ts b/yarn-project/simulator/src/client/simulator.ts index e1b946b07e2..d434f75fa28 100644 --- a/yarn-project/simulator/src/client/simulator.ts +++ b/yarn-project/simulator/src/client/simulator.ts @@ -66,14 +66,12 @@ export class AcirSimulator { msgSender, contractAddress, FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters), - false, entryPointArtifact.isStatic, ); const txHash = request.toTxRequest().hash(); const context = new ClientExecutionContext( - contractAddress, request.firstCallArgsHash, request.txContext, callContext, diff --git a/yarn-project/simulator/src/mocks/fixtures.ts b/yarn-project/simulator/src/mocks/fixtures.ts index 00e0797123a..ccba4e58f8d 100644 --- a/yarn-project/simulator/src/mocks/fixtures.ts +++ b/yarn-project/simulator/src/mocks/fixtures.ts @@ -79,7 +79,7 @@ export class PublicExecutionResultBuilder { revertReason?: SimulationError; }) { const builder = new PublicExecutionResultBuilder( - new PublicExecutionRequest(tx.to, new CallContext(from, tx.to, tx.selector, false, false), tx.args), + new PublicExecutionRequest(new CallContext(from, tx.to, tx.selector, false), tx.args), ); builder.withNestedExecutions(...nestedExecutions); diff --git a/yarn-project/simulator/src/public/dual_side_effect_trace.ts b/yarn-project/simulator/src/public/dual_side_effect_trace.ts index 483f0f188ff..f2c82196605 100644 --- a/yarn-project/simulator/src/public/dual_side_effect_trace.ts +++ b/yarn-project/simulator/src/public/dual_side_effect_trace.ts @@ -32,35 +32,35 @@ export class DualSideEffectTrace implements PublicSideEffectTraceInterface { return this.innerCallTrace.getCounter(); } - public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean) { - this.innerCallTrace.tracePublicStorageRead(storageAddress, slot, value, exists, cached); - this.enqueuedCallTrace.tracePublicStorageRead(storageAddress, slot, value, exists, cached); + public tracePublicStorageRead(contractAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean) { + this.innerCallTrace.tracePublicStorageRead(contractAddress, slot, value, exists, cached); + this.enqueuedCallTrace.tracePublicStorageRead(contractAddress, slot, value, exists, cached); } - public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) { - this.innerCallTrace.tracePublicStorageWrite(storageAddress, slot, value); - this.enqueuedCallTrace.tracePublicStorageWrite(storageAddress, slot, value); + public tracePublicStorageWrite(contractAddress: Fr, slot: Fr, value: Fr) { + this.innerCallTrace.tracePublicStorageWrite(contractAddress, slot, value); + this.enqueuedCallTrace.tracePublicStorageWrite(contractAddress, slot, value); } // TODO(8287): _exists can be removed once we have the vm properly handling the equality check - public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { - this.innerCallTrace.traceNoteHashCheck(_storageAddress, noteHash, leafIndex, exists); - this.enqueuedCallTrace.traceNoteHashCheck(_storageAddress, noteHash, leafIndex, exists); + public traceNoteHashCheck(_contractAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { + this.innerCallTrace.traceNoteHashCheck(_contractAddress, noteHash, leafIndex, exists); + this.enqueuedCallTrace.traceNoteHashCheck(_contractAddress, noteHash, leafIndex, exists); } - public traceNewNoteHash(_storageAddress: Fr, noteHash: Fr) { - this.innerCallTrace.traceNewNoteHash(_storageAddress, noteHash); - this.enqueuedCallTrace.traceNewNoteHash(_storageAddress, noteHash); + public traceNewNoteHash(_contractAddress: Fr, noteHash: Fr) { + this.innerCallTrace.traceNewNoteHash(_contractAddress, noteHash); + this.enqueuedCallTrace.traceNewNoteHash(_contractAddress, noteHash); } - public traceNullifierCheck(storageAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean) { - this.innerCallTrace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending); - this.enqueuedCallTrace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending); + public traceNullifierCheck(contractAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean) { + this.innerCallTrace.traceNullifierCheck(contractAddress, nullifier, leafIndex, exists, isPending); + this.enqueuedCallTrace.traceNullifierCheck(contractAddress, nullifier, leafIndex, exists, isPending); } - public traceNewNullifier(storageAddress: Fr, nullifier: Fr) { - this.innerCallTrace.traceNewNullifier(storageAddress, nullifier); - this.enqueuedCallTrace.traceNewNullifier(storageAddress, nullifier); + public traceNewNullifier(contractAddress: Fr, nullifier: Fr) { + this.innerCallTrace.traceNewNullifier(contractAddress, nullifier); + this.enqueuedCallTrace.traceNewNullifier(contractAddress, nullifier); } public traceL1ToL2MessageCheck(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr, exists: boolean) { diff --git a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts b/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts index 547b719c93f..0e7036a37ef 100644 --- a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts +++ b/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts @@ -157,7 +157,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI this.sideEffectCounter++; } - public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, _exists: boolean, _cached: boolean) { + public tracePublicStorageRead(contractAddress: Fr, slot: Fr, value: Fr, _exists: boolean, _cached: boolean) { // NOTE: exists and cached are unused for now but may be used for optimizations or kernel hints later if ( this.contractStorageReads.length + this.previousValidationRequestArrayLengths.publicDataReads >= @@ -167,7 +167,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI } this.contractStorageReads.push( - new ContractStorageRead(slot, value, this.sideEffectCounter, AztecAddress.fromField(storageAddress)), + new ContractStorageRead(slot, value, this.sideEffectCounter, AztecAddress.fromField(contractAddress)), ); this.avmCircuitHints.storageValues.items.push( new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ value), @@ -176,7 +176,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI this.incrementSideEffectCounter(); } - public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) { + public tracePublicStorageWrite(contractAddress: Fr, slot: Fr, value: Fr) { if ( this.contractStorageUpdateRequests.length + this.previousAccumulatedDataArrayLengths.publicDataUpdateRequests >= MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX @@ -185,15 +185,15 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI } this.contractStorageUpdateRequests.push( - new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, storageAddress), + new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, contractAddress), ); this.log.debug(`SSTORE cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`); this.incrementSideEffectCounter(); } // TODO(8287): _exists can be removed once we have the vm properly handling the equality check - public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { - // NOTE: storageAddress is unused because noteHash is an already-siloed leaf + public traceNoteHashCheck(_contractAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { + // NOTE: contractAddress is unused because noteHash is an already-siloed leaf if ( this.noteHashReadRequests.length + this.previousValidationRequestArrayLengths.noteHashReadRequests >= MAX_NOTE_HASH_READ_REQUESTS_PER_TX @@ -208,22 +208,22 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI // NOTE: counter does not increment for note hash checks (because it doesn't rely on pending note hashes) } - public traceNewNoteHash(storageAddress: Fr, noteHash: Fr) { + public traceNewNoteHash(contractAddress: Fr, noteHash: Fr) { if (this.noteHashes.length + this.previousAccumulatedDataArrayLengths.noteHashes >= MAX_NOTE_HASHES_PER_TX) { throw new SideEffectLimitReachedError('note hash', MAX_NOTE_HASHES_PER_TX); } - this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter).scope(AztecAddress.fromField(storageAddress))); + this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter).scope(AztecAddress.fromField(contractAddress))); this.log.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`); this.incrementSideEffectCounter(); } - public traceNullifierCheck(storageAddress: Fr, nullifier: Fr, _leafIndex: Fr, exists: boolean, _isPending: boolean) { + public traceNullifierCheck(contractAddress: Fr, nullifier: Fr, _leafIndex: Fr, exists: boolean, _isPending: boolean) { // NOTE: isPending and leafIndex are unused for now but may be used for optimizations or kernel hints later this.enforceLimitOnNullifierChecks(); const readRequest = new ReadRequest(nullifier, this.sideEffectCounter).scope( - AztecAddress.fromField(storageAddress), + AztecAddress.fromField(contractAddress), ); if (exists) { this.nullifierReadRequests.push(readRequest); @@ -237,14 +237,14 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI this.incrementSideEffectCounter(); } - public traceNewNullifier(storageAddress: Fr, nullifier: Fr) { + public traceNewNullifier(contractAddress: Fr, nullifier: Fr) { if (this.nullifiers.length + this.previousAccumulatedDataArrayLengths.nullifiers >= MAX_NULLIFIERS_PER_TX) { throw new SideEffectLimitReachedError('nullifier', MAX_NULLIFIERS_PER_TX); } this.nullifiers.push( new Nullifier(nullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO).scope( - AztecAddress.fromField(storageAddress), + AztecAddress.fromField(contractAddress), ), ); this.log.debug(`NEW_NULLIFIER cnt: ${this.sideEffectCounter}`); @@ -538,15 +538,9 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI function createPublicCallRequest(avmEnvironment: AvmExecutionEnvironment): PublicCallRequest { const callContext = CallContext.from({ msgSender: avmEnvironment.sender, - storageContractAddress: avmEnvironment.storageAddress, + contractAddress: avmEnvironment.address, functionSelector: avmEnvironment.functionSelector, - isDelegateCall: avmEnvironment.isDelegateCall, isStaticCall: avmEnvironment.isStaticCall, }); - return new PublicCallRequest( - avmEnvironment.address, - callContext, - computeVarArgsHash(avmEnvironment.calldata), - /*counter=*/ 0, - ); + return new PublicCallRequest(callContext, computeVarArgsHash(avmEnvironment.calldata), /*counter=*/ 0); } diff --git a/yarn-project/simulator/src/public/enqueued_call_simulator.ts b/yarn-project/simulator/src/public/enqueued_call_simulator.ts index a37c1b2066f..85e63579cf3 100644 --- a/yarn-project/simulator/src/public/enqueued_call_simulator.ts +++ b/yarn-project/simulator/src/public/enqueued_call_simulator.ts @@ -16,7 +16,6 @@ import { ContractStorageRead, ContractStorageUpdateRequest, Fr, - FunctionData, Gas, type GlobalVariables, type Header, @@ -42,7 +41,6 @@ import { PublicAccumulatedDataArrayLengths, PublicCallData, type PublicCallRequest, - PublicCallStackItem, PublicCircuitPublicInputs, PublicInnerCallRequest, type PublicKernelCircuitPublicInputs, @@ -157,7 +155,7 @@ export class EnqueuedCallSimulator { ); const callStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PublicInnerCallRequest.empty); - callStack[0].item.contractAddress = callRequest.contractAddress; + callStack[0].item.contractAddress = callRequest.callContext.contractAddress; callStack[0].item.callContext = callRequest.callContext; callStack[0].item.argsHash = callRequest.argsHash; @@ -197,22 +195,19 @@ export class EnqueuedCallSimulator { // Accumulate gas used in this enqueued call. gasUsed = gasUsed.add(Gas.from(result.startGasLeft).sub(Gas.from(result.endGasLeft))); + const { contractAddress, functionSelector } = result.executionRequest.callContext; + // Sanity check for a current upstream assumption. // Consumers of the result seem to expect "reverted <=> revertReason !== undefined". - const functionSelector = result.executionRequest.callContext.functionSelector.toString(); if (result.reverted && !result.revertReason) { throw new Error( - `Simulation of ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ - result.functionName - }) reverted with no reason.`, + `Simulation of ${contractAddress}:${functionSelector}(${result.functionName}) reverted with no reason.`, ); } // Simulate the public kernel circuit. this.log.debug( - `Running public kernel inner circuit for ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ - result.functionName - })`, + `Running public kernel inner circuit for ${contractAddress}:${functionSelector}(${result.functionName})`, ); const callData = await this.getPublicCallData(result); @@ -226,9 +221,7 @@ export class EnqueuedCallSimulator { // TODO(@leila) we shouldn't drop everything when it reverts. The tail kernel needs the data to prove that it's reverted for the correct reason. if (result.reverted) { this.log.debug( - `Reverting on ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ - result.functionName - }) with reason: ${result.revertReason}`, + `Reverting on ${contractAddress}:${functionSelector}(${result.functionName}) with reason: ${result.revertReason}`, ); // TODO(@spalladino): Check gasUsed is correct. The AVM should take care of setting gasLeft to zero upon a revert. @@ -278,15 +271,15 @@ export class EnqueuedCallSimulator { */ private async getPublicCallData(result: PublicExecutionResult) { const bytecodeHash = await this.getBytecodeHash(result); - const callStackItem = await this.getPublicCallStackItem(result); - return new PublicCallData(callStackItem, makeEmptyProof(), bytecodeHash); + const publicInputs = await this.getPublicCircuitPublicInputs(result); + return new PublicCallData(publicInputs, makeEmptyProof(), bytecodeHash); } - private async getPublicCallStackItem(result: PublicExecutionResult) { + private async getPublicCircuitPublicInputs(result: PublicExecutionResult) { const publicDataTreeInfo = await this.db.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE); this.historicalHeader.state.partial.publicDataTree.root = Fr.fromBuffer(publicDataTreeInfo.root); - const publicCircuitPublicInputs = PublicCircuitPublicInputs.from({ + return PublicCircuitPublicInputs.from({ callContext: result.executionRequest.callContext, proverAddress: AztecAddress.ZERO, argsHash: computeVarArgsHash(result.executionRequest.args), @@ -340,12 +333,6 @@ export class EnqueuedCallSimulator { // TODO(@just-mitch): need better mapping from simulator to revert code. revertCode: result.reverted ? RevertCode.APP_LOGIC_REVERTED : RevertCode.OK, }); - - return new PublicCallStackItem( - result.executionRequest.contractAddress, - new FunctionData(result.executionRequest.callContext.functionSelector, false), - publicCircuitPublicInputs, - ); } private getBytecodeHash(_result: PublicExecutionResult) { diff --git a/yarn-project/simulator/src/public/enqueued_calls_processor.ts b/yarn-project/simulator/src/public/enqueued_calls_processor.ts index f4741d0eb8e..5dfbcc5c161 100644 --- a/yarn-project/simulator/src/public/enqueued_calls_processor.ts +++ b/yarn-project/simulator/src/public/enqueued_calls_processor.ts @@ -265,9 +265,7 @@ export class EnqueuedCallsProcessor { if (enqueuedCallResult.revertReason && !PhaseIsRevertible[phase]) { this.log.debug( - `Simulation error on ${executionRequest.contractAddress.toString()}:${ - executionRequest.callContext.functionSelector - } with reason: ${enqueuedCallResult.revertReason}`, + `Simulation error on ${executionRequest.callContext.contractAddress}:${executionRequest.callContext.functionSelector} with reason: ${enqueuedCallResult.revertReason}`, ); throw enqueuedCallResult.revertReason; } diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index 7dc41776095..94fcc6106af 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -139,7 +139,7 @@ export function checkValidStaticCall( export function resultToPublicCallRequest(result: PublicExecutionResult) { const request = result.executionRequest; const item = new PublicCallStackItemCompressed( - request.contractAddress, + request.callContext.contractAddress, request.callContext, computeVarArgsHash(request.args), computeVarArgsHash(result.returnValues), diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index d9f381f5018..182605e14b9 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -63,7 +63,7 @@ export class PublicExecutor { previousValidationRequestArrayLengths: PublicValidationRequestArrayLengths = PublicValidationRequestArrayLengths.empty(), previousAccumulatedDataArrayLengths: PublicAccumulatedDataArrayLengths = PublicAccumulatedDataArrayLengths.empty(), ): Promise { - const address = executionRequest.contractAddress; + const address = executionRequest.callContext.contractAddress; const selector = executionRequest.callContext.functionSelector; const fnName = await getPublicFunctionDebugName(this.worldStateDB, address, selector, executionRequest.args); @@ -149,15 +149,13 @@ function createAvmExecutionEnvironment( transactionFee: Fr, ): AvmExecutionEnvironment { return new AvmExecutionEnvironment( - executionRequest.contractAddress, - executionRequest.callContext.storageContractAddress, + executionRequest.callContext.contractAddress, executionRequest.callContext.msgSender, executionRequest.callContext.functionSelector, /*contractCallDepth=*/ Fr.zero(), transactionFee, globalVariables, executionRequest.callContext.isStaticCall, - executionRequest.callContext.isDelegateCall, executionRequest.args, ); } diff --git a/yarn-project/simulator/src/public/public_processor.test.ts b/yarn-project/simulator/src/public/public_processor.test.ts index 60d24624aaa..2d578e20b12 100644 --- a/yarn-project/simulator/src/public/public_processor.test.ts +++ b/yarn-project/simulator/src/public/public_processor.test.ts @@ -221,7 +221,7 @@ describe('public_processor', () => { request, nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: request.contractAddress, + from: request.callContext.contractAddress, tx: makeFunctionCall(), }).build(), ], @@ -318,7 +318,7 @@ describe('public_processor', () => { request: revertibleRequests[0], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: revertibleRequests[0].callContext.storageContractAddress, + from: revertibleRequests[0].callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 13), @@ -327,7 +327,7 @@ describe('public_processor', () => { ], }).build(), PublicExecutionResultBuilder.fromFunctionCall({ - from: revertibleRequests[0].contractAddress, + from: revertibleRequests[0].callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), revertReason: new SimulationError('Simulation Failed', []), }).build(), @@ -339,7 +339,7 @@ describe('public_processor', () => { request: teardownRequest, nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotC, fr(0x201), 16), @@ -383,7 +383,7 @@ describe('public_processor', () => { expect(arrayNonEmptyLength(txEffect.publicDataWrites, PublicDataWrite.isEmpty)).toEqual(numPublicDataWrites); const expectedWrites = [ new PublicDataWrite( - computePublicDataTreeLeafSlot(nonRevertibleRequests[0].callContext.storageContractAddress, contractSlotA), + computePublicDataTreeLeafSlot(nonRevertibleRequests[0].callContext.contractAddress, contractSlotA), fr(0x101), ), new PublicDataWrite(computePublicDataTreeLeafSlot(nestedContractAddress, contractSlotC), fr(0x201)), @@ -424,7 +424,7 @@ describe('public_processor', () => { contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11)], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: nonRevertibleRequests[0].callContext.storageContractAddress, + from: nonRevertibleRequests[0].callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 12), @@ -432,7 +432,7 @@ describe('public_processor', () => { ], }).build(), PublicExecutionResultBuilder.fromFunctionCall({ - from: nonRevertibleRequests[0].callContext.storageContractAddress, + from: nonRevertibleRequests[0].callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), revertReason: new SimulationError('Simulation Failed', []), }).build(), @@ -449,7 +449,7 @@ describe('public_processor', () => { request: teardownRequest, nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x202), 16)], }).build(), @@ -514,7 +514,7 @@ describe('public_processor', () => { contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11)], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: nonRevertibleRequests[0].callContext.storageContractAddress, + from: nonRevertibleRequests[0].callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 12), @@ -538,12 +538,12 @@ describe('public_processor', () => { request: teardownRequest, nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x202), 16)], }).build(teardownResultSettings), PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x202), 17)], revertReason: new SimulationError('Simulation Failed', []), @@ -583,7 +583,7 @@ describe('public_processor', () => { expect(arrayNonEmptyLength(txEffect.publicDataWrites, PublicDataWrite.isEmpty)).toBe(numPublicDataWrites); expect(txEffect.publicDataWrites.slice(0, numPublicDataWrites)).toEqual([ new PublicDataWrite( - computePublicDataTreeLeafSlot(nonRevertibleRequests[0].callContext.storageContractAddress, contractSlotA), + computePublicDataTreeLeafSlot(nonRevertibleRequests[0].callContext.contractAddress, contractSlotA), fr(0x101), ), new PublicDataWrite(computePublicDataTreeLeafSlot(nestedContractAddress, contractSlotA), fr(0x102)), @@ -627,7 +627,7 @@ describe('public_processor', () => { contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11)], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: nonRevertibleRequests[0].callContext.storageContractAddress, + from: nonRevertibleRequests[0].callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 12), @@ -652,12 +652,12 @@ describe('public_processor', () => { request: teardownRequest, nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x202), 16)], }).build(teardownResultSettings), PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x202), 16)], revertReason: new SimulationError('Simulation Failed', []), @@ -697,7 +697,7 @@ describe('public_processor', () => { expect(arrayNonEmptyLength(txEffect.publicDataWrites, PublicDataWrite.isEmpty)).toBe(numPublicDataWrites); expect(txEffect.publicDataWrites.slice(0, numPublicDataWrites)).toEqual([ new PublicDataWrite( - computePublicDataTreeLeafSlot(nonRevertibleRequests[0].callContext.storageContractAddress, contractSlotA), + computePublicDataTreeLeafSlot(nonRevertibleRequests[0].callContext.contractAddress, contractSlotA), fr(0x101), ), new PublicDataWrite(computePublicDataTreeLeafSlot(nestedContractAddress, contractSlotA), fr(0x102)), @@ -744,7 +744,7 @@ describe('public_processor', () => { .withGasUsed(Gas.empty()) .build(); - const nestedContractAddress = revertibleRequests[0].callContext.storageContractAddress; + const nestedContractAddress = revertibleRequests[0].callContext.contractAddress; const contractSlotA = fr(0x100); const contractSlotB = fr(0x150); const contractSlotC = fr(0x200); @@ -798,7 +798,7 @@ describe('public_processor', () => { request: teardownRequest, nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotA, fr(0x103), 16), @@ -807,7 +807,7 @@ describe('public_processor', () => { contractStorageReads: [new ContractStorageRead(contractSlotA, fr(0x102), 15)], }).build({ startGasLeft: teardownGas, endGasLeft: teardownGas, transactionFee }), PublicExecutionResultBuilder.fromFunctionCall({ - from: teardownRequest.callContext.storageContractAddress, + from: teardownRequest.callContext.contractAddress, tx: makeFunctionCall('', nestedContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 13), diff --git a/yarn-project/simulator/src/public/side_effect_trace.test.ts b/yarn-project/simulator/src/public/side_effect_trace.test.ts index 4afd862e698..87cb70f0c02 100644 --- a/yarn-project/simulator/src/public/side_effect_trace.test.ts +++ b/yarn-project/simulator/src/public/side_effect_trace.test.ts @@ -115,7 +115,7 @@ describe('Side Effect Trace', () => { const pxResult = toPxResult(trace); expect(pxResult.noteHashReadRequests).toEqual([ { - //storageAddress: contractAddress, + // contractAddress, value: utxo, //exists: exists, // counter: startCounter, @@ -132,7 +132,7 @@ describe('Side Effect Trace', () => { const pxResult = toPxResult(trace); expect(pxResult.noteHashes).toEqual([ { - //storageAddress: contractAddress, + // contractAddress, value: utxo, counter: startCounter, }, diff --git a/yarn-project/simulator/src/public/side_effect_trace.ts b/yarn-project/simulator/src/public/side_effect_trace.ts index f023e09adbe..1c24a9f9117 100644 --- a/yarn-project/simulator/src/public/side_effect_trace.ts +++ b/yarn-project/simulator/src/public/side_effect_trace.ts @@ -92,13 +92,13 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { // TODO(dbanks12): checks against tx-wide limit need access to parent trace's length - public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, _exists: boolean, _cached: boolean) { + public tracePublicStorageRead(contractAddress: Fr, slot: Fr, value: Fr, _exists: boolean, _cached: boolean) { // NOTE: exists and cached are unused for now but may be used for optimizations or kernel hints later if (this.contractStorageReads.length >= MAX_PUBLIC_DATA_READS_PER_TX) { throw new SideEffectLimitReachedError('contract storage read', MAX_PUBLIC_DATA_READS_PER_TX); } this.contractStorageReads.push( - new ContractStorageRead(slot, value, this.sideEffectCounter, AztecAddress.fromField(storageAddress)), + new ContractStorageRead(slot, value, this.sideEffectCounter, AztecAddress.fromField(contractAddress)), ); this.avmCircuitHints.storageValues.items.push( new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ value), @@ -107,20 +107,20 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { this.incrementSideEffectCounter(); } - public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) { + public tracePublicStorageWrite(contractAddress: Fr, slot: Fr, value: Fr) { if (this.contractStorageUpdateRequests.length >= MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) { throw new SideEffectLimitReachedError('contract storage write', MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX); } this.contractStorageUpdateRequests.push( - new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, storageAddress), + new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, contractAddress), ); this.logger.debug(`SSTORE cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`); this.incrementSideEffectCounter(); } // TODO(8287): _exists can be removed once we have the vm properly handling the equality check - public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { - // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call + public traceNoteHashCheck(_contractAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { + // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call if (this.noteHashReadRequests.length >= MAX_NOTE_HASH_READ_REQUESTS_PER_TX) { throw new SideEffectLimitReachedError('note hash read request', MAX_NOTE_HASH_READ_REQUESTS_PER_TX); } @@ -131,7 +131,7 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { // NOTE: counter does not increment for note hash checks (because it doesn't rely on pending note hashes) } - public traceNewNoteHash(_storageAddress: Fr, noteHash: Fr) { + public traceNewNoteHash(_contractAddress: Fr, noteHash: Fr) { if (this.noteHashes.length >= MAX_NOTE_HASHES_PER_TX) { throw new SideEffectLimitReachedError('note hash', MAX_NOTE_HASHES_PER_TX); } @@ -140,8 +140,14 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { this.incrementSideEffectCounter(); } - public traceNullifierCheck(_storageAddress: Fr, nullifier: Fr, _leafIndex: Fr, exists: boolean, _isPending: boolean) { - // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call + public traceNullifierCheck( + _contractAddress: Fr, + nullifier: Fr, + _leafIndex: Fr, + exists: boolean, + _isPending: boolean, + ) { + // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call // NOTE: isPending and leafIndex are unused for now but may be used for optimizations or kernel hints later this.enforceLimitOnNullifierChecks(); @@ -159,8 +165,8 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { this.incrementSideEffectCounter(); } - public traceNewNullifier(_storageAddress: Fr, nullifier: Fr) { - // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call + public traceNewNullifier(_contractAddress: Fr, nullifier: Fr) { + // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call if (this.nullifiers.length >= MAX_NULLIFIERS_PER_TX) { throw new SideEffectLimitReachedError('nullifier', MAX_NULLIFIERS_PER_TX); } @@ -369,10 +375,9 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { function createPublicExecutionRequest(avmEnvironment: AvmExecutionEnvironment): PublicExecutionRequest { const callContext = CallContext.from({ msgSender: avmEnvironment.sender, - storageContractAddress: avmEnvironment.storageAddress, + contractAddress: avmEnvironment.address, functionSelector: avmEnvironment.functionSelector, - isDelegateCall: avmEnvironment.isDelegateCall, isStaticCall: avmEnvironment.isStaticCall, }); - return new PublicExecutionRequest(avmEnvironment.address, callContext, avmEnvironment.calldata); + return new PublicExecutionRequest(callContext, avmEnvironment.calldata); } diff --git a/yarn-project/simulator/src/public/side_effect_trace_interface.ts b/yarn-project/simulator/src/public/side_effect_trace_interface.ts index 2d229d7f7b4..e3f7b7c2ae2 100644 --- a/yarn-project/simulator/src/public/side_effect_trace_interface.ts +++ b/yarn-project/simulator/src/public/side_effect_trace_interface.ts @@ -9,12 +9,12 @@ export interface PublicSideEffectTraceInterface { fork(): PublicSideEffectTraceInterface; getCounter(): number; // all "trace*" functions can throw SideEffectLimitReachedError - tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean): void; - tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr): void; - traceNoteHashCheck(storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean): void; - traceNewNoteHash(storageAddress: Fr, noteHash: Fr): void; - traceNullifierCheck(storageAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean): void; - traceNewNullifier(storageAddress: Fr, nullifier: Fr): void; + tracePublicStorageRead(contractAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean): void; + tracePublicStorageWrite(contractAddress: Fr, slot: Fr, value: Fr): void; + traceNoteHashCheck(contractAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean): void; + traceNewNoteHash(contractAddress: Fr, noteHash: Fr): void; + traceNullifierCheck(contractAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean): void; + traceNewNullifier(contractAddress: Fr, nullifier: Fr): void; traceL1ToL2MessageCheck(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr, exists: boolean): void; traceNewL2ToL1Message(contractAddress: Fr, recipient: Fr, content: Fr): void; traceUnencryptedLog(contractAddress: Fr, log: Fr[]): void; diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts index 592be1c617b..e2de6356223 100644 --- a/yarn-project/txe/src/oracle/txe_oracle.ts +++ b/yarn-project/txe/src/oracle/txe_oracle.ts @@ -188,7 +188,6 @@ export class TXE implements TypedOracle { blockNumber: number, sideEffectsCounter = this.sideEffectsCounter, isStaticCall = false, - isDelegateCall = false, ) { const db = await this.#getTreesAt(blockNumber); const previousBlockState = await this.#getTreesAt(blockNumber - 1); @@ -200,12 +199,8 @@ export class TXE implements TypedOracle { inputs.historicalHeader.lastArchive.root = Fr.fromBuffer( (await previousBlockState.getTreeInfo(MerkleTreeId.ARCHIVE)).root, ); - inputs.callContext.msgSender = this.msgSender; - inputs.callContext.storageContractAddress = this.contractAddress; - inputs.callContext.isStaticCall = isStaticCall; - inputs.callContext.isDelegateCall = isDelegateCall; + inputs.callContext = new CallContext(this.msgSender, this.contractAddress, this.functionSelector, isStaticCall); inputs.startSideEffectCounter = sideEffectsCounter; - inputs.callContext.functionSelector = this.functionSelector; return inputs; } @@ -555,13 +550,12 @@ export class TXE implements TypedOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ) { this.logger.verbose( `Executing external function ${await this.getDebugFunctionName( targetContractAddress, functionSelector, - )}@${targetContractAddress} isStaticCall=${isStaticCall} isDelegateCall=${isDelegateCall}`, + )}@${targetContractAddress} isStaticCall=${isStaticCall}`, ); // Store and modify env @@ -575,13 +569,7 @@ export class TXE implements TypedOracle { const artifact = await this.contractDataOracle.getFunctionArtifact(targetContractAddress, functionSelector); const acir = artifact.bytecode; - const initialWitness = await this.getInitialWitness( - artifact, - argsHash, - sideEffectCounter, - isStaticCall, - isDelegateCall, - ); + const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall); const acvmCallback = new Oracle(this); const timer = new Timer(); try { @@ -633,13 +621,7 @@ export class TXE implements TypedOracle { } } - async getInitialWitness( - abi: FunctionAbi, - argsHash: Fr, - sideEffectCounter: number, - isStaticCall: boolean, - isDelegateCall: boolean, - ) { + async getInitialWitness(abi: FunctionAbi, argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean) { const argumentsSize = countArgumentsSize(abi); const args = this.packedValuesCache.unpack(argsHash); @@ -652,7 +634,6 @@ export class TXE implements TypedOracle { this.blockNumber - 1, sideEffectCounter, isStaticCall, - isDelegateCall, ); const fields = [...privateContextInputs.toFields(), ...args]; @@ -680,17 +661,12 @@ export class TXE implements TypedOracle { return `${artifact.name}:${f.name}`; } - async executePublicFunction( - targetContractAddress: AztecAddress, - args: Fr[], - callContext: CallContext, - counter: number, - ) { + private async executePublicFunction(args: Fr[], callContext: CallContext, counter: number) { const executor = new PublicExecutor( new TXEWorldStateDB(await this.trees.getLatest(), new TXEPublicContractDataSource(this)), new NoopTelemetryClient(), ); - const execution = new PublicExecutionRequest(targetContractAddress, callContext, args); + const execution = new PublicExecutionRequest(callContext, args); const executionResult = executor.simulate( execution, @@ -709,7 +685,6 @@ export class TXE implements TypedOracle { functionSelector: FunctionSelector, args: Fr[], isStaticCall: boolean, - isDelegateCall: boolean, ) { // Store and modify env const currentContractAddress = AztecAddress.fromField(this.contractAddress); @@ -720,20 +695,15 @@ export class TXE implements TypedOracle { this.setFunctionSelector(functionSelector); this.setCalldata(args); - const callContext = CallContext.empty(); - callContext.msgSender = this.msgSender; - callContext.functionSelector = this.functionSelector; - callContext.storageContractAddress = targetContractAddress; - callContext.isStaticCall = isStaticCall; - callContext.isDelegateCall = isDelegateCall; - - const executionResult = await this.executePublicFunction( + const callContext = new CallContext( + /* msgSender */ currentContractAddress, targetContractAddress, - args, - callContext, - this.sideEffectsCounter, + functionSelector, + isStaticCall, ); + const executionResult = await this.executePublicFunction(args, callContext, this.sideEffectsCounter); + // Apply side effects if (!executionResult.reverted) { this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber() + 1; @@ -751,7 +721,6 @@ export class TXE implements TypedOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ): Promise { // Store and modify env const currentContractAddress = AztecAddress.fromField(this.contractAddress); @@ -761,22 +730,17 @@ export class TXE implements TypedOracle { this.setContractAddress(targetContractAddress); this.setFunctionSelector(functionSelector); - const callContext = CallContext.empty(); - callContext.msgSender = this.msgSender; - callContext.functionSelector = FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)); - callContext.storageContractAddress = targetContractAddress; - callContext.isStaticCall = isStaticCall; - callContext.isDelegateCall = isDelegateCall; + const callContext = new CallContext( + /* msgSender */ currentContractAddress, + targetContractAddress, + FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)), + isStaticCall, + ); const args = [this.functionSelector.toField(), ...this.packedValuesCache.unpack(argsHash)]; const newArgsHash = this.packedValuesCache.pack(args); - const executionResult = await this.executePublicFunction( - targetContractAddress, - args, - callContext, - sideEffectCounter, - ); + const executionResult = await this.executePublicFunction(args, callContext, sideEffectCounter); if (executionResult.reverted) { throw new Error(`Execution reverted with reason: ${executionResult.revertReason}`); @@ -797,7 +761,6 @@ export class TXE implements TypedOracle { argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean, - isDelegateCall: boolean, ): Promise { // Definitely not right, in that the teardown should always be last. // But useful for executing flows. @@ -807,7 +770,6 @@ export class TXE implements TypedOracle { argsHash, sideEffectCounter, isStaticCall, - isDelegateCall, ); } diff --git a/yarn-project/txe/src/txe_service/txe_service.ts b/yarn-project/txe/src/txe_service/txe_service.ts index 63fad7601ae..62b97f120df 100644 --- a/yarn-project/txe/src/txe_service/txe_service.ts +++ b/yarn-project/txe/src/txe_service/txe_service.ts @@ -228,13 +228,7 @@ export class TXEService { ) { const parsedAddress = fromSingle(address); const parsedSelector = FunctionSelector.fromField(fromSingle(functionSelector)); - const result = await (this.typedOracle as TXE).avmOpcodeCall( - parsedAddress, - parsedSelector, - fromArray(args), - false, - false, - ); + const result = await (this.typedOracle as TXE).avmOpcodeCall(parsedAddress, parsedSelector, fromArray(args), false); if (!result.reverted) { throw new ExpectedFailureError('Public call did not revert'); } @@ -248,7 +242,6 @@ export class TXEService { argsHash: ForeignCallSingle, sideEffectCounter: ForeignCallSingle, isStaticCall: ForeignCallSingle, - isDelegateCall: ForeignCallSingle, ) { try { await this.typedOracle.callPrivateFunction( @@ -257,7 +250,6 @@ export class TXEService { fromSingle(argsHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool(), - fromSingle(isDelegateCall).toBool(), ); throw new ExpectedFailureError('Private call did not fail'); } catch (e) { @@ -564,7 +556,6 @@ export class TXEService { FunctionSelector.fromField(fromSingle(functionSelector)), fromArray(args), /* isStaticCall */ false, - /* isDelegateCall */ false, ); return toForeignCallResult([toArray(result.returnValues), toSingle(new Fr(1))]); @@ -582,7 +573,6 @@ export class TXEService { FunctionSelector.fromField(fromSingle(functionSelector)), fromArray(args), /* isStaticCall */ true, - /* isDelegateCall */ false, ); return toForeignCallResult([toArray(result.returnValues), toSingle(new Fr(1))]); @@ -650,7 +640,6 @@ export class TXEService { argsHash: ForeignCallSingle, sideEffectCounter: ForeignCallSingle, isStaticCall: ForeignCallSingle, - isDelegateCall: ForeignCallSingle, ) { const result = await this.typedOracle.callPrivateFunction( fromSingle(targetContractAddress), @@ -658,7 +647,6 @@ export class TXEService { fromSingle(argsHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool(), - fromSingle(isDelegateCall).toBool(), ); return toForeignCallResult([toArray([result.endSideEffectCounter, result.returnsHash])]); } @@ -687,7 +675,6 @@ export class TXEService { argsHash: ForeignCallSingle, sideEffectCounter: ForeignCallSingle, isStaticCall: ForeignCallSingle, - isDelegateCall: ForeignCallSingle, ) { const newArgsHash = await this.typedOracle.enqueuePublicFunctionCall( fromSingle(targetContractAddress), @@ -695,7 +682,6 @@ export class TXEService { fromSingle(argsHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool(), - fromSingle(isDelegateCall).toBool(), ); return toForeignCallResult([toSingle(newArgsHash)]); } @@ -706,7 +692,6 @@ export class TXEService { argsHash: ForeignCallSingle, sideEffectCounter: ForeignCallSingle, isStaticCall: ForeignCallSingle, - isDelegateCall: ForeignCallSingle, ) { const newArgsHash = await this.typedOracle.setPublicTeardownFunctionCall( fromSingle(targetContractAddress), @@ -714,7 +699,6 @@ export class TXEService { fromSingle(argsHash), fromSingle(sideEffectCounter).toNumber(), fromSingle(isStaticCall).toBool(), - fromSingle(isDelegateCall).toBool(), ); return toForeignCallResult([toSingle(newArgsHash)]); }