From c8e79136a19fdfa695fd2e5c830e22af14c02b51 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Tue, 5 Sep 2023 08:27:31 +0000 Subject: [PATCH 1/5] feat: Update selector computation --- yarn-project/foundation/src/abi/decoder.ts | 43 ++++++++++++++++++- .../foundation/src/abi/function_selector.ts | 4 +- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/yarn-project/foundation/src/abi/decoder.ts b/yarn-project/foundation/src/abi/decoder.ts index 778e109bf51..4153be9f94c 100644 --- a/yarn-project/foundation/src/abi/decoder.ts +++ b/yarn-project/foundation/src/abi/decoder.ts @@ -1,4 +1,4 @@ -import { ABIType, FunctionAbi } from '@aztec/foundation/abi'; +import { ABIParameter, ABIType, FunctionAbi } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; /** @@ -86,3 +86,44 @@ class ReturnValuesDecoder { export function decodeReturnValues(abi: FunctionAbi, returnValues: Fr[]) { return new ReturnValuesDecoder(abi, returnValues.slice()).decode(); } + +/** + * Decodes the signature of a function from the name and parameters. + */ +export class FunctionSignatureDecoder { + constructor(private name: string, private parameters: ABIParameter[]) {} + + /** + * Decodes a single function parameter for the function signature. + * @param param - The parameter to decode. + * @returns A string representing the parameter type. + */ + private decodeParameter(param: ABIType): string { + switch (param.kind) { + case 'field': + return 'Field'; + case 'integer': + if (param.sign === 'signed') { + throw new Error('Unsupported type: signed integer'); + } + return `u${param.width}`; + case 'boolean': + return 'bool'; + case 'array': + return `[${this.decodeParameter(param.type)};${param.length}]`; + case 'struct': + return `(${param.fields.map(field => `${this.decodeParameter(field.type)}`).join(',')})`; + default: + throw new Error(`Unsupported type: ${param.kind}`); + } + } + + /** + * Decodes all the parameters and build the function signature + * @returns The function signature. + */ + public decode(): string { + const hmm = this.parameters.map(param => this.decodeParameter(param.type)); + return `${this.name}(${hmm.join(',')})`; + } +} diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index dac9909eaaa..bb932554a62 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -1,4 +1,4 @@ -import { ABIParameter } from '@aztec/foundation/abi'; +import { ABIParameter, FunctionSignatureDecoder } from '@aztec/foundation/abi'; import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; import { keccak } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; @@ -97,7 +97,7 @@ export class FunctionSelector { * @returns A Buffer containing the 4-byte function selector. */ static fromNameAndParameters(name: string, parameters: ABIParameter[]) { - const signature = name === 'constructor' ? name : `${name}(${parameters.map(p => p.type.kind).join(',')})`; + const signature = new FunctionSignatureDecoder(name, parameters).decode(); return FunctionSelector.fromSignature(signature); } From 3af400ac996a98dd96bf1951ce8ebd2ec4fa758f Mon Sep 17 00:00:00 2001 From: LHerskind Date: Tue, 5 Sep 2023 10:43:35 +0000 Subject: [PATCH 2/5] feat: add oracle for selector computation --- yarn-project/acir-simulator/src/acvm/acvm.ts | 1 + .../src/client/function_selectors.ts | 2 +- .../src/client/private_execution.ts | 5 +++ .../src/client/unconstrained_execution.ts | 7 +++- .../acir-simulator/src/public/executor.ts | 5 ++- .../src/e2e_lending_contract.test.ts | 7 ++-- .../foundation/src/abi/function_selector.ts | 5 ++- .../src/contracts/child_contract/src/main.nr | 11 ++++--- .../lending_contract/src/interfaces.nr | 17 +++++----- .../contracts/lending_contract/src/main.nr | 33 ++++++++++--------- .../native_token_contract/src/main.nr | 28 +++------------- .../non_native_token_contract/src/main.nr | 7 ++-- .../src/contracts/parent_contract/src/main.nr | 9 ++--- .../src/interface.nr | 12 +++---- .../private_token_contract/src/interface.nr | 4 +-- .../contracts/test_contract/src/interface.nr | 18 +++++----- .../noir-libs/noir-aztec/src/oracle.nr | 3 +- .../noir-aztec/src/oracle/compute_selector.nr | 6 ++++ 18 files changed, 97 insertions(+), 83 deletions(-) create mode 100644 yarn-project/noir-libs/noir-aztec/src/oracle/compute_selector.nr diff --git a/yarn-project/acir-simulator/src/acvm/acvm.ts b/yarn-project/acir-simulator/src/acvm/acvm.ts index 23f3a477b58..076842c1a6d 100644 --- a/yarn-project/acir-simulator/src/acvm/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm/acvm.ts @@ -32,6 +32,7 @@ export const ONE_ACVM_FIELD: ACVMField = `0x${'00'.repeat(Fr.SIZE_IN_BYTES - 1)} * The supported oracle names. */ type ORACLE_NAMES = + | 'computeSelector' | 'packArguments' | 'getSecretKey' | 'getNote' diff --git a/yarn-project/acir-simulator/src/client/function_selectors.ts b/yarn-project/acir-simulator/src/client/function_selectors.ts index 1c8e34f0a35..900969623cb 100644 --- a/yarn-project/acir-simulator/src/client/function_selectors.ts +++ b/yarn-project/acir-simulator/src/client/function_selectors.ts @@ -1,5 +1,5 @@ import { FunctionSelector } from '@aztec/circuits.js'; -export const computeNoteHashAndNullifierSignature = 'compute_note_hash_and_nullifier(field,field,field,array)'; +export const computeNoteHashAndNullifierSignature = 'compute_note_hash_and_nullifier(Field,Field,Field,[Field;3])'; export const computeNoteHashAndNullifierSelector = FunctionSelector.fromSignature(computeNoteHashAndNullifierSignature); diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 943c89a4839..4a079ca3b5b 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -72,6 +72,11 @@ export class PrivateFunctionExecution { const unencryptedLogs = new FunctionL2Logs([]); const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, { + computeSelector: (...args) => { + const signature = oracleDebugCallToFormattedStr(args); + const returnValue = toACVMField(FunctionSelector.fromSignature(signature).toField()); + return Promise.resolve(returnValue); + }, packArguments: async args => { return toACVMField(await this.context.packedArgsCache.pack(args.map(fromACVMField))); }, diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index cc679d8313a..f11c95d4c70 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -1,5 +1,5 @@ import { CallContext, FunctionData } from '@aztec/circuits.js'; -import { DecodedReturn, decodeReturnValues } from '@aztec/foundation/abi'; +import { DecodedReturn, FunctionSelector, decodeReturnValues } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -48,6 +48,11 @@ export class UnconstrainedFunctionExecution { const initialWitness = toACVMWitness(1, this.args); const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, { + computeSelector: (...args) => { + const signature = oracleDebugCallToFormattedStr(args); + const returnValue = toACVMField(FunctionSelector.fromSignature(signature).toField()); + return Promise.resolve(returnValue); + }, getSecretKey: ([ownerX], [ownerY]) => this.context.getSecretKey(this.contractAddress, ownerX, ownerY), getPublicKey: async ([acvmAddress]) => { const address = frToAztecAddress(fromACVMField(acvmAddress)); diff --git a/yarn-project/acir-simulator/src/public/executor.ts b/yarn-project/acir-simulator/src/public/executor.ts index ee59f21719d..bdfd538e490 100644 --- a/yarn-project/acir-simulator/src/public/executor.ts +++ b/yarn-project/acir-simulator/src/public/executor.ts @@ -78,10 +78,13 @@ export class PublicExecutor { // We use this cache to hold the packed arguments. const packedArgs = await PackedArgsCache.create([]); const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, { + computeSelector: (...args) => { + const signature = oracleDebugCallToFormattedStr(args); + return Promise.resolve(toACVMField(FunctionSelector.fromSignature(signature).toField())); + }, packArguments: async args => { return toACVMField(await packedArgs.pack(args.map(fromACVMField))); }, - debugLog: (...args) => { this.log(oracleDebugCallToFormattedStr(args)); return Promise.resolve(ZERO_ACVM_FIELD); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 2eee79c81ee..41d789b8a91 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -1,6 +1,6 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; -import { AztecAddress, CheatCodes, Fr, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; +import { AztecAddress, CheatCodes, Fr, Wallet, computeMessageSecretHash, sleep } from '@aztec/aztec.js'; import { CircuitsWasm, CompleteAddress } from '@aztec/circuits.js'; import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; @@ -54,7 +54,7 @@ describe('e2e_lending_contract', () => { logger(`Tx sent with hash ${await tx.getTxHash()}`); const receipt = await tx.wait(); expect(receipt.status).toBe(TxStatus.MINED); - logger(`Debt asset deployed to ${receipt.contractAddress}`); + logger(`Stable coin asset deployed to ${receipt.contractAddress}`); stableCoin = await NativeTokenContract.at(receipt.contractAddress!, wallet); } @@ -88,6 +88,7 @@ describe('e2e_lending_contract', () => { stableCoin: NativeTokenContract, account: Account, ) => { + await sleep(5000); logger('Fetching storage snapshot 📸 '); const accountKey = await account.key(); @@ -293,6 +294,7 @@ describe('e2e_lending_contract', () => { const receipt3 = await tx3.wait(); expect(receipt3.status).toBe(TxStatus.MINED); + // At this point we should have some values!???? const tx4 = stableCoin.methods.redeemShield(shieldAmount, secret, recipient).send({ origin: recipient }); const receipt4 = await tx4.wait(); expect(receipt4.status).toBe(TxStatus.MINED); @@ -411,6 +413,7 @@ describe('e2e_lending_contract', () => { // - increase the private debt. logger('Borrow 🥸 : 🏦 -> 🍌'); + logger(`Addresses: ${stableCoin.address}, ${lendingContract.address}, ${collateralAsset.address}, ${recipient}`); const tx = lendingContract.methods .borrow_private(account.secret, account.address, borrowAmount) .send({ origin: recipient }); diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index bb932554a62..75d14872f7d 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -98,7 +98,10 @@ export class FunctionSelector { */ static fromNameAndParameters(name: string, parameters: ABIParameter[]) { const signature = new FunctionSignatureDecoder(name, parameters).decode(); - return FunctionSelector.fromSignature(signature); + const selector = FunctionSelector.fromSignature(signature); + // If you are debugging, can be useful to uncomment the following line. + // console.log(`Function selector for ${signature} is ${selector}`); + return selector; } /** diff --git a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr index 419bb4b14ef..879ccd537f8 100644 --- a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr @@ -5,7 +5,10 @@ contract Child { use crate::storage::Storage; use dep::aztec::{ abi::CallContext, - oracle::logs::emit_unencrypted_log, + oracle::{ + logs::emit_unencrypted_log, + compute_selector::compute_selector, + } }; use dep::std::option::Option; @@ -34,7 +37,7 @@ contract Child { input + context.chain_id() + context.version() } - // Returns base_value + 42. + // Returns base_value + chain_id + version + block_number + timestamp #[aztec(public)] fn pubGetValue(base_value: Field) -> Field { let returnValue = base_value + context.chain_id() + context.version() + context.block_number() + context.timestamp(); @@ -77,7 +80,7 @@ contract Child { #[aztec(public)] fn setValueTwiceWithNestedFirst() { - let pubSetValueSelector = 0x5b0f91b0; + let pubSetValueSelector = compute_selector("pubSetValue(Field)"); let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]); let storage = Storage::init(Option::none(), Option::some(&mut context)); @@ -91,7 +94,7 @@ contract Child { storage.current_value.write(20); let _hash = emit_unencrypted_log(20); - let pubSetValueSelector = 0x5b0f91b0; + let pubSetValueSelector = compute_selector("pubSetValue(Field)"); let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]); } } diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr index 8af2b6266d5..d6b457652a3 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr @@ -7,6 +7,7 @@ use dep::aztec::context::{ use crate::storage::Asset; use dep::aztec::constants_gen::RETURN_VALUES_LENGTH; +use dep::aztec::oracle::compute_selector::compute_selector; struct PriceFeed { address: Field, @@ -20,7 +21,7 @@ impl PriceFeed { fn get_price(self: Self, context: PublicContext) -> u120 { let return_values = context.call_public_function( self.address, - 3359284436, + compute_selector("get_price(Field)"), [0] ); @@ -40,15 +41,15 @@ impl Token { fn transfer_pub(self: Self, context: PublicContext, to: Field, amount: Field) { let _transfer_return_values = context.call_public_function( self.address, - 1012824788, + compute_selector("transfer_pub(Field,Field)"), [to, amount] ); } fn transfer_from_pub(self: Self, context: PublicContext, from: Field, to: Field, amount: Field) { let _transfer_return_values = context.call_public_function( - self.address, - 1602017294, + self.address, + compute_selector("transfer_from_pub(Field,Field,Field)"), [from, to, amount] ); } @@ -56,7 +57,7 @@ impl Token { fn owner_mint_pub(self: Self, context: PublicContext, to: Field, amount: Field) { let _transfer_return_values = context.call_public_function( self.address, - 1071038680, + compute_selector("owner_mint_pub(Field,Field)"), [to, amount] ); } @@ -65,7 +66,7 @@ impl Token { fn unshield(self: Self, context: &mut PrivateContext, from: Field, to: Field, amount: Field) -> [Field; RETURN_VALUES_LENGTH] { context.call_private_function( self.address, - 2423803924, + compute_selector("unshieldTokens(Field,Field,Field)"), [from, to, amount] ) } @@ -82,8 +83,8 @@ impl Lending { fn update_accumulator(self: Self, context: PublicContext) -> Asset { let return_values = context.call_public_function_no_args( - self.address, - 0x1873b536 + self.address, + compute_selector("update_accumulator()"), ); Asset { diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr index 3a36c320dc7..2f33b92a719 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr @@ -18,6 +18,7 @@ contract Lending { use crate::interest_math::compute_multiplier; use crate::helpers::{covered_by_collateral, DebtReturn, debt_updates, debt_value, compute_identifier}; use crate::interfaces::{Token, Lending, PriceFeed}; + use dep::aztec::oracle::compute_selector::compute_selector; struct Position { collateral: Field, @@ -59,7 +60,6 @@ contract Lending { } // Create a position. - // keccak256("update_accumulator()") >> 224 -> 0x1873b536 #[aztec(public)] fn update_accumulator() -> Asset { let storage = Storage::init(Option::none(), Option::some(&mut context)); @@ -98,7 +98,8 @@ contract Lending { let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender()); let _res = Token::at(collateral_asset).unshield(&mut context, asset_owner, context.this_address(), amount); // _deposit(on_behalf_of, amount, collateral_asset) - let _callStackItem2 = context.call_public_function(context.this_address(), 0x08506e50,[on_behalf_of, amount, collateral_asset]); + let selector = compute_selector("_deposit(Field,Field,Field)"); + let _callStackItem2 = context.call_public_function(context.this_address(), selector, [on_behalf_of, amount, collateral_asset]); } #[aztec(public)] @@ -108,13 +109,13 @@ contract Lending { collateral_asset: Field, ) -> Field { Token::at(collateral_asset).transfer_from_pub(context, context.msg_sender(), context.this_address(), amount); - let return_values = context.call_public_function(context.this_address(), 0x08506e50, [owner, amount, collateral_asset]); + let selector = compute_selector("_deposit(Field,Field,Field)"); + let return_values = context.call_public_function(context.this_address(), selector, [owner, amount, collateral_asset]); return_values[0] } #[aztec(public)] - // keccak256("_deposit(field,field,field)") >> 224 -> 0x08506e50 internal fn _deposit( owner: Field, amount: Field, @@ -140,7 +141,8 @@ contract Lending { amount: Field ) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender()); - let _callStackItem = context.call_public_function(context.this_address(), 0x5af6f634, [on_behalf_of, to, amount]); + let selector = compute_selector("_withdraw(Field,Field,Field)"); + let _callStackItem = context.call_public_function(context.this_address(), selector, [on_behalf_of, to, amount]); } #[aztec(public)] @@ -148,13 +150,12 @@ contract Lending { to: Field, amount: Field, ) -> Field { - // _withdraw(msg.sender, to, amount); - let return_values = context.call_public_function(context.this_address(), 0x5af6f634, [context.msg_sender(), to, amount]); + let selector = compute_selector("_withdraw(Field,Field,Field)"); + let return_values = context.call_public_function(context.this_address(), selector, [context.msg_sender(), to, amount]); return_values[0] } - // keccak256("_withdraw(field,field,field)") >> 224 -> 0x5af6f634 #[aztec(public)] internal fn _withdraw( owner: Field, @@ -195,8 +196,8 @@ contract Lending { amount: Field ) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender()); - // _borrow(msg.sender, to, amount) - let _callStackItem = context.call_public_function(context.this_address(), 0xceffa31a, [on_behalf_of, to, amount]); + let selector = compute_selector("_borrow(Field,Field,Field)"); + let _callStackItem = context.call_public_function(context.this_address(), selector, [on_behalf_of, to, amount]); } #[aztec(public)] @@ -204,13 +205,12 @@ contract Lending { to: Field, amount: Field ) -> Field { - // _borrow(msg.sender, to, amount) - let return_values = context.call_public_function(context.this_address(), 0xceffa31a, [context.msg_sender(), to, amount]); + let selector = compute_selector("_borrow(Field,Field,Field)"); + let return_values = context.call_public_function(context.this_address(), selector, [context.msg_sender(), to, amount]); return_values[0] } - // keccak256("_borrow(field,field,field)") >> 224 -> 0xceffa31a #[aztec(public)] internal fn _borrow( owner: Field, @@ -250,7 +250,8 @@ contract Lending { ) { let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender()); let _res = Token::at(stable_coin).unshield(&mut context, asset_owner, context.this_address(), amount); - let _callStackItem = context.call_public_function(context.this_address(), 0xfa94ab54, [on_behalf_of, amount, stable_coin]); + let selector = compute_selector("_repay(Field,Field,Field)"); + let _callStackItem = context.call_public_function(context.this_address(), selector, [on_behalf_of, amount, stable_coin]); } #[aztec(public)] @@ -261,12 +262,12 @@ contract Lending { ) -> Field { // Should probably just burn the tokens actually :thinking: Token::at(stable_coin).transfer_from_pub(context, context.msg_sender(), context.this_address(), amount); - let return_values = context.call_public_function(context.this_address(), 0xfa94ab54, [owner, amount, stable_coin]); + let selector = compute_selector("_repay(Field,Field,Field)"); + let return_values = context.call_public_function(context.this_address(), selector, [owner, amount, stable_coin]); return_values[0] } - // keccak256("_repay(field,field,field)") >> 224 -> 0xfa94ab54 #[aztec(public)] internal fn _repay( owner: Field, diff --git a/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr index 0155a592d3e..da46929f836 100644 --- a/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr @@ -33,6 +33,7 @@ contract NativeToken { }; use dep::aztec::public_call_stack_item::PublicCallStackItem; + use dep::aztec::oracle::compute_selector::compute_selector; #[aztec(private)] fn constructor( @@ -45,7 +46,6 @@ contract NativeToken { increment(balance, initial_supply, owner); } - // uint256(keccak256("owner_mint_pub(field,field)")) >> 224 -> 1071038680 #[aztec(public)] fn owner_mint_pub( to: Field, @@ -59,7 +59,6 @@ contract NativeToken { 1 } - // uint256(keccak256("owner_mint_priv(field,field)")) >> 224 -> 3157518188 #[aztec(public)] fn owner_mint_priv( amount: Field, @@ -79,7 +78,6 @@ contract NativeToken { // Mint Private Function // This mint function differs to the typical token mint function as it only allows minting // upon consuming valid messages from a token portal contract - // uint256(keccak256("mint(field,field,field,field,field)")) >> 224 -> 2341211258 #[aztec(private)] fn mint( amount: Field, @@ -103,7 +101,6 @@ contract NativeToken { // Withdraws using user's private balance. // @dev Destroys 2 of user's notes and sends a message to the L1 portal contract. That message can then be consumed // by calling the `withdraw` function on the L1 portal contract (assuming the args are set correctly). - // uint256(keccak256("withdraw(field,field,field,field)")) >> 224 -> 3193431016 #[aztec(private)] fn withdraw( amount: Field, @@ -123,7 +120,6 @@ contract NativeToken { // Mint Public Function // This mint function differs to the typical token mint function as it only allows minting // upon consuming valid messages from a token portal contract - // uint256(keccak256("mintPublic(field,field,field,field,field)")) >> 224 -> 1598652179 #[aztec(public)] fn mintPublic( amount: Field, @@ -151,7 +147,6 @@ contract NativeToken { } // Withdraws using user's public balance. - // uint256(keccak256("withdrawPublic(field,field,field)")) >> 224 -> 2996031894 #[aztec(public)] fn withdrawPublic( amount: Field, @@ -166,12 +161,7 @@ contract NativeToken { let current_sender_balance: Field = sender_balance.read(); - if (current_sender_balance as u120) > (amount as u120) { - // User has sufficient balance so we decrement it by `amount` - let _void1 = sender_balance.write(current_sender_balance - amount); - } - // TODO: Revert if there is not enough balance - + assert(current_sender_balance as u120 >= amount as u120); let content = get_withdraw_content_hash(amount, recipient, callerOnL1); // Emit the l2 to l1 message @@ -187,7 +177,6 @@ contract NativeToken { storage.public_allowances.at(context.msg_sender()).at(spender).write(allowance); } - // uint256(keccak256("transfer_pub(field,field)")) >> 224 -> 1012824788 #[aztec(public)] fn transfer_pub( to: Field, @@ -209,7 +198,6 @@ contract NativeToken { to_balance.write(current_to_balance + amount); } - // uint256(keccak256("transfer_from_pub(field,field,field)")) >> 224 -> 1602017294 #[aztec(public)] fn transfer_from_pub( from: Field, @@ -239,7 +227,6 @@ contract NativeToken { // Transfers `amount` of tokens from `sender`'s private balance to a `recipient`. // Note: Copied from PrivateToken - // uint256(keccak256("transfer(field,field,field)")) >> 224 -> 3704931096 #[aztec(private)] fn transfer( from: Field, @@ -257,7 +244,6 @@ contract NativeToken { } // Shield creates a way for a user to move tokens from the public context into the private context. - // uint256(keccak256("shield(field,field)")) >> 224 -> 845411215 #[aztec(public)] fn shield( amount: Field, @@ -286,7 +272,6 @@ contract NativeToken { // The shield function takes a public balance, and creates a commitment containing the amount of tokens // in the private context. - // uint256(keccak256("redeemShield(field,field,field)")) >> 224 -> 2260077221 #[aztec(private)] fn redeemShield( amount: Field, @@ -306,7 +291,6 @@ contract NativeToken { increment(balance, amount, owner); } - // uint256(keccak256("unshieldTokens(field,field,field)")) >> 224 -> 2423803924 #[aztec(private)] fn unshieldTokens( from: Field, @@ -322,10 +306,8 @@ contract NativeToken { // enqueue a public function to perform the public state update. let thisAddress = context.this_address(); - // addUnshieldedBalance selector (in decimal) - // recompute by: `cast keccak addUnshieldedBalance(field,field)` -> convert to decimal - let pubEntryPointSelector = 753269941; - let _callStackItem1 = context.call_public_function(thisAddress, pubEntryPointSelector, [amount, to]); + let addUnshieldedBalance = compute_selector("addUnshieldedBalance(Field,Field)"); + let _callStackItem1 = context.call_public_function(thisAddress, addUnshieldedBalance, [amount, to]); } #[aztec(public)] @@ -355,7 +337,7 @@ contract NativeToken { // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { let note_header = NoteHeader { contract_address, nonce, storage_slot }; - if (storage_slot == 2) { + if (storage_slot == 3) { note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage) } else { note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, preimage) diff --git a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr index f9878a152d4..53d7e84e8e4 100644 --- a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr @@ -43,6 +43,7 @@ contract NonNativeToken { }; use dep::aztec::public_call_stack_item::PublicCallStackItem; + use dep::aztec::oracle::compute_selector::compute_selector; #[aztec(private)] fn constructor( @@ -236,10 +237,8 @@ contract NonNativeToken { // enqueue a public function to perform the public state update. let thisAddress = context.this_address(); - // addUnshieldedBalance selector (in decimal) - // recompute by: `cast keccak addUnshieldedBalance(field,field)` -> convert to decimal - let pubEntryPointSelector = 753269941; - let _callStackItem1 = context.call_public_function(thisAddress, pubEntryPointSelector, [amount, recipient]); + let addUnshieldedBalance = compute_selector("addUnshieldedBalance(Field,Field)"); + let _callStackItem1 = context.call_public_function(thisAddress, addUnshieldedBalance, [amount, recipient]); } #[aztec(public)] diff --git a/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr index 99458ff1014..d1d0c377b4a 100644 --- a/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr @@ -1,5 +1,6 @@ // A contract used along with `Child` contract to test nested calls. contract Parent { + use dep::aztec::oracle::compute_selector::compute_selector; #[aztec(private)] fn constructor() {} @@ -60,7 +61,7 @@ contract Parent { targetContract: Field, targetSelector: Field, ) { - let enqueueCallToChildSelector = 0x94015a34; + let enqueueCallToChildSelector = compute_selector("enqueueCallToChild(Field,Field,Field)"); let _ret = context.call_private_function(context.this_address(), enqueueCallToChildSelector, [targetContract, targetSelector, 10]); context.call_public_function(targetContract, targetSelector, [20]); } @@ -74,7 +75,7 @@ contract Parent { targetSelector: Field, ) { context.call_public_function(targetContract, targetSelector, [20]); - let enqueueCallToChildSelector = 0x94015a34; + let enqueueCallToChildSelector = compute_selector("enqueueCallToChild(Field,Field,Field)"); let _ret = context.call_private_function(context.this_address(), enqueueCallToChildSelector, [targetContract, targetSelector, 10]); } @@ -98,7 +99,7 @@ contract Parent { targetSelector: Field, targetValue: Field, ) { - let pubEntryPointSelector = 3221316504; + let pubEntryPointSelector = compute_selector("pubEntryPoint(Field,Field,Field)"); let thisAddress = context.this_address(); let _void = context.call_public_function(thisAddress, pubEntryPointSelector, [targetContract, targetSelector, targetValue]); } @@ -110,7 +111,7 @@ contract Parent { targetSelector: Field, targetValue: Field, ) { - let pubEntryPointSelector = 3221316504; + let pubEntryPointSelector = compute_selector("pubEntryPoint(Field,Field,Field)"); let thisAddress = context.this_address(); context.call_public_function(thisAddress, pubEntryPointSelector, [targetContract, targetSelector, targetValue]); diff --git a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr index 975acddead8..6c8a95fb33a 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr @@ -36,7 +36,7 @@ impl PrivateTokenAirdropPrivateContextInterface { serialised_args[6] = recipients[2]; serialised_args[7] = spend_note_offset as Field; - context.call_private_function(self.address, 0x88bd156f, serialised_args) + context.call_private_function(self.address, 0xbf748730, serialised_args) } @@ -50,7 +50,7 @@ impl PrivateTokenAirdropPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = owner; - context.call_private_function(self.address, 0x7ecb218a, serialised_args) + context.call_private_function(self.address, 0xa4fa3a6f, serialised_args) } @@ -66,7 +66,7 @@ impl PrivateTokenAirdropPrivateContextInterface { serialised_args[1] = secret; serialised_args[2] = owner; - context.call_private_function(self.address, 0x9f7bacc8, serialised_args) + context.call_private_function(self.address, 0xd68b55c1, serialised_args) } @@ -82,7 +82,7 @@ impl PrivateTokenAirdropPrivateContextInterface { serialised_args[2] = secrets[0]; serialised_args[3] = secrets[1]; - context.call_private_function(self.address, 0xcaf1f505, serialised_args) + context.call_private_function(self.address, 0x720f5cc9, serialised_args) } @@ -96,7 +96,7 @@ impl PrivateTokenAirdropPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = owner; - context.call_private_function(self.address, 0x1dc9c3c0, serialised_args) + context.call_private_function(self.address, 0x1535439c, serialised_args) } @@ -110,7 +110,7 @@ impl PrivateTokenAirdropPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = recipient; - context.call_private_function(self.address, 0x61dd7032, serialised_args) + context.call_private_function(self.address, 0xc0888d22, serialised_args) } } diff --git a/yarn-project/noir-contracts/src/contracts/private_token_contract/src/interface.nr b/yarn-project/noir-contracts/src/contracts/private_token_contract/src/interface.nr index c308d2e8886..1eee266adcb 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_contract/src/interface.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_contract/src/interface.nr @@ -28,7 +28,7 @@ impl PrivateTokenPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = owner; - context.call_private_function(self.address, 0x1dc9c3c0, serialised_args) + context.call_private_function(self.address, 0x1535439c, serialised_args) } @@ -42,7 +42,7 @@ impl PrivateTokenPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = recipient; - context.call_private_function(self.address, 0x61dd7032, serialised_args) + context.call_private_function(self.address, 0xc0888d22, serialised_args) } } diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr index 7ccee2964e7..6d03ba23bd0 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr @@ -49,7 +49,7 @@ impl TestPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = secretHash; - context.call_public_function(self.address, 0x1c031d17, serialised_args) + context.call_public_function(self.address, 0xbac98727, serialised_args) } @@ -63,7 +63,7 @@ impl TestPrivateContextInterface { serialised_args[0] = amount; serialised_args[1] = secretHash; - context.call_public_function(self.address, 0x0217ef40, serialised_args) + context.call_public_function(self.address, 0x42040a24, serialised_args) } @@ -75,7 +75,7 @@ impl TestPrivateContextInterface { let mut serialised_args = [0; 1]; serialised_args[0] = aztec_address; - context.call_private_function(self.address, 0xe5df1726, serialised_args) + context.call_private_function(self.address, 0xaf15a45f, serialised_args) } @@ -87,7 +87,7 @@ impl TestPrivateContextInterface { let mut serialised_args = [0; 1]; serialised_args[0] = address; - context.call_private_function(self.address, 0x553aaad4, serialised_args) + context.call_private_function(self.address, 0x88f0753b, serialised_args) } @@ -119,7 +119,7 @@ impl TestPrivateContextInterface { let mut serialised_args = [0; 1]; serialised_args[0] = time; - context.call_public_function(self.address, 0x57587e4d, serialised_args) + context.call_public_function(self.address, 0xfff6026c, serialised_args) } @@ -152,7 +152,7 @@ impl TestPrivateContextInterface { serialised_args[15] = aDeepStruct.manyNotes[2].amount; serialised_args[16] = aDeepStruct.manyNotes[2].secretHash; - context.call_private_function(self.address, 0x7c97ca29, serialised_args) + context.call_private_function(self.address, 0x81d7c118, serialised_args) } } @@ -182,7 +182,7 @@ impl TestPublicContextInterface { serialised_args[0] = amount; serialised_args[1] = secretHash; - context.call_public_function(self.address, 0x1c031d17, serialised_args) + context.call_public_function(self.address, 0xbac98727, serialised_args) } @@ -196,7 +196,7 @@ impl TestPublicContextInterface { serialised_args[0] = amount; serialised_args[1] = secretHash; - context.call_public_function(self.address, 0x0217ef40, serialised_args) + context.call_public_function(self.address, 0x42040a24, serialised_args) } @@ -208,7 +208,7 @@ impl TestPublicContextInterface { let mut serialised_args = [0; 1]; serialised_args[0] = time; - context.call_public_function(self.address, 0x57587e4d, serialised_args) + context.call_public_function(self.address, 0xfff6026c, serialised_args) } } diff --git a/yarn-project/noir-libs/noir-aztec/src/oracle.nr b/yarn-project/noir-libs/noir-aztec/src/oracle.nr index 4133c00fc99..838821db45f 100644 --- a/yarn-project/noir-libs/noir-aztec/src/oracle.nr +++ b/yarn-project/noir-libs/noir-aztec/src/oracle.nr @@ -11,4 +11,5 @@ mod enqueue_public_function_call; mod public_call; mod notes; mod storage; -mod logs; \ No newline at end of file +mod logs; +mod compute_selector; \ No newline at end of file diff --git a/yarn-project/noir-libs/noir-aztec/src/oracle/compute_selector.nr b/yarn-project/noir-libs/noir-aztec/src/oracle/compute_selector.nr new file mode 100644 index 00000000000..89a130fecd6 --- /dev/null +++ b/yarn-project/noir-libs/noir-aztec/src/oracle/compute_selector.nr @@ -0,0 +1,6 @@ +#[oracle(computeSelector)] +fn compute_selector_oracle(_selector: T, _size: Field) -> Field {} + +unconstrained fn compute_selector(signature: T) -> Field { + compute_selector_oracle(signature, 0) +} \ No newline at end of file From e6eeb2b4511dc6b5e8a69e8296c88c77e6639822 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Tue, 5 Sep 2023 12:12:44 +0000 Subject: [PATCH 3/5] feat: brute force compute_note_hash_and_nullifier selector --- .../acir-simulator/src/client/simulator.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index b21033fc99c..00206d2900d 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -1,7 +1,7 @@ import { CallContext, CircuitsWasm, FunctionData, TxContext } from '@aztec/circuits.js'; import { computeTxHash } from '@aztec/circuits.js/abis'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; -import { ArrayType, FunctionType, encodeArguments } from '@aztec/foundation/abi'; +import { ArrayType, FunctionSelector, FunctionType, encodeArguments } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -177,12 +177,23 @@ export class AcirSimulator { storageSlot: Fr, notePreimage: Fr[], ) { - let abi: FunctionAbiWithDebugMetadata; - try { - abi = await this.db.getFunctionABI(contractAddress, computeNoteHashAndNullifierSelector); - } catch (e) { + let abi: FunctionAbiWithDebugMetadata | undefined = undefined; + + // Brute force + for (let i = 1; i < 5; i++) { + const signature = `compute_note_hash_and_nullifier(Field,Field,Field,[Field;${i}])`; + const selector = FunctionSelector.fromSignature(signature); + try { + abi = await this.db.getFunctionABI(contractAddress, selector); + break; + } catch (e) { + // ignore + } + } + + if (abi == undefined) { throw new Error( - `Mandatory implementation of "${computeNoteHashAndNullifierSignature}" missing in noir contract ${contractAddress.toString()}.`, + `Mandatory implementation of "compute_note_hash_and_nullifier" missing in noir contract ${contractAddress.toString()}.`, ); } From 0a4b2fd4c28a9aa73f04244b71cb415375cf367a Mon Sep 17 00:00:00 2001 From: LHerskind Date: Tue, 5 Sep 2023 14:03:48 +0000 Subject: [PATCH 4/5] chore: address comments + minor test issue with toEqual --- .../acir-simulator/src/client/function_selectors.ts | 5 ----- .../src/client/private_execution.test.ts | 10 +++++++--- yarn-project/acir-simulator/src/client/simulator.ts | 7 +++---- .../end-to-end/src/e2e_lending_contract.test.ts | 5 +---- yarn-project/foundation/src/abi/decoder.ts | 13 +++++++++++-- .../foundation/src/abi/function_selector.ts | 10 ++++++---- .../synchroniser/server_world_state_synchroniser.ts | 4 ++-- 7 files changed, 30 insertions(+), 24 deletions(-) delete mode 100644 yarn-project/acir-simulator/src/client/function_selectors.ts diff --git a/yarn-project/acir-simulator/src/client/function_selectors.ts b/yarn-project/acir-simulator/src/client/function_selectors.ts deleted file mode 100644 index 900969623cb..00000000000 --- a/yarn-project/acir-simulator/src/client/function_selectors.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { FunctionSelector } from '@aztec/circuits.js'; - -export const computeNoteHashAndNullifierSignature = 'compute_note_hash_and_nullifier(Field,Field,Field,[Field;3])'; - -export const computeNoteHashAndNullifierSelector = FunctionSelector.fromSignature(computeNoteHashAndNullifierSignature); 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 0a4202791b1..b00efb9dfea 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -621,7 +621,9 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ args, abi: parentAbi }); expect(result.callStackItem.publicInputs.returnValues[0]).toEqual(new Fr(privateIncrement)); - expect(oracle.getFunctionABI.mock.calls[0]).toEqual([childAddress, childSelector]); + expect(oracle.getFunctionABI.mock.calls[0].map(a => a.toBuffer())).toEqual( + [childAddress, childSelector].map(a => a.toBuffer()), + ); expect(oracle.getPortalContractAddress.mock.calls[0]).toEqual([childAddress]); expect(result.nestedExecutions).toHaveLength(1); expect(result.nestedExecutions[0].callStackItem.publicInputs.returnValues[0]).toEqual(new Fr(privateIncrement)); @@ -671,7 +673,9 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ args, abi: parentAbi }); expect(result.callStackItem.publicInputs.returnValues[0]).toEqual(argsHash); - expect(oracle.getFunctionABI.mock.calls[0]).toEqual([testAddress, testCodeGenSelector]); + expect(oracle.getFunctionABI.mock.calls[0].map(a => a.toBuffer())).toEqual( + [testAddress, testCodeGenSelector].map(a => a.toBuffer()), + ); expect(oracle.getPortalContractAddress.mock.calls[0]).toEqual([testAddress]); expect(result.nestedExecutions).toHaveLength(1); expect(result.nestedExecutions[0].callStackItem.publicInputs.returnValues[0]).toEqual(argsHash); @@ -815,7 +819,7 @@ describe('Private Execution test suite', () => { ); expect(result.enqueuedPublicFunctionCalls).toHaveLength(1); - expect(result.enqueuedPublicFunctionCalls[0]).toEqual(publicCallRequest); + expect(result.enqueuedPublicFunctionCalls[0].toBuffer()).toEqual(publicCallRequest.toBuffer()); expect(result.callStackItem.publicInputs.publicCallStack[0]).toEqual(publicCallRequestHash); }); }); diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 00206d2900d..5c4948b56e3 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -1,4 +1,4 @@ -import { CallContext, CircuitsWasm, FunctionData, TxContext } from '@aztec/circuits.js'; +import { CallContext, CircuitsWasm, FunctionData, MAX_NOTE_FIELDS_LENGTH, TxContext } from '@aztec/circuits.js'; import { computeTxHash } from '@aztec/circuits.js/abis'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { ArrayType, FunctionSelector, FunctionType, encodeArguments } from '@aztec/foundation/abi'; @@ -15,7 +15,6 @@ import { PackedArgsCache } from '../common/packed_args_cache.js'; import { ClientTxExecutionContext } from './client_execution_context.js'; import { DBOracle, FunctionAbiWithDebugMetadata } from './db_oracle.js'; import { ExecutionResult } from './execution_result.js'; -import { computeNoteHashAndNullifierSelector, computeNoteHashAndNullifierSignature } from './function_selectors.js'; import { PrivateFunctionExecution } from './private_execution.js'; import { UnconstrainedFunctionExecution } from './unconstrained_execution.js'; @@ -180,12 +179,12 @@ export class AcirSimulator { let abi: FunctionAbiWithDebugMetadata | undefined = undefined; // Brute force - for (let i = 1; i < 5; i++) { + for (let i = 0; i < MAX_NOTE_FIELDS_LENGTH; i++) { const signature = `compute_note_hash_and_nullifier(Field,Field,Field,[Field;${i}])`; const selector = FunctionSelector.fromSignature(signature); try { abi = await this.db.getFunctionABI(contractAddress, selector); - break; + if (abi !== undefined) break; } catch (e) { // ignore } diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 41d789b8a91..27a303e5d9f 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -1,6 +1,6 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; -import { AztecAddress, CheatCodes, Fr, Wallet, computeMessageSecretHash, sleep } from '@aztec/aztec.js'; +import { AztecAddress, CheatCodes, Fr, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; import { CircuitsWasm, CompleteAddress } from '@aztec/circuits.js'; import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; @@ -88,7 +88,6 @@ describe('e2e_lending_contract', () => { stableCoin: NativeTokenContract, account: Account, ) => { - await sleep(5000); logger('Fetching storage snapshot 📸 '); const accountKey = await account.key(); @@ -294,7 +293,6 @@ describe('e2e_lending_contract', () => { const receipt3 = await tx3.wait(); expect(receipt3.status).toBe(TxStatus.MINED); - // At this point we should have some values!???? const tx4 = stableCoin.methods.redeemShield(shieldAmount, secret, recipient).send({ origin: recipient }); const receipt4 = await tx4.wait(); expect(receipt4.status).toBe(TxStatus.MINED); @@ -413,7 +411,6 @@ describe('e2e_lending_contract', () => { // - increase the private debt. logger('Borrow 🥸 : 🏦 -> 🍌'); - logger(`Addresses: ${stableCoin.address}, ${lendingContract.address}, ${collateralAsset.address}, ${recipient}`); const tx = lendingContract.methods .borrow_private(account.secret, account.address, borrowAmount) .send({ origin: recipient }); diff --git a/yarn-project/foundation/src/abi/decoder.ts b/yarn-project/foundation/src/abi/decoder.ts index 4153be9f94c..5ca889f9d63 100644 --- a/yarn-project/foundation/src/abi/decoder.ts +++ b/yarn-project/foundation/src/abi/decoder.ts @@ -123,7 +123,16 @@ export class FunctionSignatureDecoder { * @returns The function signature. */ public decode(): string { - const hmm = this.parameters.map(param => this.decodeParameter(param.type)); - return `${this.name}(${hmm.join(',')})`; + return `${this.name}(${this.parameters.map(param => this.decodeParameter(param.type)).join(',')})`; } } + +/** + * Decodes a function signature from the name and parameters. + * @param name - The name of the function- + * @param parameters - The parameters of the function. + * @returns - The function signature. + */ +export function decodeFunctionSignature(name: string, parameters: ABIParameter[]) { + return new FunctionSignatureDecoder(name, parameters).decode(); +} diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index 75d14872f7d..da10c7d0d28 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -1,9 +1,11 @@ -import { ABIParameter, FunctionSignatureDecoder } from '@aztec/foundation/abi'; +import { ABIParameter, decodeFunctionSignature } from '@aztec/foundation/abi'; import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; import { keccak } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader } from '@aztec/foundation/serialize'; +import { createDebugLogger } from '../log/logger.js'; + /** * A function selector is the first 4 bytes of the hash of a function signature. */ @@ -12,6 +14,7 @@ export class FunctionSelector { * The size of the function selector in bytes. */ public static SIZE = 4; + protected logger = createDebugLogger('aztec:foundation:function-selector'); constructor(/** number representing the function selector */ public value: number) { if (value > 2 ** (FunctionSelector.SIZE * 8) - 1) { @@ -97,10 +100,9 @@ export class FunctionSelector { * @returns A Buffer containing the 4-byte function selector. */ static fromNameAndParameters(name: string, parameters: ABIParameter[]) { - const signature = new FunctionSignatureDecoder(name, parameters).decode(); + const signature = decodeFunctionSignature(name, parameters); const selector = FunctionSelector.fromSignature(signature); - // If you are debugging, can be useful to uncomment the following line. - // console.log(`Function selector for ${signature} is ${selector}`); + selector.logger(`Function selector for ${signature} is ${selector}`); return selector; } diff --git a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts index f96c432c05e..eb135466b0b 100644 --- a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts +++ b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts @@ -1,5 +1,5 @@ import { SerialQueue } from '@aztec/foundation/fifo'; -import { createDebugLogger } from '@aztec/foundation/log'; +import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { L2Block, L2BlockDownloader, L2BlockSource } from '@aztec/types'; import { MerkleTreeOperations, MerkleTrees } from '../index.js'; @@ -28,7 +28,7 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser { private merkleTreeDb: MerkleTrees, private l2BlockSource: L2BlockSource, config: WorldStateConfig, - private log = createDebugLogger('aztec:world_state'), + private log: DebugLogger = createDebugLogger('aztec:world_state'), ) { this.l2BlockDownloader = new L2BlockDownloader( l2BlockSource, From 92c0b181b635a84bfb58a1643085484078b2bcf2 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Tue, 5 Sep 2023 15:01:07 +0000 Subject: [PATCH 5/5] confusion: removing the debuglogger make jest works --- .../src/client/private_execution.test.ts | 10 +++------- yarn-project/foundation/src/abi/function_selector.ts | 6 ++---- .../synchroniser/server_world_state_synchroniser.ts | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) 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 b00efb9dfea..0a4202791b1 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -621,9 +621,7 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ args, abi: parentAbi }); expect(result.callStackItem.publicInputs.returnValues[0]).toEqual(new Fr(privateIncrement)); - expect(oracle.getFunctionABI.mock.calls[0].map(a => a.toBuffer())).toEqual( - [childAddress, childSelector].map(a => a.toBuffer()), - ); + expect(oracle.getFunctionABI.mock.calls[0]).toEqual([childAddress, childSelector]); expect(oracle.getPortalContractAddress.mock.calls[0]).toEqual([childAddress]); expect(result.nestedExecutions).toHaveLength(1); expect(result.nestedExecutions[0].callStackItem.publicInputs.returnValues[0]).toEqual(new Fr(privateIncrement)); @@ -673,9 +671,7 @@ describe('Private Execution test suite', () => { const result = await runSimulator({ args, abi: parentAbi }); expect(result.callStackItem.publicInputs.returnValues[0]).toEqual(argsHash); - expect(oracle.getFunctionABI.mock.calls[0].map(a => a.toBuffer())).toEqual( - [testAddress, testCodeGenSelector].map(a => a.toBuffer()), - ); + expect(oracle.getFunctionABI.mock.calls[0]).toEqual([testAddress, testCodeGenSelector]); expect(oracle.getPortalContractAddress.mock.calls[0]).toEqual([testAddress]); expect(result.nestedExecutions).toHaveLength(1); expect(result.nestedExecutions[0].callStackItem.publicInputs.returnValues[0]).toEqual(argsHash); @@ -819,7 +815,7 @@ describe('Private Execution test suite', () => { ); expect(result.enqueuedPublicFunctionCalls).toHaveLength(1); - expect(result.enqueuedPublicFunctionCalls[0].toBuffer()).toEqual(publicCallRequest.toBuffer()); + expect(result.enqueuedPublicFunctionCalls[0]).toEqual(publicCallRequest); expect(result.callStackItem.publicInputs.publicCallStack[0]).toEqual(publicCallRequestHash); }); }); diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index da10c7d0d28..236acfedd79 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -4,8 +4,6 @@ import { keccak } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader } from '@aztec/foundation/serialize'; -import { createDebugLogger } from '../log/logger.js'; - /** * A function selector is the first 4 bytes of the hash of a function signature. */ @@ -14,7 +12,6 @@ export class FunctionSelector { * The size of the function selector in bytes. */ public static SIZE = 4; - protected logger = createDebugLogger('aztec:foundation:function-selector'); constructor(/** number representing the function selector */ public value: number) { if (value > 2 ** (FunctionSelector.SIZE * 8) - 1) { @@ -102,7 +99,8 @@ export class FunctionSelector { static fromNameAndParameters(name: string, parameters: ABIParameter[]) { const signature = decodeFunctionSignature(name, parameters); const selector = FunctionSelector.fromSignature(signature); - selector.logger(`Function selector for ${signature} is ${selector}`); + // If using the debug logger here it kill the typing in the `server_world_state_synchroniser` and jest tests. + // console.log(`Function selector for ${signature} is ${selector}`); return selector; } diff --git a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts index eb135466b0b..f96c432c05e 100644 --- a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts +++ b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts @@ -1,5 +1,5 @@ import { SerialQueue } from '@aztec/foundation/fifo'; -import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; +import { createDebugLogger } from '@aztec/foundation/log'; import { L2Block, L2BlockDownloader, L2BlockSource } from '@aztec/types'; import { MerkleTreeOperations, MerkleTrees } from '../index.js'; @@ -28,7 +28,7 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser { private merkleTreeDb: MerkleTrees, private l2BlockSource: L2BlockSource, config: WorldStateConfig, - private log: DebugLogger = createDebugLogger('aztec:world_state'), + private log = createDebugLogger('aztec:world_state'), ) { this.l2BlockDownloader = new L2BlockDownloader( l2BlockSource,