Skip to content

Commit

Permalink
chore: Update Noir contracts interfaces to use addresses instead of p…
Browse files Browse the repository at this point in the history
…ubkeys (#1083)

* Update zk token contract interface to use addresses instead of pubkeys

* Update NonNativeToken

* Update pending commitments

* Fix imports sort order

* Update public token

* Update uniswap

* Fix import whitespace

* Fix deployment of non native token contract

* Fix public execution test

* Fix private execution test

* Fixes to uniswap sandbox example
  • Loading branch information
spalladino authored Jul 19, 2023
1 parent bd52b83 commit 1df89fb
Show file tree
Hide file tree
Showing 35 changed files with 369 additions and 721 deletions.
98 changes: 62 additions & 36 deletions yarn-project/acir-simulator/src/client/private_execution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
computeUniqueCommitment,
siloCommitment,
} from '@aztec/circuits.js/abis';
import { Grumpkin, pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg';
import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg';
import { makeAddressWithPreimagesFromPrivateKey } from '@aztec/circuits.js/factories';
import { FunctionAbi, encodeArguments, generateFunctionSelector } from '@aztec/foundation/abi';
import { asyncMap } from '@aztec/foundation/async-map';
import { AztecAddress } from '@aztec/foundation/aztec-address';
Expand All @@ -43,7 +44,7 @@ import { default as levelup } from 'levelup';
import { type MemDown, default as memdown } from 'memdown';

import { buildL1ToL2Message } from '../test/utils.js';
import { NoirPoint, computeSlotForMapping, toPublicKey } from '../utils.js';
import { computeSlotForMapping } from '../utils.js';
import { DBOracle } from './db_oracle.js';
import { AcirSimulator } from './simulator.js';

Expand All @@ -66,6 +67,7 @@ describe('Private Execution test suite', () => {
privateData: PRIVATE_DATA_TREE_HEIGHT,
l1ToL2Messages: L1_TO_L2_MSG_TREE_HEIGHT,
};

const trees: { [name: keyof typeof treeHeights]: AppendOnlyTree } = {};
const txContext = new TxContext(false, false, false, ContractDeploymentData.empty(), new Fr(69), new Fr(420));

Expand Down Expand Up @@ -150,23 +152,38 @@ describe('Private Execution test suite', () => {
describe('zk token contract', () => {
const contractAddress = defaultContractAddress;
const recipientPk = Buffer.from('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec', 'hex');
let owner: NoirPoint;
let recipient: NoirPoint;
let owner: AztecAddress;
let recipient: AztecAddress;
let currentNoteIndex = 0n;

const buildNote = (amount: bigint, owner: NoirPoint) => {
const buildNote = (amount: bigint, noteOwner: AztecAddress) => {
const nonce = new Fr(currentNoteIndex);
const preimage = [new Fr(amount), new Fr(owner.x), new Fr(owner.y), Fr.random(), new Fr(1n)];
const preimage = [new Fr(amount), noteOwner.toField(), Fr.random(), new Fr(1n)];
return { index: currentNoteIndex++, nonce, preimage };
};

beforeAll(() => {
const grumpkin = new Grumpkin(circuitsWasm);
owner = toPublicKey(ownerPk, grumpkin);
recipient = toPublicKey(recipientPk, grumpkin);
});
beforeEach(async () => {
const {
address: ownerAddress,
partialAddress: ownerPartialAddress,
publicKey: ownerPubKey,
} = await makeAddressWithPreimagesFromPrivateKey(ownerPk);

const {
address: recipientAddress,
partialAddress: recipientPartialAddress,
publicKey: recipientPubKey,
} = await makeAddressWithPreimagesFromPrivateKey(recipientPk);

owner = ownerAddress;
recipient = recipientAddress;

oracle.getPublicKey.mockImplementation((address: AztecAddress) => {
if (address.equals(owner)) return Promise.resolve([ownerPubKey, ownerPartialAddress]);
if (address.equals(recipient)) return Promise.resolve([recipientPubKey, recipientPartialAddress]);
throw new Error(`Unknown address ${address}`);
});

beforeEach(() => {
oracle.getFunctionABI.mockImplementation((_, selector) =>
Promise.resolve(
ZkTokenContractAbi.functions.find(f => selector.equals(generateFunctionSelector(f.name, f.parameters)))!,
Expand Down Expand Up @@ -212,7 +229,7 @@ describe('Private Execution test suite', () => {

expect(result.preimages.newNotes).toHaveLength(1);
const newNote = result.preimages.newNotes[0];
expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner, circuitsWasm));
expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm));

const newCommitments = result.callStackItem.publicInputs.newCommitments.filter(field => !field.equals(Fr.ZERO));
expect(newCommitments).toHaveLength(1);
Expand All @@ -230,7 +247,7 @@ describe('Private Execution test suite', () => {

expect(result.preimages.newNotes).toHaveLength(1);
const newNote = result.preimages.newNotes[0];
expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner, circuitsWasm));
expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm));

const newCommitments = result.callStackItem.publicInputs.newCommitments.filter(field => !field.equals(Fr.ZERO));
expect(newCommitments).toHaveLength(1);
Expand All @@ -245,7 +262,7 @@ describe('Private Execution test suite', () => {
const amountToTransfer = 100n;
const abi = ZkTokenContractAbi.functions.find(f => f.name === 'transfer')!;

const storageSlot = computeSlotForMapping(new Fr(1n), owner, circuitsWasm);
const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm);

const notes = [buildNote(60n, owner), buildNote(80n, owner)];
oracle.getNotes.mockResolvedValue(notes);
Expand All @@ -264,13 +281,13 @@ describe('Private Execution test suite', () => {

expect(result.preimages.newNotes).toHaveLength(2);
const [changeNote, recipientNote] = result.preimages.newNotes;
expect(recipientNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), recipient, circuitsWasm));
expect(recipientNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), recipient.toField(), circuitsWasm));

const newCommitments = result.callStackItem.publicInputs.newCommitments.filter(field => !field.equals(Fr.ZERO));
expect(newCommitments).toHaveLength(2);

const [changeNoteCommitment, recipientNoteCommitment] = newCommitments;
const recipientStorageSlot = computeSlotForMapping(new Fr(1n), recipient, circuitsWasm);
const recipientStorageSlot = computeSlotForMapping(new Fr(1n), recipient.toField(), circuitsWasm);
expect(recipientNoteCommitment).toEqual(
await acirSimulator.computeInnerNoteHash(contractAddress, recipientStorageSlot, recipientNote.preimage),
);
Expand All @@ -290,7 +307,7 @@ describe('Private Execution test suite', () => {
const balance = 160n;
const abi = ZkTokenContractAbi.functions.find(f => f.name === 'transfer')!;

const storageSlot = computeSlotForMapping(new Fr(1n), owner, circuitsWasm);
const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm);

const notes = [buildNote(balance, owner)];
oracle.getNotes.mockResolvedValue(notes);
Expand Down Expand Up @@ -382,14 +399,19 @@ describe('Private Execution test suite', () => {
});
});

describe('Consuming Messages', () => {
describe('consuming Messages', () => {
const contractAddress = defaultContractAddress;
const recipientPk = Buffer.from('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec', 'hex');
let recipient: NoirPoint;

beforeAll(() => {
const grumpkin = new Grumpkin(circuitsWasm);
recipient = toPublicKey(recipientPk, grumpkin);
let recipient: AztecAddress;

beforeEach(async () => {
const { address, partialAddress, publicKey } = await makeAddressWithPreimagesFromPrivateKey(recipientPk);
recipient = address;
oracle.getPublicKey.mockImplementation((address: AztecAddress) => {
if (address.equals(recipient)) return Promise.resolve([publicKey, partialAddress]);
throw new Error(`Unknown address ${address}`);
});
});

it('Should be able to consume a dummy cross chain message', async () => {
Expand All @@ -401,7 +423,7 @@ describe('Private Execution test suite', () => {
// Function selector: 0xeeb73071 keccak256('mint(uint256,bytes32,address)')
const preimage = await buildL1ToL2Message(
'eeb73071',
[new Fr(bridgedAmount), new Fr(recipient.x), canceller.toField()],
[new Fr(bridgedAmount), recipient.toField(), canceller.toField()],
contractAddress,
secret,
);
Expand All @@ -418,7 +440,7 @@ describe('Private Execution test suite', () => {
});
});

const args = [bridgedAmount, recipient, recipient.x, messageKey, secret, canceller.toField()];
const args = [bridgedAmount, recipient, messageKey, secret, canceller.toField()];
const result = await runSimulator({ origin: contractAddress, contractAddress, abi, args });

// Check a nullifier has been created
Expand Down Expand Up @@ -502,11 +524,15 @@ describe('Private Execution test suite', () => {
});

describe('pending commitments contract', () => {
let owner: NoirPoint;

beforeAll(() => {
const grumpkin = new Grumpkin(circuitsWasm);
owner = toPublicKey(ownerPk, grumpkin);
let owner: AztecAddress;

beforeEach(async () => {
const { address, partialAddress, publicKey } = await makeAddressWithPreimagesFromPrivateKey(ownerPk);
owner = address;
oracle.getPublicKey.mockImplementation((address: AztecAddress) => {
if (address.equals(owner)) return Promise.resolve([publicKey, partialAddress]);
throw new Error(`Unknown address ${address}`);
});
});

beforeEach(() => {
Expand Down Expand Up @@ -537,7 +563,7 @@ describe('Private Execution test suite', () => {

expect(result.preimages.newNotes).toHaveLength(1);
const note = result.preimages.newNotes[0];
expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner, circuitsWasm));
expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm));

expect(note.preimage[0]).toEqual(new Fr(amountToTransfer));

Expand All @@ -546,7 +572,7 @@ describe('Private Execution test suite', () => {
expect(newCommitments).toHaveLength(1);

const commitment = newCommitments[0];
const storageSlot = computeSlotForMapping(new Fr(1n), owner, circuitsWasm);
const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm);
expect(commitment).toEqual(await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, note.preimage));
// read request should match commitment
const nonce = computeCommitmentNonce(circuitsWasm, txNullifier, 0);
Expand Down Expand Up @@ -587,7 +613,7 @@ describe('Private Execution test suite', () => {

expect(execCreate.preimages.newNotes).toHaveLength(1);
const note = execCreate.preimages.newNotes[0];
expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner, circuitsWasm));
expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm));

expect(note.preimage[0]).toEqual(new Fr(amountToTransfer));

Expand All @@ -598,7 +624,7 @@ describe('Private Execution test suite', () => {
expect(newCommitments).toHaveLength(1);

const commitment = newCommitments[0];
const storageSlot = computeSlotForMapping(new Fr(1n), owner, circuitsWasm);
const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm);
expect(commitment).toEqual(await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, note.preimage));
// read request should match commitment
const nonce = computeCommitmentNonce(circuitsWasm, txNullifier, 0);
Expand Down Expand Up @@ -629,7 +655,7 @@ describe('Private Execution test suite', () => {

expect(result.preimages.newNotes).toHaveLength(1);
const note = result.preimages.newNotes[0];
expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner, circuitsWasm));
expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm));

expect(note.preimage[0]).toEqual(new Fr(amountToTransfer));

Expand All @@ -638,7 +664,7 @@ describe('Private Execution test suite', () => {
expect(newCommitments).toHaveLength(1);

const commitment = newCommitments[0];
const storageSlot = computeSlotForMapping(new Fr(1n), owner, circuitsWasm);
const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm);
expect(commitment).toEqual(await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, note.preimage));
// read requests should be empty
const readRequest = result.callStackItem.publicInputs.readRequests[0].value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { CircuitsWasm, FunctionData, PrivateHistoricTreeRoots } from '@aztec/circuits.js';
import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { 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';
import { Fr, Point } from '@aztec/foundation/fields';
import { ZkTokenContractAbi } from '@aztec/noir-contracts/examples';
import { ExecutionRequest } from '@aztec/types';

import { mock } from 'jest-mock-extended';

import { NoirPoint, toPublicKey } from '../utils.js';
import { DBOracle } from './db_oracle.js';
import { AcirSimulator } from './simulator.js';

Expand All @@ -28,18 +28,30 @@ describe('Unconstrained Execution test suite', () => {
});

describe('zk token contract', () => {
let ownerPk: Buffer;
let owner: NoirPoint;
const ownerPk: Buffer = Buffer.from('5e30a2f886b4b6a11aea03bf4910fbd5b24e61aa27ea4d05c393b3ab592a8d33', 'hex');

const buildNote = (amount: bigint, owner: NoirPoint) => {
return [new Fr(amount), new Fr(owner.x), new Fr(owner.y), Fr.random(), new Fr(1n)];
};
let owner: AztecAddress;

beforeAll(() => {
ownerPk = Buffer.from('5e30a2f886b4b6a11aea03bf4910fbd5b24e61aa27ea4d05c393b3ab592a8d33', 'hex');
const buildNote = (amount: bigint, owner: AztecAddress) => {
return [new Fr(amount), owner, Fr.random(), new Fr(1n)];
};

const calculateAddress = (privateKey: Buffer) => {
const grumpkin = new Grumpkin(bbWasm);
owner = toPublicKey(ownerPk, grumpkin);
const pubKey = Point.fromBuffer(grumpkin.mul(Grumpkin.generator, privateKey));
const partialAddress = Fr.random();
const address = computeContractAddressFromPartial(bbWasm, pubKey, partialAddress);
return [address, partialAddress, pubKey] as const;
};

beforeEach(() => {
const [ownerAddress, ownerPartialAddress, ownerPubKey] = calculateAddress(ownerPk);
owner = ownerAddress;

oracle.getPublicKey.mockImplementation((address: AztecAddress) => {
if (address.equals(owner)) return Promise.resolve([ownerPubKey, ownerPartialAddress]);
throw new Error(`Unknown address ${address}`);
});
});

it('should run the getBalance function', async () => {
Expand Down
26 changes: 10 additions & 16 deletions yarn-project/acir-simulator/src/public/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
L1_TO_L2_MSG_TREE_HEIGHT,
PrivateHistoricTreeRoots,
} from '@aztec/circuits.js';
import { Grumpkin, pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg';
import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg';
import { FunctionAbi, encodeArguments } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { keccak } from '@aztec/foundation/crypto';
Expand All @@ -25,7 +25,7 @@ import { MockProxy, mock } from 'jest-mock-extended';
import { type MemDown, default as memdown } from 'memdown';

import { buildL1ToL2Message } from '../test/utils.js';
import { NoirPoint, computeSlotForMapping, toPublicKey } from '../utils.js';
import { computeSlotForMapping } from '../utils.js';
import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js';
import { PublicExecution } from './execution.js';
import { PublicExecutor } from './executor.js';
Expand Down Expand Up @@ -53,14 +53,10 @@ describe('ACIR public execution simulator', () => {
});

describe('PublicToken contract', () => {
let recipientPk: Buffer;
let recipient: NoirPoint;
let recipient: AztecAddress;

beforeAll(() => {
recipientPk = Buffer.from('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec', 'hex');

const grumpkin = new Grumpkin(circuitsWasm);
recipient = toPublicKey(recipientPk, grumpkin);
beforeEach(() => {
recipient = AztecAddress.random();
});

describe('mint', () => {
Expand Down Expand Up @@ -91,7 +87,7 @@ describe('ACIR public execution simulator', () => {
const expectedBalance = new Fr(160n);
expect(result.returnValues).toEqual([expectedBalance]);

const storageSlot = computeSlotForMapping(new Fr(1n), recipient, circuitsWasm);
const storageSlot = computeSlotForMapping(new Fr(1n), recipient.toField(), circuitsWasm);
expect(result.contractStorageUpdateRequests).toEqual([
{ storageSlot, oldValue: previousBalance, newValue: expectedBalance },
]);
Expand Down Expand Up @@ -127,7 +123,7 @@ describe('ACIR public execution simulator', () => {
isStaticCall: false,
});

recipientStorageSlot = computeSlotForMapping(new Fr(1n), recipient, circuitsWasm);
recipientStorageSlot = computeSlotForMapping(new Fr(1n), recipient.toField(), circuitsWasm);
senderStorageSlot = computeSlotForMapping(new Fr(1n), Fr.fromBuffer(sender.toBuffer()), circuitsWasm);

publicContracts.getBytecode.mockResolvedValue(Buffer.from(abi.bytecode, 'base64'));
Expand Down Expand Up @@ -326,14 +322,12 @@ describe('ACIR public execution simulator', () => {

const bridgedAmount = 20n;
const secret = new Fr(1n);
const recipientPk = Buffer.from('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec', 'hex');
const grumpkin = new Grumpkin(circuitsWasm);
const recipient = toPublicKey(recipientPk, grumpkin);
const recipient = AztecAddress.random();

// Function selector: 0xeeb73071 keccak256('mint(uint256,bytes32,address)')
const preimage = await buildL1ToL2Message(
'eeb73071',
[new Fr(bridgedAmount), new Fr(recipient.x), canceller.toField()],
[new Fr(bridgedAmount), recipient.toField(), canceller.toField()],
contractAddress,
secret,
);
Expand All @@ -342,7 +336,7 @@ describe('ACIR public execution simulator', () => {
const messageKey = Fr.random();
const args = encodeArguments(mintPublicAbi, [
bridgedAmount,
recipient.x,
recipient.toField(),
messageKey,
secret,
canceller.toField(),
Expand Down
Loading

0 comments on commit 1df89fb

Please sign in to comment.