diff --git a/docs/docs/aztec/concepts/smart_contracts/functions/context.md b/docs/docs/aztec/concepts/smart_contracts/functions/context.md index 5bd2f4526b37..3020710aa9ce 100644 --- a/docs/docs/aztec/concepts/smart_contracts/functions/context.md +++ b/docs/docs/aztec/concepts/smart_contracts/functions/context.md @@ -130,13 +130,7 @@ New L2 to L1 messages contains messages that are delivered to the [l1 outbox](/p ## Public Context -The Public Context includes all of the information passed from the `Public VM` into the execution environment. It is very similar to the [Private Context](#the-private-context), however it has some minor differences (detailed below). - -### Public Context Inputs - -In the current version of the system, the public context is almost a clone of the private execution context. - -#include_code public-context-inputs /noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr rust +The Public Context includes all of the information passed from the `Public VM` into the execution environment. Its interface is very similar to the [Private Context](#the-private-context), however it has some minor differences (detailed below). ### Public Global Variables diff --git a/docs/docs/migration_notes.md b/docs/docs/migration_notes.md index 2186fdc0d4d6..f3c169112228 100644 --- a/docs/docs/migration_notes.md +++ b/docs/docs/migration_notes.md @@ -6,9 +6,30 @@ keywords: [sandbox, cli, aztec, notes, migration, updating, upgrading] Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them. -## 0.41.0 +## 0.42.0 + +## Public execution migrated to the Aztec Virtual Machine + +**What does this mean for me?** + +It should be mostly transparent, with a few caveats: + +- Not all Noir blackbox functions are supported by the AVM. Only `Sha256`, `PedersenHash`, `Poseidon2Permutation`, `Keccak256`, and `ToRadix` are supported. +- For public functions, `context.nullifier_exists(...)` will now also consider pending nullifiers. +- The following methods of `PublicContext` are not supported anymore: `fee_recipient`, `fee_per_da_gas`, `fee_per_l2_gas`, `call_public_function_no_args`, `static_call_public_function_no_args`, `delegate_call_public_function_no_args`, `call_public_function_with_packed_args`, `set_return_hash`, `finish`. However, in terms of functionality, the new context's interface should be equivalent (unless otherwise specified in this list). +- Delegate calls are not yet supported in the AVM. +- If you have types with custom serialization that you use across external contracts calls, you might need to modify its serialization to match how Noir would serialize it. This is a known problem unrelated to the AVM, but triggered more often when using it. +- A few error messages might change format, so you might need to change your test assertions. + +**Internal details** +Before this change, public bytecode was executed using the same simulator as in private: the ACIR simulator (and internally, the Brillig VM). On the Aztec.nr side, public functions accessed the context through `PublicContext`. +After this change, public bytecode will be run using the AVM simulator (the simulator for our upcoming zkVM). This bytecode is generated from Noir contracts in two steps: First, `nargo compile` produces an artifact which has Brillig bytecode for public functions, just as it did before. Second: the `avm-transpiler` takes that artifact, and it transpiles Brillig bytecode to AVM bytecode. This final artifact can now be deployed and used with the new public runtime. + +On the Aztec.nr side, public functions keep accessing the context using `PublicContext` but the underlying implementation is switch with what formerly was the `AvmContext`. + +## 0.41.0 ### [Aztec.nr] State variable rework @@ -27,7 +48,8 @@ fn get_decimals() -> pub u8 { } ``` -The compiler will now error out with +The compiler will now error out with + ``` Expected type SharedImmutable<_, &mut PrivateContext>, found type SharedImmutable ``` @@ -44,7 +66,7 @@ This means that, without any additional features, we'd end up with some extra bo #[aztec(storage)] - struct Storage { + struct Storage { -- nonce_for_burn_approval: PublicMutable, +- nonce_for_burn_approval: PublicMutable, + nonce_for_burn_approval: PublicMutable, - portal_address: SharedImmutable, + portal_address: SharedImmutable, @@ -90,8 +112,8 @@ Additionally, the Noir LSP will now honor "go to definitions" requests for contr ### [Aztec.js] Simulate changes -* `.simulate()` now tracks closer the process performed by `.send().wait()`, specifically going through the account contract entrypoint instead of directly calling the intended function. -* `wallet.viewTx(...)` has been renamed to `wallet.simulateUnconstrained(...)` to better clarify what it does. +- `.simulate()` now tracks closer the process performed by `.send().wait()`, specifically going through the account contract entrypoint instead of directly calling the intended function. +- `wallet.viewTx(...)` has been renamed to `wallet.simulateUnconstrained(...)` to better clarify what it does. ### [Aztec.nr] Keys: Token note now stores an owner master nullifying public key hash instead of an owner address @@ -119,7 +141,6 @@ Creating a token note and adding it to storage now looks like this: Computing the nullifier similarly changes to use this master nullifying public key hash. - ## 0.40.0 ### [Aztec.nr] Debug logging diff --git a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr deleted file mode 100644 index 9fd0bee966f9..000000000000 --- a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr +++ /dev/null @@ -1,368 +0,0 @@ -use crate::hash::{compute_secret_hash, compute_message_hash, compute_message_nullifier}; -use dep::protocol_types::{address::{AztecAddress, EthAddress}, constants::L1_TO_L2_MESSAGE_LENGTH, header::Header}; -use dep::protocol_types::traits::{Deserialize, Serialize, Empty}; -use dep::protocol_types::abis::function_selector::FunctionSelector; -use dep::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs; -use crate::context::inputs::avm_context_inputs::AvmContextInputs; -use crate::context::interface::ContextInterface; -use crate::context::interface::PublicContextInterface; -use crate::context::gas::GasOpts; -use crate::context::public_context::FunctionReturns; - -struct AvmContext { - inputs: AvmContextInputs, -} - -impl AvmContext { - pub fn new(inputs: AvmContextInputs) -> Self { - AvmContext { inputs } - } - - pub fn storage_address(self) -> AztecAddress { - storage_address() - } - pub fn fee_per_l2_gas(self) -> Field { - fee_per_l2_gas() - } - pub fn fee_per_da_gas(self) -> Field { - fee_per_da_gas() - } - - /** - * Emit a log with the given event selector and message. - * - * @param event_selector The event selector for the log. - * @param message The message to emit in the log. - * Should be automatically convertible to [Field; N]. For example str works with - * one char per field. Otherwise you can use CompressedString. - */ - pub fn emit_unencrypted_log_with_selector(&mut self, event_selector: Field, log: T) { - emit_unencrypted_log(event_selector, log); - } - pub fn note_hash_exists(self, note_hash: Field, leaf_index: Field) -> bool { - note_hash_exists(note_hash, leaf_index) == 1 - } - pub fn l1_to_l2_msg_exists(self, msg_hash: Field, msg_leaf_index: Field) -> bool { - l1_to_l2_msg_exists(msg_hash, msg_leaf_index) == 1 - } -} - -impl PublicContextInterface for AvmContext { - fn block_number(self) -> Field { - block_number() - } - - fn timestamp(self) -> u64 { - timestamp() - } - - fn coinbase(self) -> EthAddress { - assert(false, "'coinbase' not implemented!"); - EthAddress::zero() - } - - fn fee_recipient(self) -> AztecAddress { - assert(false, "'fee_recipient' not implemented!"); - AztecAddress::zero() - } - - fn fee_per_da_gas(self) -> Field { - assert(false, "'fee_per_da_gas' not implemented!"); - 0 - } - - fn fee_per_l2_gas(self) -> Field { - assert(false, "'fee_per_l2_gas' not implemented!"); - 0 - } - - fn transaction_fee(self) -> Field { - transaction_fee() - } - - fn nullifier_exists(self, unsiloed_nullifier: Field, address: AztecAddress) -> bool { - nullifier_exists(unsiloed_nullifier, address.to_field()) == 1 - } - - fn emit_unencrypted_log(&mut self, log: T) { - let event_selector = 5; // Matches current PublicContext. - self.emit_unencrypted_log_with_selector(event_selector, log); - } - - fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field) { - let secret_hash = compute_secret_hash(secret); - let message_hash = compute_message_hash( - sender, - self.chain_id(), - /*recipient=*/self.this_address(), - self.version(), - content, - secret_hash - ); - let nullifier = compute_message_nullifier(message_hash, secret, leaf_index); - - assert(!self.nullifier_exists(nullifier, self.this_address()), "L1-to-L2 message is already nullified"); - assert(self.l1_to_l2_msg_exists(message_hash, leaf_index), "Tried to consume nonexistent L1-to-L2 message"); - - // Push nullifier (and the "commitment" corresponding to this can be "empty") - self.push_new_nullifier(nullifier, 0); - } - - fn message_portal(&mut self, recipient: EthAddress, content: Field) { - send_l2_to_l1_msg(recipient, content); - } - - fn call_public_function( - self: &mut Self, - contract_address: AztecAddress, - function_selector: FunctionSelector, - args: [Field], - gas_opts: GasOpts - ) -> FunctionReturns { - let results = call( - gas_for_call(gas_opts), - contract_address, - args, - function_selector.to_field() - ); - let data_to_return: [Field; RETURNS_COUNT] = results.0; - let success: u8 = results.1; - assert(success == 1, "Nested call failed!"); - - FunctionReturns::new(data_to_return) - } - - fn static_call_public_function( - self: &mut Self, - contract_address: AztecAddress, - function_selector: FunctionSelector, - args: [Field], - gas_opts: GasOpts - ) -> FunctionReturns { - let (data_to_return, success): ([Field; RETURNS_COUNT], u8) = call_static( - gas_for_call(gas_opts), - contract_address, - args, - function_selector.to_field() - ); - - assert(success == 1, "Nested static call failed!"); - FunctionReturns::new(data_to_return) - } - - fn delegate_call_public_function( - self: &mut Self, - contract_address: AztecAddress, - function_selector: FunctionSelector, - args: [Field] - ) -> FunctionReturns { - assert(false, "'delegate_call_public_function' not implemented!"); - FunctionReturns::new([0; RETURNS_COUNT]) - } -} - -impl ContextInterface for AvmContext { - fn push_new_note_hash(&mut self, note_hash: Field) { - emit_note_hash(note_hash); - } - fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) { - // Cannot nullify pending commitments in AVM, so `nullified_commitment` is not used - emit_nullifier(nullifier); - } - fn msg_sender(self) -> AztecAddress { - sender() - } - fn this_address(self) -> AztecAddress { - address() - } - fn chain_id(self) -> Field { - chain_id() - } - fn version(self) -> Field { - version() - } - fn selector(self) -> FunctionSelector { - FunctionSelector::from_field(self.inputs.selector) - } - fn get_args_hash(self) -> Field { - self.inputs.args_hash - } -} - -impl Empty for AvmContext { - fn empty() -> Self { - AvmContext::new(AvmContextInputs::empty()) - } -} - -// Helper functions -fn gas_for_call(user_gas: GasOpts) -> [Field; 2] { - // It's ok to use the max possible gas here, because the gas will be - // capped by the gas left in the (STATIC)CALL instruction. - let MAX_POSSIBLE_FIELD: Field = 0 - 1; - [ - user_gas.l2_gas.unwrap_or(MAX_POSSIBLE_FIELD), - user_gas.da_gas.unwrap_or(MAX_POSSIBLE_FIELD) - ] -} - -// Unconstrained opcode wrappers (do not use directly). -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6420): reconsider. -unconstrained fn address() -> AztecAddress { - address_opcode() -} -unconstrained fn storage_address() -> AztecAddress { - storage_address_opcode() -} -unconstrained fn sender() -> AztecAddress { - sender_opcode() -} -unconstrained fn portal() -> EthAddress { - portal_opcode() -} -unconstrained fn fee_per_l2_gas() -> Field { - fee_per_l2_gas_opcode() -} -unconstrained fn fee_per_da_gas() -> Field { - fee_per_da_gas_opcode() -} -unconstrained fn transaction_fee() -> Field { - transaction_fee_opcode() -} -unconstrained fn chain_id() -> Field { - chain_id_opcode() -} -unconstrained fn version() -> Field { - version_opcode() -} -unconstrained fn block_number() -> Field { - block_number_opcode() -} -unconstrained fn timestamp() -> u64 { - timestamp_opcode() -} -unconstrained fn l2_gas_left() -> Field { - l2_gas_left_opcode() -} -unconstrained fn da_gas_left() -> Field { - da_gas_left_opcode() -} -unconstrained fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u8 { - note_hash_exists_opcode(note_hash, leaf_index) -} -unconstrained fn emit_note_hash(note_hash: Field) { - emit_note_hash_opcode(note_hash) -} -unconstrained fn nullifier_exists(nullifier: Field, address: Field) -> u8 { - nullifier_exists_opcode(nullifier, address) -} -unconstrained fn emit_nullifier(nullifier: Field) { - emit_nullifier_opcode(nullifier) -} -unconstrained fn emit_unencrypted_log(event_selector: Field, message: T) { - emit_unencrypted_log_opcode(event_selector, message) -} -unconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u8 { - l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index) -} -unconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) { - send_l2_to_l1_msg_opcode(recipient, content) -} -unconstrained fn call( - gas: [Field; 2], - address: AztecAddress, - args: [Field], - function_selector: Field -) -> ([Field; RET_SIZE], u8) { - call_opcode(gas, address, args, function_selector) -} -unconstrained fn call_static( - gas: [Field; 2], - address: AztecAddress, - args: [Field], - function_selector: Field -) -> ([Field; RET_SIZE], u8) { - call_static_opcode(gas, address, args, function_selector) -} - -// AVM oracles (opcodes) follow, do not use directly. -#[oracle(avmOpcodeAddress)] -fn address_opcode() -> AztecAddress {} - -#[oracle(avmOpcodeStorageAddress)] -fn storage_address_opcode() -> AztecAddress {} - -#[oracle(avmOpcodeSender)] -fn sender_opcode() -> AztecAddress {} - -#[oracle(avmOpcodePortal)] -fn portal_opcode() -> EthAddress {} - -#[oracle(avmOpcodeFeePerL2Gas)] -fn fee_per_l2_gas_opcode() -> Field {} - -#[oracle(avmOpcodeFeePerDaGas)] -fn fee_per_da_gas_opcode() -> Field {} - -#[oracle(avmOpcodeTransactionFee)] -fn transaction_fee_opcode() -> Field {} - -#[oracle(avmOpcodeChainId)] -fn chain_id_opcode() -> Field {} - -#[oracle(avmOpcodeVersion)] -fn version_opcode() -> Field {} - -#[oracle(avmOpcodeBlockNumber)] -fn block_number_opcode() -> Field {} - -#[oracle(avmOpcodeTimestamp)] -fn timestamp_opcode() -> u64 {} - -#[oracle(avmOpcodeL2GasLeft)] -fn l2_gas_left_opcode() -> Field {} - -#[oracle(avmOpcodeDaGasLeft)] -fn da_gas_left_opcode() -> Field {} - -#[oracle(avmOpcodeNoteHashExists)] -fn note_hash_exists_opcode(note_hash: Field, leaf_index: Field) -> u8 {} - -#[oracle(avmOpcodeEmitNoteHash)] -fn emit_note_hash_opcode(note_hash: Field) {} - -#[oracle(avmOpcodeNullifierExists)] -fn nullifier_exists_opcode(nullifier: Field, address: Field) -> u8 {} - -#[oracle(avmOpcodeEmitNullifier)] -fn emit_nullifier_opcode(nullifier: Field) {} - -#[oracle(amvOpcodeEmitUnencryptedLog)] -fn emit_unencrypted_log_opcode(event_selector: Field, message: T) {} - -#[oracle(avmOpcodeL1ToL2MsgExists)] -fn l1_to_l2_msg_exists_opcode(msg_hash: Field, msg_leaf_index: Field) -> u8 {} - -#[oracle(avmOpcodeSendL2ToL1Msg)] -fn send_l2_to_l1_msg_opcode(recipient: EthAddress, content: Field) {} - -#[oracle(avmOpcodeCall)] -fn call_opcode( - gas: [Field; 2], // gas allocation: [l2_gas, da_gas] - address: AztecAddress, - args: [Field], - // TODO(5110): consider passing in calldata directly - function_selector: Field -) -> ([Field; RET_SIZE], u8) {} -// ^ return data ^ success - -#[oracle(avmOpcodeStaticCall)] -fn call_static_opcode( - gas: [Field; 2], // gas allocation: [l2_gas, da_gas] - address: AztecAddress, - args: [Field], - // TODO(5110): consider passing in calldata directly - function_selector: Field -) -> ([Field; RET_SIZE], u8) {} -// ^ return data ^ success - 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 a04465f60bfc..69904595c964 100644 --- a/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr +++ b/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr @@ -2,11 +2,9 @@ use dep::protocol_types::{abis::function_selector::FunctionSelector, address::Az use crate::context::private_context::PrivateContext; use crate::context::public_context::PublicContext; -use crate::context::avm_context::AvmContext; use crate::context::gas::GasOpts; use crate::context::public_context::FunctionReturns; -use crate::hash::hash_args; use crate::oracle::arguments; struct PrivateCallInterface { @@ -91,153 +89,29 @@ impl PrivateStaticVoidCallInterface { } struct PublicCallInterface { - target_contract: AztecAddress, - selector: FunctionSelector, - args_hash: Field, -} - -impl PublicCallInterface { - pub fn call(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.call_public_function_with_packed_args( - self.target_contract, - self.selector, - self.args_hash, - false, - false - ); - returns.deserialize_into() - } - - pub fn view(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false); - returns.deserialize_into() - } - - pub fn delegate_call(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true); - returns.deserialize_into() - } - - pub fn enqueue(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args( - self.target_contract, - self.selector, - self.args_hash, - false, - false - ) - } - - pub fn enqueue_view(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false) - } - - pub fn delegate_enqueue(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true) - } -} - -struct PublicVoidCallInterface { - target_contract: AztecAddress, - selector: FunctionSelector, - args_hash: Field -} - -impl PublicVoidCallInterface { - pub fn call(self, context: &mut PublicContext) { - context.call_public_function_with_packed_args( - self.target_contract, - self.selector, - self.args_hash, - false, - false - ).assert_empty() - } - - pub fn view(self, context: &mut PublicContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty(); - } - - pub fn delegate_call(self, context: &mut PublicContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true).assert_empty(); - } - - pub fn enqueue(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args( - self.target_contract, - self.selector, - self.args_hash, - false, - false - ) - } - - pub fn enqueue_view(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false) - } - - pub fn delegate_enqueue(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true) - } -} - -struct PublicStaticCallInterface { - target_contract: AztecAddress, - selector: FunctionSelector, - args_hash: Field, -} - -impl PublicStaticCallInterface { - pub fn view(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false); - returns.deserialize_into() - } - - pub fn enqueue_view(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false) - } -} - -struct PublicStaticVoidCallInterface { - target_contract: AztecAddress, - selector: FunctionSelector, - args_hash: Field -} - -impl PublicStaticVoidCallInterface { - pub fn view(self, context: &mut PublicContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty(); - } - - pub fn enqueue_view(self, context: &mut PrivateContext) { - context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false) - } -} - -struct AvmCallInterface { target_contract: AztecAddress, selector: FunctionSelector, args: [Field], gas_opts: GasOpts, } -impl AvmCallInterface { +impl PublicCallInterface { pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self { self.gas_opts = gas_opts; self } - pub fn call(self, context: &mut AvmContext) -> T where T: Deserialize { + pub fn call(self, context: &mut PublicContext) -> T where T: Deserialize { let returns = context.call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); returns.deserialize_into() } - pub fn view(self, context: &mut AvmContext) -> T where T: Deserialize { + pub fn view(self, context: &mut PublicContext) -> T where T: Deserialize { let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); returns.deserialize_into() } - pub fn delegate_call(self, context: &mut AvmContext) -> T where T: Deserialize { + 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() } @@ -279,30 +153,30 @@ impl AvmCallInterface { } } -struct AvmVoidCallInterface { +struct PublicVoidCallInterface { target_contract: AztecAddress, selector: FunctionSelector, args: [Field], gas_opts: GasOpts, } -impl AvmVoidCallInterface { +impl PublicVoidCallInterface { pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self { self.gas_opts = gas_opts; self } - pub fn call(self, context: &mut AvmContext) { + pub fn call(self, context: &mut PublicContext) { let returns = context.call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); returns.assert_empty() } - pub fn view(self, context: &mut AvmContext) { + pub fn view(self, context: &mut PublicContext) { let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); returns.assert_empty() } - pub fn delegate_call(self, context: &mut AvmContext) { + 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() } @@ -344,20 +218,20 @@ impl AvmVoidCallInterface { } } -struct AvmStaticCallInterface { +struct PublicStaticCallInterface { target_contract: AztecAddress, selector: FunctionSelector, args: [Field], gas_opts: GasOpts, } -impl AvmStaticCallInterface { +impl PublicStaticCallInterface { pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self { self.gas_opts = gas_opts; self } - pub fn view(self, context: &mut AvmContext) -> T where T: Deserialize { + pub fn view(self, context: &mut PublicContext) -> T where T: Deserialize { let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); returns.deserialize_into() } @@ -375,20 +249,20 @@ impl AvmStaticCallInterface { } } -struct AvmStaticVoidCallInterface { +struct PublicStaticVoidCallInterface { target_contract: AztecAddress, selector: FunctionSelector, args: [Field], gas_opts: GasOpts, } -impl AvmStaticVoidCallInterface { +impl PublicStaticVoidCallInterface { pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self { self.gas_opts = gas_opts; self } - pub fn view(self, context: &mut AvmContext) { + pub fn view(self, context: &mut PublicContext) { let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); returns.assert_empty() } diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr deleted file mode 100644 index ebb371a3f9fb..000000000000 --- a/noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr +++ /dev/null @@ -1,18 +0,0 @@ -use dep::protocol_types::traits::Empty; - -struct AvmContextInputs { - selector: Field, - args_hash: Field, - is_static_call: bool -} - -impl Empty for AvmContextInputs { - fn empty() -> Self { - AvmContextInputs { - selector: 0, - args_hash: 0, - is_static_call: false - } - } -} - diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr index c15ead73744d..9075e5a207dc 100644 --- a/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr +++ b/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr @@ -1,8 +1,10 @@ use dep::protocol_types::traits::Empty; +// These inputs will likely go away once the AVM processes 1 public kernel per enqueued call. struct PublicContextInputs { selector: Field, args_hash: Field, + is_static_call: bool } impl Empty for PublicContextInputs { @@ -10,6 +12,7 @@ impl Empty for PublicContextInputs { PublicContextInputs { selector: 0, args_hash: 0, + is_static_call: false } } } 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 9ac5ff10d532..e7f31971ff71 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -1,14 +1,9 @@ use crate::hash::{compute_secret_hash, compute_message_hash, compute_message_nullifier}; -use dep::protocol_types::{ - address::{AztecAddress, EthAddress}, - constants::{L1_TO_L2_MESSAGE_LENGTH, NESTED_CALL_L2_GAS_BUFFER}, header::Header -}; -use dep::protocol_types::traits::{Deserialize, Serialize, Empty}; +use dep::protocol_types::address::{AztecAddress, EthAddress}; +use dep::protocol_types::traits::{Deserialize, Empty}; use dep::protocol_types::abis::function_selector::FunctionSelector; -use dep::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs; use crate::context::inputs::public_context_inputs::PublicContextInputs; -use crate::context::interface::ContextInterface; -use crate::context::interface::PublicContextInterface; +use crate::context::interface::{ContextInterface, PublicContextInterface}; use crate::context::gas::GasOpts; struct PublicContext { @@ -192,75 +187,78 @@ impl ContextInterface for PublicContext { // Helper functions fn gas_for_call(user_gas: GasOpts) -> [Field; 2] { + // It's ok to use the max possible gas here, because the gas will be + // capped by the gas left in the (STATIC)CALL instruction. + let MAX_POSSIBLE_FIELD: Field = 0 - 1; [ - user_gas.l2_gas.unwrap_or_else(|| l2_gas_left() - NESTED_CALL_L2_GAS_BUFFER), - user_gas.da_gas.unwrap_or_else(|| da_gas_left()) + user_gas.l2_gas.unwrap_or(MAX_POSSIBLE_FIELD), + user_gas.da_gas.unwrap_or(MAX_POSSIBLE_FIELD) ] } // Unconstrained opcode wrappers (do not use directly). // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6420): reconsider. -fn address() -> AztecAddress { +unconstrained fn address() -> AztecAddress { address_opcode() } -fn storage_address() -> AztecAddress { +unconstrained fn storage_address() -> AztecAddress { storage_address_opcode() } -fn sender() -> AztecAddress { +unconstrained fn sender() -> AztecAddress { sender_opcode() } -fn portal() -> EthAddress { +unconstrained fn portal() -> EthAddress { portal_opcode() } -fn fee_per_l2_gas() -> Field { +unconstrained fn fee_per_l2_gas() -> Field { fee_per_l2_gas_opcode() } -fn fee_per_da_gas() -> Field { +unconstrained fn fee_per_da_gas() -> Field { fee_per_da_gas_opcode() } -fn transaction_fee() -> Field { +unconstrained fn transaction_fee() -> Field { transaction_fee_opcode() } -fn chain_id() -> Field { +unconstrained fn chain_id() -> Field { chain_id_opcode() } -fn version() -> Field { +unconstrained fn version() -> Field { version_opcode() } -fn block_number() -> Field { +unconstrained fn block_number() -> Field { block_number_opcode() } -fn timestamp() -> u64 { +unconstrained fn timestamp() -> u64 { timestamp_opcode() } -fn l2_gas_left() -> Field { +unconstrained fn l2_gas_left() -> Field { l2_gas_left_opcode() } -fn da_gas_left() -> Field { +unconstrained fn da_gas_left() -> Field { da_gas_left_opcode() } -fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u8 { +unconstrained fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u8 { note_hash_exists_opcode(note_hash, leaf_index) } -fn emit_note_hash(note_hash: Field) { +unconstrained fn emit_note_hash(note_hash: Field) { emit_note_hash_opcode(note_hash) } -fn nullifier_exists(nullifier: Field, address: Field) -> u8 { +unconstrained fn nullifier_exists(nullifier: Field, address: Field) -> u8 { nullifier_exists_opcode(nullifier, address) } -fn emit_nullifier(nullifier: Field) { +unconstrained fn emit_nullifier(nullifier: Field) { emit_nullifier_opcode(nullifier) } -fn emit_unencrypted_log(event_selector: Field, message: T) { +unconstrained fn emit_unencrypted_log(event_selector: Field, message: T) { emit_unencrypted_log_opcode(event_selector, message) } -fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u8 { +unconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u8 { l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index) } -fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) { +unconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) { send_l2_to_l1_msg_opcode(recipient, content) } -fn call( +unconstrained fn call( gas: [Field; 2], address: AztecAddress, args: [Field], @@ -268,7 +266,7 @@ fn call( ) -> ([Field; RET_SIZE], u8) { call_opcode(gas, address, args, function_selector) } -fn call_static( +unconstrained fn call_static( gas: [Field; 2], address: AztecAddress, args: [Field], diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index f782be2ca3a4..5d9ad2b7e300 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -1,7 +1,4 @@ -use crate::{ - context::{AvmContext, PublicContext}, oracle::{storage::{storage_read, storage_write}}, - state_vars::storage::Storage -}; +use crate::{context::PublicContext, oracle::{storage::{storage_read, storage_write}}, state_vars::storage::Storage}; use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}}; // Just like SharedImmutable but without the ability to read from private functions. @@ -66,35 +63,3 @@ impl PublicImmutable { T::deserialize(fields) } } - -// TODO (https://github.com/AztecProtocol/aztec-packages/issues/5818): remove this impl and leave the PublicContext impl -// once AvmContext becomes PublicContext. -impl PublicImmutable { - // docs:start:public_immutable_struct_write - pub fn initialize(self, value: T) where T: Serialize { - // TODO(#4738): Uncomment the following assert - // assert( - // self.context.public.unwrap_unchecked().is_deployment(), "PublicImmutable can only be initialized during contract deployment" - // ); - - // We check that the struct is not yet initialized by checking if the initialization slot is 0 - let initialization_slot = INITIALIZATION_SLOT_SEPARATOR + self.storage_slot; - let fields_read: [Field; 1] = storage_read(initialization_slot); - assert(fields_read[0] == 0, "PublicImmutable already initialized"); - - // We populate the initialization slot with a non-zero value to indicate that the struct is initialized - storage_write(initialization_slot, [0xdead]); - - let fields_write = T::serialize(value); - storage_write(self.storage_slot, fields_write); - } - // docs:end:public_immutable_struct_write - - // Note that we don't access the context, but we do call oracles that are only available in public - // docs:start:public_immutable_struct_read - pub fn read(self) -> T where T: Deserialize { - let fields = storage_read(self.storage_slot); - T::deserialize(fields) - } - // docs:end:public_immutable_struct_read -} diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr index 128d8a4ce470..f3ce3a6d1405 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr @@ -1,4 +1,4 @@ -use crate::context::{AvmContext, PublicContext}; +use crate::context::PublicContext; use crate::oracle::storage::storage_read; use crate::oracle::storage::storage_write; use dep::protocol_types::traits::{Deserialize, Serialize}; @@ -51,21 +51,3 @@ impl PublicMutable { T::deserialize(fields) } } - -// TODO (https://github.com/AztecProtocol/aztec-packages/issues/5818): remove this impl and leave the PublicContext impl -// once AvmContext becomes PublicContext. -impl PublicMutable { - // docs:start:public_mutable_struct_read - pub fn read(self) -> T where T: Deserialize { - let fields = storage_read(self.storage_slot); - T::deserialize(fields) - } - // docs:end:public_mutable_struct_read - - // docs:start:public_mutable_struct_write - pub fn write(self, value: T) where T: Serialize { - let fields = T::serialize(value); - storage_write(self.storage_slot, fields); - } - // docs:end:public_mutable_struct_write -} diff --git a/noir-projects/noir-contracts/bootstrap.sh b/noir-projects/noir-contracts/bootstrap.sh index 880ef561f814..3eb62c4530f3 100755 --- a/noir-projects/noir-contracts/bootstrap.sh +++ b/noir-projects/noir-contracts/bootstrap.sh @@ -19,5 +19,5 @@ echo "Compiling contracts..." NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo} $NARGO compile --silence-warnings -echo "Transpiling avm contracts..." +echo "Transpiling contracts..." scripts/transpile.sh \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr index 9a8431fb2528..e775de82db54 100644 --- a/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr @@ -93,49 +93,4 @@ contract StaticChild { new_value } - - // AVM - - // Returns base_value + chain_id + version + block_number + timestamp statically - #[aztec(public-vm)] - #[aztec(view)] - fn avm_get_value(base_value: Field) -> Field { - let return_value = base_value - + context.chain_id() - + context.version() - + context.block_number() - + context.timestamp() as Field; - - return_value - } - - // Sets `current_value` to `new_value` - #[aztec(public-vm)] - fn avm_set_value(new_value: Field) -> Field { - storage.current_value.write(new_value); - context.emit_unencrypted_log(new_value); - - new_value - } - - // Increments `current_value` by `new_value` - #[aztec(public-vm)] - fn avm_inc_value(new_value: Field) -> Field { - let old_value = storage.current_value.read(); - storage.current_value.write(old_value + new_value); - context.emit_unencrypted_log(new_value); - - new_value - } - - // View function that attempts to modify state. Should always fail regardless how it's called. - #[aztec(public-vm)] - #[aztec(view)] - fn avm_illegal_inc_value(new_value: Field) -> Field { - let old_value = storage.current_value.read(); - storage.current_value.write(old_value + new_value); - context.emit_unencrypted_log(new_value); - - new_value - } } diff --git a/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr index e03529b57d05..7ee891472479 100644 --- a/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr @@ -128,69 +128,4 @@ contract StaticParent { // Call the target public function through the pub entrypoint statically StaticParent::at(context.this_address()).public_call(target_contract, target_selector, args[0]).enqueue_view(&mut context) } - - // AVM - - #[aztec(public-vm)] - fn avm_call( - target_contract: AztecAddress, - target_selector: FunctionSelector, - arg: Field - ) -> Field { - context.call_public_function( - target_contract, - target_selector, - [arg].as_slice(), - GasOpts::default() - ).deserialize_into() - } - - // Public function to statically call another public function to the target_contract using the selector and value provided - #[aztec(public-vm)] - fn avm_static_call( - target_contract: AztecAddress, - target_selector: FunctionSelector, - args: [Field; 1] - ) -> Field { - context.static_call_public_function( - target_contract, - target_selector, - args.as_slice(), - GasOpts::default() - ).deserialize_into() - } - - // Same as above but using a specific function from the interface - #[aztec(public-vm)] - fn avm_get_value_from_child(target_contract: AztecAddress, value: Field) -> Field { - StaticChild::at(target_contract).avm_get_value(value).view(&mut context) - } - - // Public function to set a static context and verify correct propagation for nested public calls - #[aztec(public-vm)] - fn avm_nested_static_call( - target_contract: AztecAddress, - target_selector: FunctionSelector, - args: [Field; 1] - ) -> Field { - // Call the target public function through the pub entrypoint statically - StaticParent::at(context.this_address()).avm_call(target_contract, target_selector, args[0]).view(&mut context) - } - - // Same as above but using a specific function from the interface - #[aztec(private)] - fn enqueue_avm_get_value_from_child(target_contract: AztecAddress, value: Field) { - StaticChild::at(target_contract).avm_get_value(value).enqueue_view(&mut context); - } - - // Private function to set a static context and verify correct propagation of nested enqueuing of public calls - #[aztec(private)] - fn enqueue_static_nested_call_to_avm_function( - target_contract: AztecAddress, - target_selector: FunctionSelector, - args: [Field; 1] - ) { - // Call the target public function through the pub entrypoint statically - StaticParent::at(context.this_address()).avm_call(target_contract, target_selector, args[0]).enqueue_view(&mut context) - } } diff --git a/noir/noir-repo/aztec_macros/src/transforms/functions.rs b/noir/noir-repo/aztec_macros/src/transforms/functions.rs index a82c059aec14..5d99eaee4c6a 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/functions.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/functions.rs @@ -36,15 +36,15 @@ pub fn transform_function( is_internal: bool, is_static: bool, ) -> Result<(), AztecMacroError> { + assert!(matches!(ty, "Private" | "Public")); let context_name = format!("{}Context", ty); let inputs_name = format!("{}ContextInputs", ty); let return_type_name = format!("{}CircuitPublicInputs", ty); - let is_avm = ty == "Public"; let is_private = ty == "Private"; // Force a static context if the function is static if is_static { - let is_static_check = create_static_check(func.name(), is_avm); + let is_static_check = create_static_check(func.name(), is_private); func.def.body.statements.insert(0, is_static_check); } @@ -72,10 +72,10 @@ pub fn transform_function( } // Insert the context creation as the first action - let create_context = if !is_avm { - create_context(&context_name, &func.def.parameters)? + let create_context = if is_private { + create_context_private(&context_name, &func.def.parameters)? } else { - create_context_avm()? + create_context_public()? }; func.def.body.statements.splice(0..0, (create_context).iter().cloned()); @@ -84,7 +84,7 @@ pub fn transform_function( func.def.parameters.insert(0, input); // Abstract return types such that they get added to the kernel's return_values - if !is_avm { + if is_private { if let Some(return_values_statements) = abstract_return_values(func)? { // In case we are pushing return values to the context, we remove the statement that originated it // This avoids running duplicate code, since blocks like if/else can be value returning statements @@ -101,13 +101,13 @@ pub fn transform_function( } // Push the finish method call to the end of the function - if !is_avm { + if is_private { let finish_def = create_context_finish(); func.def.body.statements.push(finish_def); } // The AVM doesn't need a return type yet. - if !is_avm { + if is_private { let return_type = create_return_type(&return_type_name); func.def.return_type = return_type; func.def.return_visibility = Visibility::Public; @@ -116,7 +116,7 @@ pub fn transform_function( } // Public functions should have unconstrained auto-inferred - func.def.is_unconstrained = is_avm; + func.def.is_unconstrained = !is_private; // Private functions need to be recursive if is_private { @@ -285,8 +285,8 @@ fn create_mark_as_initialized(ty: &str) -> Statement { /// ```noir /// assert(context.inputs.call_context.is_static_call == true, "Function can only be called statically") /// ``` -fn create_static_check(fname: &str, is_avm: bool) -> Statement { - let is_static_call_expr = if !is_avm { +fn create_static_check(fname: &str, is_private: bool) -> Statement { + let is_static_call_expr = if is_private { ["inputs", "call_context", "is_static_call"] .iter() .fold(variable("context"), |acc, member| member_access(acc, member)) @@ -410,7 +410,7 @@ fn serialize_to_hasher( /// let mut context = PrivateContext::new(inputs, hasher.hash()); /// } /// ``` -fn create_context(ty: &str, params: &[Param]) -> Result, AztecMacroError> { +fn create_context_private(ty: &str, params: &[Param]) -> Result, AztecMacroError> { let mut injected_statements: Vec = vec![]; let hasher_name = "args_hasher"; @@ -471,8 +471,7 @@ fn create_context(ty: &str, params: &[Param]) -> Result, AztecMac Ok(injected_statements) } -/// Creates the private context object to be accessed within the function, the parameters need to be extracted to be -/// appended into the args hash object. +/// Creates the public context object to be accessed within the function. /// /// The replaced code: /// ```noir @@ -481,7 +480,7 @@ fn create_context(ty: &str, params: &[Param]) -> Result, AztecMac /// let mut context = PublicContext::new(inputs); /// } /// ``` -fn create_context_avm() -> Result, AztecMacroError> { +fn create_context_public() -> Result, AztecMacroError> { let mut injected_expressions: Vec = vec![]; // Create the inputs to the context diff --git a/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts index a55331b5f3b9..3ade8732b5cd 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts @@ -70,7 +70,7 @@ describe('benchmarks/tx_size_fees', () => { // non-rev: 1 nullifiers, overhead; rev: 2 note hashes, 1 nullifier, 1168 B enc note logs, 0 B enc logs, 0 B unenc logs, teardown // L2: // non-rev: 0; rev: 0 - 200021120n, + 200910076n, ], [ 'public fee', @@ -79,7 +79,7 @@ describe('benchmarks/tx_size_fees', () => { // non-rev: 1 nullifiers, overhead; rev: 2 note hashes, 1 nullifier, 1168 B enc note logs, 0 B enc logs,0 B unenc logs, teardown // L2: // non-rev: 0; rev: 0 - 200021120n, + 201440216n, ], [ 'private fee', @@ -88,7 +88,7 @@ describe('benchmarks/tx_size_fees', () => { // non-rev: 3 nullifiers, overhead; rev: 2 note hashes, 1168 B enc note logs, 0 B enc logs, 0 B unenc logs, teardown // L2: // non-rev: 0; rev: 0 - 200021632n, + 200228528n, ], ] as const)( 'sends a tx with a fee with %s payment method', diff --git a/yarn-project/end-to-end/src/e2e_static_calls.test.ts b/yarn-project/end-to-end/src/e2e_static_calls.test.ts index d74e08d5a9c5..07d07eff9430 100644 --- a/yarn-project/end-to-end/src/e2e_static_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_static_calls.test.ts @@ -201,100 +201,4 @@ describe('e2e_static_calls', () => { ).rejects.toThrow(STATIC_CONTEXT_ASSERTION_ERROR); }); }); - - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5818): clean up the following tests and either remove the "public" version above or rename these to be the new public. - // There should be 1:1 correspondence between the two sets of tests. - describe('avm', () => { - describe('direct view calls to child', () => { - it('performs legal public static calls', async () => { - await childContract.methods.avm_get_value(42n).send().wait(); - }); - - it('fails when performing non-static calls to poorly written static public functions', async () => { - await expect(childContract.methods.avm_illegal_inc_value(42n).send().wait()).rejects.toThrow( - STATIC_CALL_STATE_MODIFICATION_ERROR, - ); - }); - }); - - describe('parent calls child', () => { - it('performs legal public to public static calls', async () => { - // Using low level calls - await parentContract.methods - .avm_static_call(childContract.address, childContract.methods.avm_get_value.selector, [42n]) - .send() - .wait(); - - // Using contract interface - await parentContract.methods.public_get_value_from_child(childContract.address, 42n).send().wait(); - }); - - it('performs legal enqueued public static calls', async () => { - // Using low level calls - await parentContract.methods - .enqueue_static_call_to_pub_function(childContract.address, childContract.methods.avm_get_value.selector, [ - 42n, - ]) - .send() - .wait(); - - // Using contract interface - await parentContract.methods.enqueue_avm_get_value_from_child(childContract.address, 42).send().wait(); - }); - - it('performs legal (nested) public to public static calls', async () => { - await parentContract.methods - .avm_nested_static_call(childContract.address, childContract.methods.avm_get_value.selector, [42n]) - .send() - .wait(); - }); - - it('performs legal (nested) enqueued public static calls', async () => { - await parentContract.methods - .enqueue_static_nested_call_to_avm_function( - childContract.address, - childContract.methods.avm_get_value.selector, - [42n], - ) - .send() - .wait(); - }); - - it('fails when performing illegal enqueued public static calls', async () => { - await expect( - parentContract.methods - .enqueue_static_call_to_pub_function(childContract.address, childContract.methods.avm_set_value.selector, [ - 42n, - ]) - .send() - .wait(), - ).rejects.toThrow(STATIC_CALL_STATE_MODIFICATION_ERROR); - }); - - it('fails when performing illegal (nested) enqueued public static calls', async () => { - await expect( - parentContract.methods - .enqueue_static_nested_call_to_avm_function( - childContract.address, - childContract.methods.avm_set_value.selector, - [42n], - ) - .send() - .wait(), - ).rejects.toThrow(STATIC_CALL_STATE_MODIFICATION_ERROR); - }); - - it('fails when performing non-static enqueue calls to poorly written public static functions', async () => { - await expect( - parentContract.methods - .enqueue_call(childContract.address, childContract.methods.avm_illegal_inc_value.selector, [ - 42n, - wallet.getCompleteAddress().address, - ]) - .send() - .wait(), - ).rejects.toThrow(STATIC_CONTEXT_ASSERTION_ERROR); - }); - }); - }); }); diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index 9febceedb10b..1386a3dd23f1 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -39,7 +39,8 @@ import { PublicExecutor } from './executor.js'; export const createMemDown = () => (memdown as any)() as MemDown; -describe('ACIR public execution simulator', () => { +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/5818): remove. +describe.skip('ACIR public execution simulator', () => { let publicState: MockProxy; let publicContracts: MockProxy; let commitmentsDb: MockProxy;