Skip to content

Commit ed80a05

Browse files
committed
refactor: speed up transfer test
1 parent ea8e0ee commit ed80a05

File tree

3 files changed

+119
-56
lines changed

3 files changed

+119
-56
lines changed

yarn-project/end-to-end/scripts/create_k8s_dashboard.sh

100644100755
File mode changed.

yarn-project/end-to-end/src/fixtures/snapshot_manager.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ async function setupFromState(statePath: string, logger: Logger): Promise<Subsys
467467
* The 'restore' function is not provided, as it must be a closure within the test context to capture the results.
468468
*/
469469
export const addAccounts =
470-
(numberOfAccounts: number, logger: DebugLogger) =>
470+
(numberOfAccounts: number, logger: DebugLogger, waitUntilProven = true) =>
471471
async ({ pxe }: { pxe: PXE }) => {
472472
// Generate account keys.
473473
const accountKeys: [Fr, GrumpkinScalar][] = Array.from({ length: numberOfAccounts }).map(_ => [
@@ -494,7 +494,7 @@ export const addAccounts =
494494

495495
logger.verbose('Deploying accounts...');
496496
const txs = await Promise.all(accountManagers.map(account => account.deploy()));
497-
await Promise.all(txs.map(tx => tx.wait({ interval: 0.1, proven: true })));
497+
await Promise.all(txs.map(tx => tx.wait({ interval: 0.1, proven: waitUntilProven })));
498498

499499
return { accountKeys };
500500
};
@@ -505,12 +505,16 @@ export const addAccounts =
505505
* @param sender - Wallet to send the deployment tx.
506506
* @param accountsToDeploy - Which accounts to publicly deploy.
507507
*/
508-
export async function publicDeployAccounts(sender: Wallet, accountsToDeploy: (CompleteAddress | AztecAddress)[]) {
508+
export async function publicDeployAccounts(
509+
sender: Wallet,
510+
accountsToDeploy: (CompleteAddress | AztecAddress)[],
511+
waitUntilProven = true,
512+
) {
509513
const accountAddressesToDeploy = accountsToDeploy.map(a => ('address' in a ? a.address : a));
510514
const instances = await Promise.all(accountAddressesToDeploy.map(account => sender.getContractInstance(account)));
511515
const batch = new BatchCall(sender, [
512516
(await registerContractClass(sender, SchnorrAccountContractArtifact)).request(),
513517
...instances.map(instance => deployInstance(sender, instance!).request()),
514518
]);
515-
await batch.send().wait({ proven: true });
519+
await batch.send().wait({ proven: waitUntilProven });
516520
}

yarn-project/end-to-end/src/spartan/transfer.test.ts

+111-52
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
type AccountWallet,
44
type AccountWalletWithSecretKey,
55
type AztecAddress,
6-
type CompleteAddress,
6+
BatchCall,
77
ExtendedNote,
88
Fr,
99
Note,
@@ -17,7 +17,7 @@ import { TokenContract } from '@aztec/noir-contracts.js';
1717

1818
import { jest } from '@jest/globals';
1919

20-
import { addAccounts, publicDeployAccounts } from '../fixtures/snapshot_manager.js';
20+
import { addAccounts } from '../fixtures/snapshot_manager.js';
2121

2222
const { PXE_URL } = process.env;
2323
if (!PXE_URL) {
@@ -65,24 +65,47 @@ describe('token transfer test', () => {
6565
const TOKEN_SYMBOL = 'USD';
6666
const TOKEN_DECIMALS = 18n;
6767
const MINT_AMOUNT = 20n;
68+
69+
const ROUNDS = 5n;
70+
6871
let pxe: PXE;
6972
let wallets: AccountWalletWithSecretKey[];
70-
let completeAddresses: CompleteAddress[];
73+
let recipientWallet: AccountWalletWithSecretKey;
7174
let tokenAddress: AztecAddress;
7275
let tokenAtWallet0: TokenContract;
76+
7377
beforeAll(async () => {
78+
expect(ROUNDS).toBeLessThanOrEqual(MINT_AMOUNT);
79+
80+
// My guess is that is never proven so if we are waiting for it to prove we wait forever?
7481
pxe = await createCompatibleClient(PXE_URL, logger);
75-
const { accountKeys } = await addAccounts(3, logger)({ pxe });
82+
{
83+
const { accountKeys } = await addAccounts(1, logger, false)({ pxe });
84+
const accountManagers = accountKeys.map(ak => getSchnorrAccount(pxe, ak[0], ak[1], 1));
85+
86+
const partialAddress = accountManagers[0].getCompleteAddress().partialAddress;
87+
await pxe.registerAccount(accountKeys[0][0], partialAddress);
88+
recipientWallet = await accountManagers[0].getWallet();
89+
logger.verbose(`Recipient Wallet address: ${recipientWallet.getAddress()} registered`);
90+
}
91+
92+
const { accountKeys } = await addAccounts(3, logger, false)({ pxe });
7693
const accountManagers = accountKeys.map(ak => getSchnorrAccount(pxe, ak[0], ak[1], 1));
77-
wallets = await Promise.all(accountManagers.map(a => a.getWallet()));
78-
completeAddresses = await pxe.getRegisteredAccounts();
79-
wallets.forEach((w, i) => logger.verbose(`Wallet ${i} address: ${w.getAddress()}`));
80-
await publicDeployAccounts(wallets[0], completeAddresses.slice(0, 2));
94+
95+
wallets = await Promise.all(
96+
accountManagers.map(async (a, i) => {
97+
const partialAddress = a.getCompleteAddress().partialAddress;
98+
await pxe.registerAccount(accountKeys[i][0], partialAddress);
99+
const wallet = await a.getWallet();
100+
logger.verbose(`Wallet ${i} address: ${wallet.getAddress()} registered`);
101+
return wallet;
102+
}),
103+
);
81104

82105
logger.verbose(`Deploying TokenContract...`);
83106
const tokenContract = await TokenContract.deploy(
84107
wallets[0],
85-
completeAddresses[0],
108+
wallets[0].getAddress(),
86109
TOKEN_NAME,
87110
TOKEN_SYMBOL,
88111
TOKEN_DECIMALS,
@@ -93,24 +116,43 @@ describe('token transfer test', () => {
93116
tokenAddress = tokenContract.address;
94117
tokenAtWallet0 = await TokenContract.at(tokenAddress, wallets[0]);
95118

96-
logger.verbose(`Minting ${MINT_AMOUNT} publicly...`);
97-
await tokenAtWallet0.methods.mint_public(completeAddresses[0].address, MINT_AMOUNT).send().wait();
98-
99-
logger.verbose(`Minting ${MINT_AMOUNT} privately...`);
100-
const secret = Fr.random();
101-
const secretHash = computeSecretHash(secret);
102-
const receipt = await tokenAtWallet0.methods.mint_private(MINT_AMOUNT, secretHash).send().wait();
103-
104-
await addPendingShieldNoteToPXE({
105-
amount: MINT_AMOUNT,
106-
secretHash,
107-
txHash: receipt.txHash,
108-
accountAddress: completeAddresses[0].address,
109-
assetAddress: tokenAddress,
110-
wallet: wallets[0],
119+
logger.verbose(`Minting ${MINT_AMOUNT} public assets to the ${wallets.length} wallets...`);
120+
await new BatchCall(
121+
wallets[0],
122+
wallets.map(w => tokenAtWallet0.methods.mint_public(w.getAddress(), MINT_AMOUNT).request()),
123+
)
124+
.send()
125+
.wait();
126+
127+
logger.verbose(`Minting ${MINT_AMOUNT} private assets to the ${wallets.length} wallets...`);
128+
const secrets: Fr[] = wallets.map(() => Fr.random());
129+
const receipt = await new BatchCall(
130+
wallets[0],
131+
wallets.map((w, i) => tokenAtWallet0.methods.mint_private(MINT_AMOUNT, computeSecretHash(secrets[i])).request()),
132+
)
133+
.send()
134+
.wait();
135+
136+
wallets.forEach(async (wallet, i) => {
137+
await addPendingShieldNoteToPXE({
138+
amount: MINT_AMOUNT,
139+
secretHash: computeSecretHash(secrets[i]),
140+
txHash: receipt.txHash,
141+
accountAddress: wallet.getAddress(),
142+
assetAddress: tokenAddress,
143+
wallet: wallet,
144+
});
111145
});
112-
const txClaim = tokenAtWallet0.methods.redeem_shield(completeAddresses[0].address, MINT_AMOUNT, secret).send();
113-
await txClaim.wait({ debug: true });
146+
147+
await Promise.all(
148+
wallets.map(async (w, i) =>
149+
(await TokenContract.at(tokenAddress, w)).methods
150+
.redeem_shield(w.getAddress(), MINT_AMOUNT, secrets[i])
151+
.send()
152+
.wait(),
153+
),
154+
);
155+
114156
logger.verbose(`Minting complete.`);
115157
});
116158

@@ -119,34 +161,51 @@ describe('token transfer test', () => {
119161
expect(name).toBe(TOKEN_NAME);
120162
});
121163

122-
it('can transfer 1 publicly', async () => {
164+
it('can transfer 1 token privately and publicly', async () => {
165+
const recipient = recipientWallet.getAddress();
123166
const transferAmount = 1n;
124-
const numTransfers = MINT_AMOUNT / transferAmount;
125-
const initialBalance = await tokenAtWallet0.methods.balance_of_public(completeAddresses[0].address).simulate();
126-
expect(initialBalance).toBeGreaterThanOrEqual(transferAmount);
127-
for (let i = 1n; i <= numTransfers; i++) {
128-
await tokenAtWallet0.methods
129-
.transfer_public(completeAddresses[0].address, completeAddresses[1].address, transferAmount, 0)
130-
.send()
131-
.wait();
132-
}
133-
const finalBalance0 = await tokenAtWallet0.methods.balance_of_public(completeAddresses[0].address).simulate();
134-
expect(finalBalance0).toBe(0n);
135-
const finalBalance1 = await tokenAtWallet0.methods.balance_of_public(completeAddresses[1].address).simulate();
136-
expect(finalBalance1).toBe(MINT_AMOUNT);
137-
});
138167

139-
it('can transfer 1 privately', async () => {
140-
const transferAmount = 1n;
141-
const numTransfers = MINT_AMOUNT / transferAmount;
142-
const initialBalance = await tokenAtWallet0.methods.balance_of_private(completeAddresses[0].address).simulate();
143-
expect(initialBalance).toBeGreaterThanOrEqual(transferAmount);
144-
for (let i = 1n; i <= numTransfers; i++) {
145-
await tokenAtWallet0.methods.transfer(completeAddresses[1].address, transferAmount).send().wait();
168+
wallets.forEach(async w => {
169+
expect(MINT_AMOUNT).toBe(
170+
await (await TokenContract.at(tokenAddress, w)).methods.balance_of_private(w.getAddress()).simulate(),
171+
);
172+
expect(MINT_AMOUNT).toBe(await tokenAtWallet0.methods.balance_of_public(w.getAddress()).simulate());
173+
});
174+
175+
expect(0n).toBe(
176+
await (await TokenContract.at(tokenAddress, recipientWallet)).methods.balance_of_private(recipient).simulate(),
177+
);
178+
expect(0n).toBe(await tokenAtWallet0.methods.balance_of_public(recipient).simulate());
179+
180+
// For each round, make both private and public transfers
181+
for (let i = 1n; i <= ROUNDS; i++) {
182+
await Promise.all([
183+
...wallets.map(async w =>
184+
(await TokenContract.at(tokenAddress, w)).methods.transfer(recipient, transferAmount).send().wait(),
185+
),
186+
...wallets.map(async w =>
187+
(await TokenContract.at(tokenAddress, w)).methods
188+
.transfer_public(w.getAddress(), recipient, transferAmount, 0)
189+
.send()
190+
.wait(),
191+
),
192+
]);
146193
}
147-
const finalBalance0 = await tokenAtWallet0.methods.balance_of_private(completeAddresses[0].address).simulate();
148-
expect(finalBalance0).toBe(0n);
149-
const finalBalance1 = await tokenAtWallet0.methods.balance_of_private(completeAddresses[1].address).simulate();
150-
expect(finalBalance1).toBe(MINT_AMOUNT);
194+
195+
wallets.forEach(async w => {
196+
expect(MINT_AMOUNT - ROUNDS * transferAmount).toBe(
197+
await (await TokenContract.at(tokenAddress, w)).methods.balance_of_private(w.getAddress()).simulate(),
198+
);
199+
expect(MINT_AMOUNT - ROUNDS * transferAmount).toBe(
200+
await tokenAtWallet0.methods.balance_of_public(w.getAddress()).simulate(),
201+
);
202+
});
203+
204+
expect(ROUNDS * transferAmount * BigInt(wallets.length)).toBe(
205+
await (await TokenContract.at(tokenAddress, recipientWallet)).methods.balance_of_private(recipient).simulate(),
206+
);
207+
expect(ROUNDS * transferAmount * BigInt(wallets.length)).toBe(
208+
await tokenAtWallet0.methods.balance_of_public(recipient).simulate(),
209+
);
151210
});
152211
});

0 commit comments

Comments
 (0)