Skip to content

Commit 65b21a6

Browse files
authored
refactor: improve use of authwit proxy in e2e tests (#20466)
## Summary The use of the generic proxy for authwit tests made readability quite difficult. We are now improving this by adding two helper functions At the same time, we are adding a comment to the tests that while a little repetitive, it makes the use of the proxy much clearer
2 parents 8d16762 + aae09cc commit 65b21a6

File tree

10 files changed

+197
-168
lines changed

10 files changed

+197
-168
lines changed

yarn-project/end-to-end/src/e2e_authwit.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import { computeInnerAuthWitHash } from '@aztec/aztec.js/authorization';
33
import { Fr } from '@aztec/aztec.js/fields';
44
import { AuthRegistryContract } from '@aztec/noir-contracts.js/AuthRegistry';
55
import { AuthWitTestContract } from '@aztec/noir-test-contracts.js/AuthWitTest';
6+
import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
67
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
78

89
import { jest } from '@jest/globals';
910

11+
import { sendThroughAuthwitProxy } from './fixtures/authwit_proxy.js';
1012
import { DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js';
1113
import { ensureAccountContractsPublished, setup } from './fixtures/utils.js';
1214
import type { TestWallet } from './test-wallet/test_wallet.js';
@@ -21,6 +23,7 @@ describe('e2e_authwit_tests', () => {
2123
let account2Address: AztecAddress;
2224

2325
let auth: AuthWitTestContract;
26+
let authwitProxy: GenericProxyContract;
2427

2528
beforeAll(async () => {
2629
({
@@ -30,6 +33,7 @@ describe('e2e_authwit_tests', () => {
3033
await ensureAccountContractsPublished(wallet, [account1Address, account2Address]);
3134

3235
auth = await AuthWitTestContract.deploy(wallet).send({ from: account1Address });
36+
authwitProxy = await GenericProxyContract.deploy(wallet).send({ from: account1Address });
3337
});
3438

3539
describe('Private', () => {
@@ -60,9 +64,10 @@ describe('e2e_authwit_tests', () => {
6064
});
6165

6266
// Consume the inner hash using the account1 as the "on behalf of".
63-
await auth.methods
64-
.consume(account1Address, innerHash)
65-
.send({ from: account2Address, authWitnesses: [witness] });
67+
// We send through the proxy so the proxy becomes msg_sender in consume,
68+
// while account1 remains the tx sender (with their keys in scope).
69+
const action = auth.methods.consume(account1Address, innerHash);
70+
await sendThroughAuthwitProxy(authwitProxy, action, { from: account1Address, authWitnesses: [witness] });
6671

6772
expect(await wallet.lookupValidity(account1Address, intent, witness)).toEqual({
6873
isValidInPrivate: false,
@@ -71,7 +76,10 @@ describe('e2e_authwit_tests', () => {
7176

7277
// Try to consume the same authwit again, it should fail
7378
await expect(
74-
auth.methods.consume(account1Address, innerHash).send({ from: account2Address, authWitnesses: [witness] }),
79+
sendThroughAuthwitProxy(authwitProxy, auth.methods.consume(account1Address, innerHash), {
80+
from: account1Address,
81+
authWitnesses: [witness],
82+
}),
7583
).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
7684
});
7785
});

yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class BlacklistTokenContractTest {
5454
asset!: TokenBlacklistContract;
5555
tokenSim!: TokenSimulator;
5656
badAccount!: InvalidAccountContract;
57-
proxy!: GenericProxyContract;
57+
authwitProxy!: GenericProxyContract;
5858
cheatCodes!: CheatCodes;
5959
sequencer!: SequencerClient;
6060
aztecNode!: AztecNode;
@@ -120,8 +120,8 @@ export class BlacklistTokenContractTest {
120120
// (so their notes are in scope), but msg_sender in the target must differ from the note owner
121121
// to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender.
122122
this.logger.verbose(`Deploying generic proxy...`);
123-
this.proxy = await GenericProxyContract.deploy(this.wallet).send({ from: this.adminAddress });
124-
this.logger.verbose(`Deployed to ${this.proxy.address}.`);
123+
this.authwitProxy = await GenericProxyContract.deploy(this.wallet).send({ from: this.adminAddress });
124+
this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`);
125125

126126
await this.crossTimestampOfChange();
127127

yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization';
22
import { Fr } from '@aztec/aztec.js/fields';
33

4+
import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js';
45
import { DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js';
56
import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js';
67

@@ -151,19 +152,16 @@ describe('e2e_blacklist_token_contract burn', () => {
151152
expect(amount).toBeGreaterThan(0n);
152153

153154
const action = asset.methods.burn(adminAddress, amount, authwitNonce);
154-
const call = await action.getFunctionCall();
155-
const witness = await wallet.createAuthWit(adminAddress, { caller: t.proxy.address, action });
155+
const witness = await wallet.createAuthWit(adminAddress, { caller: t.authwitProxy.address, action });
156156

157-
await t.proxy.methods
158-
.forward_private_3(call.to, call.selector, call.args)
159-
.send({ from: adminAddress, authWitnesses: [witness] });
157+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
158+
await sendThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] });
160159
tokenSim.burnPrivate(adminAddress, amount);
161160

162161
// Perform the transfer again, should fail
163-
const txReplay = t.proxy.methods
164-
.forward_private_3(call.to, call.selector, call.args)
165-
.send({ from: adminAddress, authWitnesses: [witness] });
166-
await expect(txReplay).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
162+
await expect(
163+
sendThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
164+
).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
167165
});
168166

169167
describe('failure cases', () => {
@@ -191,16 +189,13 @@ describe('e2e_blacklist_token_contract burn', () => {
191189
const authwitNonce = Fr.random();
192190
expect(amount).toBeGreaterThan(0n);
193191

194-
// We need to compute the message we want to sign and add it to the wallet as approved
195192
const action = asset.methods.burn(adminAddress, amount, authwitNonce);
193+
const witness = await wallet.createAuthWit(adminAddress, { caller: t.authwitProxy.address, action });
196194

197-
// Both wallets are connected to same node and PXE so we could just insert directly
198-
// But doing it in two actions to show the flow.
199-
const witness = await wallet.createAuthWit(adminAddress, { caller: otherAddress, action });
200-
201-
await expect(action.simulate({ from: otherAddress, authWitnesses: [witness] })).rejects.toThrow(
202-
'Assertion failed: Balance too low',
203-
);
195+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
196+
await expect(
197+
simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
198+
).rejects.toThrow('Assertion failed: Balance too low');
204199
});
205200

206201
it('burn on behalf of other without approval', async () => {
@@ -209,14 +204,15 @@ describe('e2e_blacklist_token_contract burn', () => {
209204
const authwitNonce = Fr.random();
210205
expect(amount).toBeGreaterThan(0n);
211206

212-
// We need to compute the message we want to sign and add it to the wallet as approved
213207
const action = asset.methods.burn(adminAddress, amount, authwitNonce);
208+
const call = await action.getFunctionCall();
214209
const messageHash = await computeAuthWitMessageHash(
215-
{ caller: otherAddress, call: await action.getFunctionCall() },
210+
{ caller: t.authwitProxy.address, call },
216211
await wallet.getChainInfo(),
217212
);
218213

219-
await expect(action.simulate({ from: otherAddress })).rejects.toThrow(
214+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
215+
await expect(simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress })).rejects.toThrow(
220216
`Unknown auth witness for message hash ${messageHash.toString()}`,
221217
);
222218
});
@@ -227,18 +223,19 @@ describe('e2e_blacklist_token_contract burn', () => {
227223
const authwitNonce = Fr.random();
228224
expect(amount).toBeGreaterThan(0n);
229225

230-
// We need to compute the message we want to sign and add it to the wallet as approved
231226
const action = asset.methods.burn(adminAddress, amount, authwitNonce);
227+
const call = await action.getFunctionCall();
232228
const expectedMessageHash = await computeAuthWitMessageHash(
233-
{ caller: blacklistedAddress, call: await action.getFunctionCall() },
229+
{ caller: t.authwitProxy.address, call },
234230
await wallet.getChainInfo(),
235231
);
236232

237233
const witness = await wallet.createAuthWit(adminAddress, { caller: otherAddress, action });
238234

239-
await expect(action.simulate({ from: blacklistedAddress, authWitnesses: [witness] })).rejects.toThrow(
240-
`Unknown auth witness for message hash ${expectedMessageHash.toString()}`,
241-
);
235+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
236+
await expect(
237+
simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
238+
).rejects.toThrow(`Unknown auth witness for message hash ${expectedMessageHash.toString()}`);
242239
});
243240

244241
it('burn from blacklisted account', async () => {

yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization';
22
import { Fr } from '@aztec/aztec.js/fields';
33

4+
import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js';
45
import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js';
56
import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js';
67

@@ -49,19 +50,16 @@ describe('e2e_blacklist_token_contract transfer private', () => {
4950
expect(amount).toBeGreaterThan(0n);
5051

5152
const action = asset.methods.transfer(adminAddress, otherAddress, amount, authwitNonce);
52-
const call = await action.getFunctionCall();
53-
const witness = await wallet.createAuthWit(adminAddress, { caller: t.proxy.address, action });
53+
const witness = await wallet.createAuthWit(adminAddress, { caller: t.authwitProxy.address, action });
5454

55-
await t.proxy.methods
56-
.forward_private_4(call.to, call.selector, call.args)
57-
.send({ from: adminAddress, authWitnesses: [witness] });
55+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
56+
await sendThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] });
5857
tokenSim.transferPrivate(adminAddress, otherAddress, amount);
5958

6059
// Perform the transfer again, should fail
61-
const txReplay = t.proxy.methods
62-
.forward_private_4(call.to, call.selector, call.args)
63-
.send({ from: adminAddress, authWitnesses: [witness] });
64-
await expect(txReplay).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
60+
await expect(
61+
sendThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
62+
).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
6563
});
6664

6765
describe('failure cases', () => {
@@ -94,17 +92,13 @@ describe('e2e_blacklist_token_contract transfer private', () => {
9492
const authwitNonce = Fr.random();
9593
expect(amount).toBeGreaterThan(0n);
9694

97-
// We need to compute the message we want to sign and add it to the wallet as approved
9895
const action = asset.methods.transfer(adminAddress, otherAddress, amount, authwitNonce);
96+
const witness = await wallet.createAuthWit(adminAddress, { caller: t.authwitProxy.address, action });
9997

100-
// Both wallets are connected to same node and PXE so we could just insert directly
101-
// But doing it in two actions to show the flow.
102-
const witness = await wallet.createAuthWit(adminAddress, { caller: otherAddress, action });
103-
104-
// Perform the transfer
105-
await expect(action.simulate({ from: otherAddress, authWitnesses: [witness] })).rejects.toThrow(
106-
'Assertion failed: Balance too low',
107-
);
98+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
99+
await expect(
100+
simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
101+
).rejects.toThrow('Assertion failed: Balance too low');
108102
expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual(balance0);
109103
expect(await asset.methods.balance_of_private(otherAddress).simulate({ from: otherAddress })).toEqual(balance1);
110104
});
@@ -122,14 +116,15 @@ describe('e2e_blacklist_token_contract transfer private', () => {
122116
const authwitNonce = Fr.random();
123117
expect(amount).toBeGreaterThan(0n);
124118

125-
// We need to compute the message we want to sign and add it to the wallet as approved
126119
const action = asset.methods.transfer(adminAddress, otherAddress, amount, authwitNonce);
120+
const call = await action.getFunctionCall();
127121
const messageHash = await computeAuthWitMessageHash(
128-
{ caller: otherAddress, call: await action.getFunctionCall() },
122+
{ caller: t.authwitProxy.address, call },
129123
await wallet.getChainInfo(),
130124
);
131125

132-
await expect(action.simulate({ from: otherAddress })).rejects.toThrow(
126+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
127+
await expect(simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress })).rejects.toThrow(
133128
`Unknown auth witness for message hash ${messageHash.toString()}`,
134129
);
135130
});
@@ -140,18 +135,19 @@ describe('e2e_blacklist_token_contract transfer private', () => {
140135
const authwitNonce = Fr.random();
141136
expect(amount).toBeGreaterThan(0n);
142137

143-
// We need to compute the message we want to sign and add it to the wallet as approved
144138
const action = asset.methods.transfer(adminAddress, otherAddress, amount, authwitNonce);
139+
const call = await action.getFunctionCall();
145140
const expectedMessageHash = await computeAuthWitMessageHash(
146-
{ caller: blacklistedAddress, call: await action.getFunctionCall() },
141+
{ caller: t.authwitProxy.address, call },
147142
await wallet.getChainInfo(),
148143
);
149144

150145
const witness = await wallet.createAuthWit(adminAddress, { caller: otherAddress, action });
151146

152-
await expect(action.simulate({ from: blacklistedAddress, authWitnesses: [witness] })).rejects.toThrow(
153-
`Unknown auth witness for message hash ${expectedMessageHash.toString()}`,
154-
);
147+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
148+
await expect(
149+
simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
150+
).rejects.toThrow(`Unknown auth witness for message hash ${expectedMessageHash.toString()}`);
155151
expect(await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress })).toEqual(balance0);
156152
});
157153

yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization';
22
import { Fr } from '@aztec/aztec.js/fields';
33

4+
import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js';
45
import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js';
56
import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js';
67

@@ -41,19 +42,16 @@ describe('e2e_blacklist_token_contract unshielding', () => {
4142
expect(amount).toBeGreaterThan(0n);
4243

4344
const action = asset.methods.unshield(adminAddress, otherAddress, amount, authwitNonce);
44-
const call = await action.getFunctionCall();
45-
const witness = await wallet.createAuthWit(adminAddress, { caller: t.proxy.address, action });
45+
const witness = await wallet.createAuthWit(adminAddress, { caller: t.authwitProxy.address, action });
4646

47-
await t.proxy.methods
48-
.forward_private_4(call.to, call.selector, call.args)
49-
.send({ from: adminAddress, authWitnesses: [witness] });
47+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
48+
await sendThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] });
5049
tokenSim.transferToPublic(adminAddress, otherAddress, amount);
5150

5251
// Perform the transfer again, should fail
53-
const txReplay = t.proxy.methods
54-
.forward_private_4(call.to, call.selector, call.args)
55-
.send({ from: adminAddress, authWitnesses: [witness] });
56-
await expect(txReplay).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
52+
await expect(
53+
sendThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
54+
).rejects.toThrow(DUPLICATE_NULLIFIER_ERROR);
5755
});
5856

5957
describe('failure cases', () => {
@@ -85,16 +83,13 @@ describe('e2e_blacklist_token_contract unshielding', () => {
8583
const authwitNonce = Fr.random();
8684
expect(amount).toBeGreaterThan(0n);
8785

88-
// We need to compute the message we want to sign and add it to the wallet as approved
8986
const action = asset.methods.unshield(adminAddress, otherAddress, amount, authwitNonce);
87+
const witness = await wallet.createAuthWit(adminAddress, { caller: t.authwitProxy.address, action });
9088

91-
// Both wallets are connected to same node and PXE so we could just insert directly
92-
// But doing it in two actions to show the flow.
93-
const witness = await wallet.createAuthWit(adminAddress, { caller: otherAddress, action });
94-
95-
await expect(action.simulate({ from: otherAddress, authWitnesses: [witness] })).rejects.toThrow(
96-
'Assertion failed: Balance too low',
97-
);
89+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
90+
await expect(
91+
simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
92+
).rejects.toThrow('Assertion failed: Balance too low');
9893
});
9994

10095
it('on behalf of other (invalid designated caller)', async () => {
@@ -103,20 +98,19 @@ describe('e2e_blacklist_token_contract unshielding', () => {
10398
const authwitNonce = Fr.random();
10499
expect(amount).toBeGreaterThan(0n);
105100

106-
// We need to compute the message we want to sign and add it to the wallet as approved
107101
const action = asset.methods.unshield(adminAddress, otherAddress, amount, authwitNonce);
102+
const call = await action.getFunctionCall();
108103
const expectedMessageHash = await computeAuthWitMessageHash(
109-
{ caller: blacklistedAddress, call: await action.getFunctionCall() },
104+
{ caller: t.authwitProxy.address, call },
110105
await wallet.getChainInfo(),
111106
);
112107

113-
// Both wallets are connected to same node and PXE so we could just insert directly
114-
// But doing it in two actions to show the flow.
115108
const witness = await wallet.createAuthWit(adminAddress, { caller: otherAddress, action });
116109

117-
await expect(action.simulate({ from: blacklistedAddress, authWitnesses: [witness] })).rejects.toThrow(
118-
`Unknown auth witness for message hash ${expectedMessageHash.toString()}`,
119-
);
110+
// Admin sends through proxy so their keys are in scope, while proxy becomes msg_sender to trigger authwit.
111+
await expect(
112+
simulateThroughAuthwitProxy(t.authwitProxy, action, { from: adminAddress, authWitnesses: [witness] }),
113+
).rejects.toThrow(`Unknown auth witness for message hash ${expectedMessageHash.toString()}`);
120114
});
121115

122116
it('unshield from blacklisted account', async () => {

0 commit comments

Comments
 (0)