Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(contracts): Update Noir contracts interfaces to use addresses instead of pubkeys #1083

Merged
merged 15 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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