From 75beb5041d7e22acd8a78707bb7bcb7d850f6cb3 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:04:11 +0000 Subject: [PATCH 01/10] feat: oracle to get the contract's portal contract address --- yarn-project/acir-simulator/src/acvm/acvm.ts | 1 + .../src/client/private_execution.test.ts | 18 +++++++++++++++++- .../src/client/private_execution.ts | 4 ++++ .../acir-simulator/src/client/simulator.ts | 1 + .../src/contracts/test_contract/src/main.nr | 13 ++++++++++++- .../noir-libs/noir-aztec/src/context.nr | 6 ++++-- .../noir-libs/noir-aztec/src/oracle.nr | 1 + .../noir-libs/noir-aztec/src/oracle/context.nr | 8 ++++++++ 8 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 yarn-project/noir-libs/noir-aztec/src/oracle/context.nr diff --git a/yarn-project/acir-simulator/src/acvm/acvm.ts b/yarn-project/acir-simulator/src/acvm/acvm.ts index ab20ecf93d5..e858655bc0b 100644 --- a/yarn-project/acir-simulator/src/acvm/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm/acvm.ts @@ -38,6 +38,7 @@ type ORACLE_NAMES = | 'createNullifier' | 'getCommitment' | 'getL1ToL2Message' + | 'getPortalAddress' | 'emitEncryptedLog' | 'emitUnencryptedLog' | 'getPublicKey' diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 2da802b912f..82555e00966 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -85,11 +85,13 @@ describe('Private Execution test suite', () => { args = [], origin = AztecAddress.random(), contractAddress = defaultContractAddress, + portalContractAddress = EthAddress.ZERO, txContext = {}, }: { abi: FunctionAbi; origin?: AztecAddress; contractAddress?: AztecAddress; + portalContractAddress?: EthAddress; args?: any[]; txContext?: Partial>; }) => { @@ -107,7 +109,7 @@ describe('Private Execution test suite', () => { txRequest, abi, functionData.isConstructor ? AztecAddress.ZERO : contractAddress, - EthAddress.ZERO, + portalContractAddress, blockData, ); }; @@ -980,4 +982,18 @@ describe('Private Execution test suite', () => { expect(result.returnValues).toEqual([pubKey.x.value, pubKey.y.value]); }); }); + + describe('Context oracles', () => { + it("Should be able to get and return the contract's portal contract address", async () => { + const portalContractAddress = EthAddress.random(); + + // Tweak the contract ABI so we can extract return values + const abi = TestContractAbi.functions.find(f => f.name === 'getPortalAddress')!; + abi.returnTypes = [{ kind: 'field' }]; + + // Generate a partial address, pubkey, and resulting address + const result = await runSimulator({ origin: AztecAddress.random(), abi, args: [], portalContractAddress }); + expect(result.returnValues).toEqual([portalContractAddress.toField().value]); + }); + }); }); diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 73a60982c61..0a4884adc3a 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -175,6 +175,10 @@ export class PrivateFunctionExecution { return Promise.resolve(ZERO_ACVM_FIELD); }, + getPortalAddress: () => { + // TODO: should this look into the oracle itself? + return Promise.resolve(toACVMField(this.callContext.portalContractAddress)); + }, }); const publicInputs = extractPublicInputs(partialWitness, acir); diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 6c936a29994..36fb1a968b4 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -41,6 +41,7 @@ export class AcirSimulator { request: TxExecutionRequest, entryPointABI: FunctionAbi, contractAddress: AztecAddress, + // TODO: should this be fetched first - where is it calculated portalContractAddress: EthAddress, constantHistoricBlockData: ConstantHistoricBlockData, ): Promise { diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr index 4580fc44c29..e8b1f4f4597 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr @@ -12,7 +12,8 @@ contract Test { use dep::aztec::oracle::{ create_l2_to_l1_message::create_l2_to_l1_message, create_nullifier::create_nullifier, - get_public_key::get_public_key + get_public_key::get_public_key, + context::get_portal_address }; fn constructor( @@ -32,6 +33,16 @@ contract Test { context.finish() } + // Get the portal contract address through an oracle call + fn getPortalAddress( + inputs: PrivateContextInputs, + ) -> distinct pub abi::PrivateCircuitPublicInputs { + let mut context = Context::new(inputs, abi::hash_args([])); + let portal_address = get_portal_address(); + context.return_values.push_array([portal_address]); + context.finish() + } + // Purely exists for testing open fn createL2ToL1MessagePublic( _inputs: PublicContextInputs, diff --git a/yarn-project/noir-libs/noir-aztec/src/context.nr b/yarn-project/noir-libs/noir-aztec/src/context.nr index 4681564d2df..71cd3062007 100644 --- a/yarn-project/noir-libs/noir-aztec/src/context.nr +++ b/yarn-project/noir-libs/noir-aztec/src/context.nr @@ -47,6 +47,7 @@ use crate::oracle::{ call_private_function::call_private_function_internal, public_call::call_public_function_internal, enqueue_public_function_call::enqueue_public_function_call_internal, + context::get_portal_address, }; @@ -104,8 +105,9 @@ impl Context { self.inputs.call_context.storage_contract_address } - fn this_portal_address(self) -> Field { - self.inputs.call_context.portal_contract_address + fn this_portal_address(_self: Self) -> Field { + // Get the portal contract address from an oracle call + get_portal_address() } fn chain_id(self) -> Field { diff --git a/yarn-project/noir-libs/noir-aztec/src/oracle.nr b/yarn-project/noir-libs/noir-aztec/src/oracle.nr index b99008a6c1f..13834c14dc6 100644 --- a/yarn-project/noir-libs/noir-aztec/src/oracle.nr +++ b/yarn-project/noir-libs/noir-aztec/src/oracle.nr @@ -1,5 +1,6 @@ mod arguments; mod call_private_function; +mod context; mod create_commitment; mod create_l2_to_l1_message; mod create_nullifier; diff --git a/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr b/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr new file mode 100644 index 00000000000..9de8ffe4d04 --- /dev/null +++ b/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr @@ -0,0 +1,8 @@ +#[oracle(getPortalAddress)] +fn _get_portal_address() -> Field {} + + +unconstrained fn get_portal_address() -> Field { + let portal_address = _get_portal_address(); + portal_address +} \ No newline at end of file From e64a3e2f19deb53c6e802aa0d0c8672d0c2f6181 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:10:58 +0000 Subject: [PATCH 02/10] fix: use context rather than oracle directly --- .../noir-contracts/src/contracts/test_contract/src/main.nr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr index e8b1f4f4597..9d5b7728836 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr @@ -12,8 +12,7 @@ contract Test { use dep::aztec::oracle::{ create_l2_to_l1_message::create_l2_to_l1_message, create_nullifier::create_nullifier, - get_public_key::get_public_key, - context::get_portal_address + get_public_key::get_public_key }; fn constructor( @@ -38,7 +37,7 @@ contract Test { inputs: PrivateContextInputs, ) -> distinct pub abi::PrivateCircuitPublicInputs { let mut context = Context::new(inputs, abi::hash_args([])); - let portal_address = get_portal_address(); + let portal_address = context.this_portal_address(); context.return_values.push_array([portal_address]); context.finish() } From 2a0b7659e119296eb92f0bcadbfa7630a01bc2ff Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:33:01 +0000 Subject: [PATCH 03/10] feat: generalise query --- yarn-project/acir-simulator/src/acvm/acvm.ts | 2 +- .../src/client/private_execution.test.ts | 10 +++++++--- .../acir-simulator/src/client/private_execution.ts | 7 ++++--- .../src/contracts/test_contract/src/main.nr | 8 +++++--- yarn-project/noir-libs/noir-aztec/src/context.nr | 5 ++--- .../noir-libs/noir-aztec/src/oracle/context.nr | 9 ++++----- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/acvm.ts b/yarn-project/acir-simulator/src/acvm/acvm.ts index e858655bc0b..d6d9ed81e8a 100644 --- a/yarn-project/acir-simulator/src/acvm/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm/acvm.ts @@ -38,7 +38,7 @@ type ORACLE_NAMES = | 'createNullifier' | 'getCommitment' | 'getL1ToL2Message' - | 'getPortalAddress' + | 'getPortalContractAddress' | 'emitEncryptedLog' | 'emitUnencryptedLog' | 'getPublicKey' diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 82555e00966..09487891814 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -986,13 +986,17 @@ describe('Private Execution test suite', () => { describe('Context oracles', () => { it("Should be able to get and return the contract's portal contract address", async () => { const portalContractAddress = EthAddress.random(); + const aztecAddressToQuery = AztecAddress.random(); // Tweak the contract ABI so we can extract return values - const abi = TestContractAbi.functions.find(f => f.name === 'getPortalAddress')!; + const abi = TestContractAbi.functions.find(f => f.name === 'getPortalContractAddress')!; abi.returnTypes = [{ kind: 'field' }]; - // Generate a partial address, pubkey, and resulting address - const result = await runSimulator({ origin: AztecAddress.random(), abi, args: [], portalContractAddress }); + const args = [aztecAddressToQuery.toField()]; + + // Overwrite the oracle return value + oracle.getPortalContractAddress.mockResolvedValue(portalContractAddress); + const result = await runSimulator({ origin: AztecAddress.random(), abi, args }); expect(result.returnValues).toEqual([portalContractAddress.toField().value]); }); }); diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 0a4884adc3a..12b8250409a 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -175,9 +175,10 @@ export class PrivateFunctionExecution { return Promise.resolve(ZERO_ACVM_FIELD); }, - getPortalAddress: () => { - // TODO: should this look into the oracle itself? - return Promise.resolve(toACVMField(this.callContext.portalContractAddress)); + getPortalContractAddress: async ([aztecAddress]) => { + const contractAddress = AztecAddress.fromString(aztecAddress); + const portalContactAddress = await this.context.db.getPortalContractAddress(contractAddress); + return Promise.resolve(toACVMField(portalContactAddress)); }, }); diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr index 9d5b7728836..e2b66107ffe 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr @@ -12,7 +12,8 @@ contract Test { use dep::aztec::oracle::{ create_l2_to_l1_message::create_l2_to_l1_message, create_nullifier::create_nullifier, - get_public_key::get_public_key + get_public_key::get_public_key, + context::get_portal_address }; fn constructor( @@ -33,11 +34,12 @@ contract Test { } // Get the portal contract address through an oracle call - fn getPortalAddress( + fn getPortalContractAddress( inputs: PrivateContextInputs, + aztec_address: Field ) -> distinct pub abi::PrivateCircuitPublicInputs { let mut context = Context::new(inputs, abi::hash_args([])); - let portal_address = context.this_portal_address(); + let portal_address = get_portal_address(aztec_address); context.return_values.push_array([portal_address]); context.finish() } diff --git a/yarn-project/noir-libs/noir-aztec/src/context.nr b/yarn-project/noir-libs/noir-aztec/src/context.nr index 71cd3062007..36811cd88f0 100644 --- a/yarn-project/noir-libs/noir-aztec/src/context.nr +++ b/yarn-project/noir-libs/noir-aztec/src/context.nr @@ -105,9 +105,8 @@ impl Context { self.inputs.call_context.storage_contract_address } - fn this_portal_address(_self: Self) -> Field { - // Get the portal contract address from an oracle call - get_portal_address() + fn this_portal_address(self) -> Field { + self.inputs.call_context.portal_contract_address } fn chain_id(self) -> Field { diff --git a/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr b/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr index 9de8ffe4d04..1b70c476d9a 100644 --- a/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr +++ b/yarn-project/noir-libs/noir-aztec/src/oracle/context.nr @@ -1,8 +1,7 @@ -#[oracle(getPortalAddress)] -fn _get_portal_address() -> Field {} +#[oracle(getPortalContractAddress)] +fn _get_portal_address(_contract_address: Field) -> Field {} - -unconstrained fn get_portal_address() -> Field { - let portal_address = _get_portal_address(); +unconstrained fn get_portal_address(contract_address: Field) -> Field { + let portal_address = _get_portal_address(contract_address); portal_address } \ No newline at end of file From d16c5b0a109a9f2a69ca71b7977d16027ef8fb9e Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:41:34 +0000 Subject: [PATCH 04/10] feat: alter uniswap test to use new oracle --- .../src/uniswap_trade_on_l1_from_l2.test.ts | 5 ++--- .../src/contracts/uniswap_contract/src/main.nr | 13 ++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts index 6ac27d8b1bb..13e6504f306 100644 --- a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts @@ -23,7 +23,8 @@ import { delay, deployAndInitializeNonNativeL2TokenContracts, setup } from './fi const dumpedState = 'src/fixtures/dumps/uniswap_state'; // When taking a dump use the block number of the fork to improve speed. -const EXPECTED_FORKED_BLOCK = 0; //17514288; +// const EXPECTED_FORKED_BLOCK = 0; //17514288; +const EXPECTED_FORKED_BLOCK = 17514288; // We tell the archiver to only sync from this block. process.env.SEARCH_START_BLOCK = EXPECTED_FORKED_BLOCK.toString(); @@ -196,11 +197,9 @@ describe('uniswap_trade_on_l1_from_l2', () => { .swap( selector, wethCrossChainHarness.l2Contract.address.toField(), - wethCrossChainHarness.tokenPortalAddress.toField(), wethAmountToBridge, new Fr(3000), daiCrossChainHarness.l2Contract.address.toField(), - daiCrossChainHarness.tokenPortalAddress.toField(), new Fr(minimumOutputAmount), ownerAddress, ownerAddress, diff --git a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr index bdb6b086a9d..1807dfb5e67 100644 --- a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr @@ -4,7 +4,10 @@ contract Uniswap { use dep::aztec::abi::PrivateContextInputs; use dep::aztec::abi::PublicContextInputs; use dep::aztec::context::Context; - use dep::aztec::oracle::public_call; + use dep::aztec::oracle::{ + public_call, + context::get_portal_address + }; use dep::aztec::private_call_stack_item::PrivateCallStackItem; use dep::aztec::public_call_stack_item::PublicCallStackItem; use dep::aztec::types::point::Point; @@ -28,11 +31,9 @@ contract Uniswap { inputs: PrivateContextInputs, withdrawFnSelector: Field, // withdraw method on inputAsset (l2 contract) that would withdraw to L1 inputAsset: Field, - inputAssetPortalAddress: Field, // l1 portal of input asset inputAmount: Field, uniswapFeeTier: Field, // which uniswap tier to use (eg 3000 for 0.3% fee) outputAsset: Field, - outputAssetPortalAddress: Field, // l1 portal of output asset minimumOutputAmount: Field, // minimum output amount to receive (slippage protection for the swap) sender: Field, recipient: Field, // receiver address of output asset after the swap @@ -45,11 +46,9 @@ contract Uniswap { let mut context = Context::new(inputs, abi::hash_args([ withdrawFnSelector, inputAsset, - inputAssetPortalAddress, inputAmount, uniswapFeeTier, outputAsset, - outputAssetPortalAddress, minimumOutputAmount, sender, recipient, @@ -73,6 +72,10 @@ contract Uniswap { let result = return_values[0]; context.return_values.push(result); + // Get portal addresses + let inputAssetPortalAddress = get_portal_address(inputAsset); + let outputAssetPortalAddress = get_portal_address(outputAsset); + // Send the swap message to L1 portal let content_hash = _compute_swap_content_hash( inputAssetPortalAddress, From 30efbf325dbdc0950d331ae86b16b40b97226848 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:45:58 +0000 Subject: [PATCH 05/10] more uniswap pruning --- .../src/uniswap_trade_on_l1_from_l2.test.ts | 1 - .../src/contracts/uniswap_contract/src/main.nr | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts index 13e6504f306..5d88bfe65fb 100644 --- a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts @@ -206,7 +206,6 @@ describe('uniswap_trade_on_l1_from_l2', () => { secretHash, new Fr(2 ** 32 - 1), ethAccount.toField(), - uniswapPortalAddress, ethAccount.toField(), ) .send({ origin: ownerAddress }); diff --git a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr index 1807dfb5e67..f8c213173cd 100644 --- a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr @@ -40,7 +40,6 @@ contract Uniswap { secretHash: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 deadlineForL1ToL2Message: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 cancellerForL1ToL2Message: Field, // L1 address of who can cancel the message to consume assets on L2. - l1UniswapPortal: Field, // L1 address of uniswap portal contract callerOnL1: Field, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) -> distinct pub abi::PrivateCircuitPublicInputs { let mut context = Context::new(inputs, abi::hash_args([ @@ -55,10 +54,14 @@ contract Uniswap { secretHash, deadlineForL1ToL2Message, cancellerForL1ToL2Message, - l1UniswapPortal, callerOnL1, ])); + // Get portal addresses + let l1UniswapPortal = context.this_portal_address(); + let inputAssetPortalAddress = get_portal_address(inputAsset); + let outputAssetPortalAddress = get_portal_address(outputAsset); + // inputAsset.withdraw(inputAmount, sender, recipient=l1UniswapPortal, callerOnL1=l1UniswapPortal) // only uniswap portal can call this (done to safeguard ordering of message consumption) // ref: https://docs.aztec.network/aztec/how-it-works/l1-l2-messaging#designated-caller @@ -72,10 +75,6 @@ contract Uniswap { let result = return_values[0]; context.return_values.push(result); - // Get portal addresses - let inputAssetPortalAddress = get_portal_address(inputAsset); - let outputAssetPortalAddress = get_portal_address(outputAsset); - // Send the swap message to L1 portal let content_hash = _compute_swap_content_hash( inputAssetPortalAddress, From f1b8b4b266397f62be9b5947399c4a7592c4eb8a Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:48:30 +0000 Subject: [PATCH 06/10] fix: prune sandbox example --- .../aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts index bfe14d21cdc..60c1f44c283 100644 --- a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts +++ b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts @@ -246,18 +246,15 @@ async function main() { .swap( selector, wethL2Contract.address.toField(), - wethTokenPortalAddress.toField(), wethAmountToBridge, new Fr(3000), daiL2Contract.address.toField(), - daiTokenPortalAddress.toField(), new Fr(minimumOutputAmount), owner, owner, secretHash, new Fr(2 ** 32 - 1), ethAccount.toField(), - uniswapPortalAddress, ethAccount.toField(), ) .send({ origin: owner }); From 17fade7e7013219845d5fb796da8bdbd4a9e9dec Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:52:11 +0000 Subject: [PATCH 07/10] clean --- yarn-project/acir-simulator/src/client/simulator.ts | 1 - .../aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts | 2 -- .../end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 36fb1a968b4..6c936a29994 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -41,7 +41,6 @@ export class AcirSimulator { request: TxExecutionRequest, entryPointABI: FunctionAbi, contractAddress: AztecAddress, - // TODO: should this be fetched first - where is it calculated portalContractAddress: EthAddress, constantHistoricBlockData: ConstantHistoricBlockData, ): Promise { diff --git a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts index 60c1f44c283..09bd46d7c29 100644 --- a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts +++ b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts @@ -129,7 +129,6 @@ async function deployAllContracts(owner: AztecAddress) { wethTokenPortalAddress, uniswapL2Contract, uniswapPortal, - uniswapPortalAddress, }; } @@ -185,7 +184,6 @@ async function main() { wethTokenPortalAddress, uniswapL2Contract, uniswapPortal, - uniswapPortalAddress, } = result; // Give me some WETH so I can deposit to L2 and do the swap... diff --git a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts index 5d88bfe65fb..4751d3cf3b1 100644 --- a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts @@ -23,8 +23,7 @@ import { delay, deployAndInitializeNonNativeL2TokenContracts, setup } from './fi const dumpedState = 'src/fixtures/dumps/uniswap_state'; // When taking a dump use the block number of the fork to improve speed. -// const EXPECTED_FORKED_BLOCK = 0; //17514288; -const EXPECTED_FORKED_BLOCK = 17514288; +const EXPECTED_FORKED_BLOCK = 0; //17514288; // We tell the archiver to only sync from this block. process.env.SEARCH_START_BLOCK = EXPECTED_FORKED_BLOCK.toString(); From dd52908f46c4c560d47d1f26d00eddac89caef18 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 12:12:53 +0000 Subject: [PATCH 08/10] fix: cleanup public contract data indexing --- .../src/client/unconstrained_execution.ts | 5 +++ .../acir-simulator/src/public/executor.ts | 6 ++++ .../archiver/src/archiver/archiver_store.ts | 32 +++++++++++-------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index bf659acc31f..dda38312c8b 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -83,6 +83,11 @@ export class UnconstrainedFunctionExecution { } return values.map(v => toACVMField(v)); }, + getPortalContractAddress: async ([aztecAddress]) => { + const contractAddress = AztecAddress.fromString(aztecAddress); + const portalContactAddress = await this.context.db.getPortalContractAddress(contractAddress); + return Promise.resolve(toACVMField(portalContactAddress)); + }, }); const returnValues: ACVMField[] = extractReturnWitness(acir, partialWitness); diff --git a/yarn-project/acir-simulator/src/public/executor.ts b/yarn-project/acir-simulator/src/public/executor.ts index 94c8018686d..83ca02add8d 100644 --- a/yarn-project/acir-simulator/src/public/executor.ts +++ b/yarn-project/acir-simulator/src/public/executor.ts @@ -152,6 +152,12 @@ export class PublicExecutor { this.log(`Emitted unencrypted log: "${log.toString('ascii')}"`); return Promise.resolve(ZERO_ACVM_FIELD); }, + getPortalContractAddress: async ([aztecAddress]) => { + const contractAddress = AztecAddress.fromString(aztecAddress); + let portalContactAddress = await this.contractsDb.getPortalContractAddress(contractAddress); + if (!portalContactAddress) portalContactAddress = EthAddress.ZERO; + return Promise.resolve(toACVMField(portalContactAddress)); + }, }); const returnValues = extractReturnWitness(acir, partialWitness).map(fromACVMField); diff --git a/yarn-project/archiver/src/archiver/archiver_store.ts b/yarn-project/archiver/src/archiver/archiver_store.ts index 80fbfd82c66..64fab096c37 100644 --- a/yarn-project/archiver/src/archiver/archiver_store.ts +++ b/yarn-project/archiver/src/archiver/archiver_store.ts @@ -160,7 +160,12 @@ export class MemoryArchiverStore implements ArchiverDataStore { /** * A sparse array containing all the contract data that have been fetched so far. */ - private contractPublicData: (ContractPublicData[] | undefined)[] = []; + private contractPublicDataByBlock: (ContractPublicData[] | undefined)[] = []; + + /** + * A mapping of contract address to contract data. + */ + private contractPublicData: Map = new Map(); /** * Contains all the confirmed L1 to L2 messages (i.e. messages that were consumed in an L2 block) @@ -241,10 +246,17 @@ export class MemoryArchiverStore implements ArchiverDataStore { * @returns True if the operation is successful (always in this implementation). */ public addL2ContractPublicData(data: ContractPublicData[], blockNum: number): Promise { - if (this.contractPublicData[blockNum]?.length) { - this.contractPublicData[blockNum]?.push(...data); + // Add to the contracts mapping + for (const contractData of data) { + const key = contractData.contractData.contractAddress.toString(); + this.contractPublicData.set(key, contractData); + } + + // Add the index per block + if (this.contractPublicDataByBlock[blockNum]?.length) { + this.contractPublicDataByBlock[blockNum]?.push(...data); } else { - this.contractPublicData[blockNum] = [...data]; + this.contractPublicDataByBlock[blockNum] = [...data]; } return Promise.resolve(true); } @@ -316,15 +328,7 @@ export class MemoryArchiverStore implements ArchiverDataStore { * @returns The contract's public data. */ public getL2ContractPublicData(contractAddress: AztecAddress): Promise { - let result; - for (let i = INITIAL_L2_BLOCK_NUM; i < this.contractPublicData.length; i++) { - const contracts = this.contractPublicData[i]; - const contract = contracts?.find(c => c.contractData.contractAddress.equals(contractAddress)); - if (contract) { - result = contract; - break; - } - } + const result = this.contractPublicData.get(contractAddress.toString()); return Promise.resolve(result); } @@ -337,7 +341,7 @@ export class MemoryArchiverStore implements ArchiverDataStore { if (blockNum > this.l2Blocks.length) { return Promise.resolve([]); } - return Promise.resolve(this.contractPublicData[blockNum] || []); + return Promise.resolve(this.contractPublicDataByBlock[blockNum] || []); } /** From 80edc4cf7d9933097ca70a498b3f24da8d680931 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 15:36:23 +0000 Subject: [PATCH 09/10] sugar --- yarn-project/acir-simulator/src/public/executor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/acir-simulator/src/public/executor.ts b/yarn-project/acir-simulator/src/public/executor.ts index 83ca02add8d..5fa5ec06dcc 100644 --- a/yarn-project/acir-simulator/src/public/executor.ts +++ b/yarn-project/acir-simulator/src/public/executor.ts @@ -154,8 +154,8 @@ export class PublicExecutor { }, getPortalContractAddress: async ([aztecAddress]) => { const contractAddress = AztecAddress.fromString(aztecAddress); - let portalContactAddress = await this.contractsDb.getPortalContractAddress(contractAddress); - if (!portalContactAddress) portalContactAddress = EthAddress.ZERO; + const portalContactAddress = + (await this.contractsDb.getPortalContractAddress(contractAddress)) ?? EthAddress.ZERO; return Promise.resolve(toACVMField(portalContactAddress)); }, }); From bdf9b426449aa1875d95d58aa9fd6bd605f4097c Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 9 Aug 2023 15:11:06 +0000 Subject: [PATCH 10/10] chore(context): add unit tests for context utility functions --- .../src/client/private_execution.test.ts | 24 +++++++++++++++++++ .../src/contracts/test_contract/src/main.nr | 20 ++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 09487891814..43a69221d78 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -999,5 +999,29 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ origin: AztecAddress.random(), abi, args }); expect(result.returnValues).toEqual([portalContractAddress.toField().value]); }); + + it('this_address should return the current context address', async () => { + const contractAddress = AztecAddress.random(); + + // Tweak the contract ABI so we can extract return values + const abi = TestContractAbi.functions.find(f => f.name === 'getThisAddress')!; + abi.returnTypes = [{ kind: 'field' }]; + + // Overwrite the oracle return value + const result = await runSimulator({ origin: AztecAddress.random(), abi, args: [], contractAddress }); + expect(result.returnValues).toEqual([contractAddress.toField().value]); + }); + + it("this_portal_address should return the current context's portal address", async () => { + const portalContractAddress = EthAddress.random(); + + // Tweak the contract ABI so we can extract return values + const abi = TestContractAbi.functions.find(f => f.name === 'getThisPortalAddress')!; + abi.returnTypes = [{ kind: 'field' }]; + + // Overwrite the oracle return value + const result = await runSimulator({ origin: AztecAddress.random(), abi, args: [], portalContractAddress }); + expect(result.returnValues).toEqual([portalContractAddress.toField().value]); + }); }); }); diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr index e2b66107ffe..db44cc275b5 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr @@ -44,6 +44,26 @@ contract Test { context.finish() } + // Get the address of the l1 portal for this contract (taken from the input context) + fn getThisPortalAddress( + inputs: PrivateContextInputs, + ) -> distinct pub abi::PrivateCircuitPublicInputs { + let mut context = Context::new(inputs, abi::hash_args([])); + let this_portal_address = context.this_portal_address(); + context.return_values.push_array([this_portal_address]); + context.finish() + } + + // Get the address of this contract (taken from the input context) + fn getThisAddress( + inputs: PrivateContextInputs, + ) -> distinct pub abi::PrivateCircuitPublicInputs { + let mut context = Context::new(inputs, abi::hash_args([])); + let this_address = context.this_address(); + context.return_values.push_array([this_address]); + context.finish() + } + // Purely exists for testing open fn createL2ToL1MessagePublic( _inputs: PublicContextInputs,