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

feat: Recursive fn calls to spend more notes. #1779

Merged
merged 13 commits into from
Aug 25, 2023
31 changes: 19 additions & 12 deletions yarn-project/acir-simulator/src/client/private_execution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ describe('Private Execution test suite', () => {
abi,
args = [],
origin = AztecAddress.random(),
msgSender = AztecAddress.ZERO,
contractAddress = defaultContractAddress,
LeilaWang marked this conversation as resolved.
Show resolved Hide resolved
portalContractAddress = EthAddress.ZERO,
txContext = {},
}: {
abi: FunctionAbi;
origin?: AztecAddress;
msgSender?: AztecAddress;
contractAddress?: AztecAddress;
portalContractAddress?: EthAddress;
args?: any[];
Expand All @@ -113,6 +115,7 @@ describe('Private Execution test suite', () => {
abi,
functionData.isConstructor ? AztecAddress.ZERO : contractAddress,
portalContractAddress,
msgSender,
);
};

Expand Down Expand Up @@ -301,12 +304,13 @@ describe('Private Execution test suite', () => {
);
await insertLeaves(consumedNotes.map(n => n.siloedNoteHash));

const args = [amountToTransfer, owner, recipient];
const result = await runSimulator({ args, abi });
const args = [amountToTransfer, recipient];
const result = await runSimulator({ args, abi, msgSender: owner });

// The two notes were nullified
const newNullifiers = result.callStackItem.publicInputs.newNullifiers.filter(field => !field.equals(Fr.ZERO));
expect(newNullifiers).toEqual(consumedNotes.map(n => n.innerNullifier));
expect(newNullifiers).toHaveLength(consumedNotes.length);
expect(newNullifiers).toEqual(expect.arrayContaining(consumedNotes.map(n => n.innerNullifier)));

expect(result.preimages.newNotes).toHaveLength(2);
const [changeNote, recipientNote] = result.preimages.newNotes;
Expand All @@ -327,7 +331,8 @@ describe('Private Execution test suite', () => {
expect(changeNote.preimage[0]).toEqual(new Fr(40n));

const readRequests = result.callStackItem.publicInputs.readRequests.filter(field => !field.equals(Fr.ZERO));
expect(readRequests).toEqual(consumedNotes.map(n => n.uniqueSiloedNoteHash));
expect(readRequests).toHaveLength(consumedNotes.length);
expect(readRequests).toEqual(expect.arrayContaining(consumedNotes.map(n => n.uniqueSiloedNoteHash)));
});

it('should be able to transfer with dummy notes', async () => {
Expand All @@ -345,8 +350,8 @@ describe('Private Execution test suite', () => {
);
await insertLeaves(consumedNotes.map(n => n.siloedNoteHash));

const args = [amountToTransfer, owner, recipient];
const result = await runSimulator({ args, abi });
const args = [amountToTransfer, recipient];
const result = await runSimulator({ args, abi, msgSender: owner });

const newNullifiers = result.callStackItem.publicInputs.newNullifiers.filter(field => !field.equals(Fr.ZERO));
expect(newNullifiers).toEqual(consumedNotes.map(n => n.innerNullifier));
Expand Down Expand Up @@ -529,12 +534,13 @@ describe('Private Execution test suite', () => {
);
await insertLeaves(consumedNotes.map(n => n.siloedNoteHash));

const args = [amountToTransfer, owner, recipient];
const result = await runSimulator({ args, abi });
const args = [amountToTransfer, recipient];
const result = await runSimulator({ args, abi, msgSender: owner });

// The two notes were nullified
const newNullifiers = result.callStackItem.publicInputs.newNullifiers.filter(field => !field.equals(Fr.ZERO));
expect(newNullifiers).toEqual(consumedNotes.map(n => n.innerNullifier));
expect(newNullifiers).toHaveLength(consumedNotes.length);
expect(newNullifiers).toEqual(expect.arrayContaining(consumedNotes.map(n => n.innerNullifier)));

expect(result.preimages.newNotes).toHaveLength(2);
const [changeNote, recipientNote] = result.preimages.newNotes;
Expand All @@ -555,7 +561,8 @@ describe('Private Execution test suite', () => {
expect(changeNote.preimage[0]).toEqual(new Fr(40n));

const readRequests = result.callStackItem.publicInputs.readRequests.filter(field => !field.equals(Fr.ZERO));
expect(readRequests).toEqual(consumedNotes.map(n => n.uniqueSiloedNoteHash));
expect(readRequests).toHaveLength(consumedNotes.length);
expect(readRequests).toEqual(expect.arrayContaining(consumedNotes.map(n => n.uniqueSiloedNoteHash)));
});

it('should be able to transfer with dummy notes', async () => {
Expand All @@ -573,8 +580,8 @@ describe('Private Execution test suite', () => {
);
await insertLeaves(consumedNotes.map(n => n.siloedNoteHash));

const args = [amountToTransfer, owner, recipient];
const result = await runSimulator({ args, abi });
const args = [amountToTransfer, recipient];
const result = await runSimulator({ args, abi, msgSender: owner });

const newNullifiers = result.callStackItem.publicInputs.newNullifiers.filter(field => !field.equals(Fr.ZERO));
expect(newNullifiers).toEqual(consumedNotes.map(n => n.innerNullifier));
Expand Down
7 changes: 3 additions & 4 deletions yarn-project/acir-simulator/src/client/simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,15 @@ export class AcirSimulator {
* @param entryPointABI - The ABI of the entry point function.
* @param contractAddress - The address of the contract (should match request.origin)
* @param portalContractAddress - The address of the portal contract.
* @param historicBlockData - Data required to reconstruct the block hash, this also contains the historic tree roots.
* @param curve - The curve instance for elliptic curve operations.
* @param packedArguments - The entrypoint packed arguments
* @param msgSender - The address calling the function. This can be replaced to simulate a call from another contract or a specific account.
* @returns The result of the execution.
*/
public async run(
request: TxExecutionRequest,
entryPointABI: FunctionAbiWithDebugMetadata,
contractAddress: AztecAddress,
portalContractAddress: EthAddress,
msgSender = AztecAddress.ZERO,
): Promise<ExecutionResult> {
if (entryPointABI.functionType !== FunctionType.SECRET) {
throw new Error(`Cannot run ${entryPointABI.functionType} function as secret`);
Expand All @@ -76,7 +75,7 @@ export class AcirSimulator {

const historicBlockData = await this.db.getHistoricBlockData();
const callContext = new CallContext(
AztecAddress.ZERO,
msgSender,
contractAddress,
portalContractAddress,
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ async function main() {

// Perform a transfer
logger(`Transferring ${SECONDARY_AMOUNT} tokens from owner to another account.`);
const transferTx = zkContract.methods
.transfer(SECONDARY_AMOUNT, owner.address, account2.address)
.send({ origin: owner.address });
const transferTx = zkContract.methods.transfer(SECONDARY_AMOUNT, account2.address).send({ origin: owner.address });
await transferTx.isMined({ interval: 0.5 });
const balanceAfterTransfer = await getBalance(zkContract, owner.address);
const receiverBalance = await getBalance(zkContract, account2.address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,7 @@ const transferWethOnL2 = async (
receiver: AztecAddress,
transferAmount: bigint,
) => {
const transferTx = wethL2Contract.methods
.transfer(transferAmount, ownerAddress, receiver)
.send({ origin: ownerAddress });
const transferTx = wethL2Contract.methods.transfer(transferAmount, receiver).send({ origin: ownerAddress });
await transferTx.isMined({ interval: 0.5 });
const transferReceipt = await transferTx.getReceipt();
// expect(transferReceipt.status).toBe(TxStatus.MINED);
Expand Down
Loading