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: Tell user they need to pip install clang. #5525

Closed
wants to merge 12 commits into from
11 changes: 10 additions & 1 deletion barretenberg/scripts/bindgen.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
#!/usr/bin/env bash
set -eu

if ! pip list | grep -E 'clang\s+16.0.6' > /dev/null; then
echo "You need to install python clang: pip install clang==16.0.6"
exit 1
fi

#find ./cpp/src -type f -name "c_bind*.hpp" | ./scripts/decls_json.py > exports.json
cat ./scripts/c_bind_files.txt | ./scripts/decls_json.py > exports.json
(cd ./ts && yarn node --loader ts-node/esm ./src/bindgen/index.ts ../exports.json > ./src/barretenberg_api/index.ts)
(
cd ./ts && \
yarn node --loader ts-node/esm ./src/bindgen/index.ts ../exports.json > ./src/barretenberg_api/index.ts && \
yarn prettier -w ./src/barretenberg_api/index.ts
)
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/account_manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class AccountManager {
private accountContract: AccountContract,
salt?: Salt,
) {
this.salt = salt ? new Fr(salt) : Fr.random();
this.salt = salt !== undefined ? new Fr(salt) : Fr.random();
}

protected getEncryptionPublicKey() {
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export {
Body,
CompleteAddress,
ExtendedNote,
FunctionCall,
type FunctionCall,
GrumpkinPrivateKey,
L1ToL2Message,
L1Actor,
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuit-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ export * from './packed_arguments.js';
export * from './interfaces/index.js';
export * from './auth_witness.js';
export * from './aztec_node/rpc/index.js';
export { CompleteAddress, PublicKey, PartialAddress, GrumpkinPrivateKey } from '@aztec/circuits.js';
export { CompleteAddress, type PublicKey, type PartialAddress, GrumpkinPrivateKey } from '@aztec/circuits.js';
3 changes: 2 additions & 1 deletion yarn-project/circuits.js/src/types/grumpkin_private_key.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type GrumpkinScalar } from '@aztec/foundation/fields';
import { GrumpkinScalar } from '@aztec/foundation/fields';

/** A type alias for private key which belongs to the scalar field of Grumpkin curve. */
export type GrumpkinPrivateKey = GrumpkinScalar;
export const GrumpkinPrivateKey = GrumpkinScalar;
4 changes: 3 additions & 1 deletion yarn-project/end-to-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"clean": "rm -rf ./dest .tsbuildinfo",
"formatting": "run -T prettier --check ./src \"!src/web/main.js\" && run -T eslint ./src",
"formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
"test": "LOG_LEVEL=verbose NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --runInBand --testTimeout=60000 --forceExit",
"test": "LOG_LEVEL=${LOG_LEVEL:-verbose} NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=120000 --forceExit",
"test:integration": "concurrently -k -s first -c reset,dim -n test,anvil \"yarn test:integration:run\" \"anvil\"",
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --no-cache --runInBand --config jest.integration.config.json"
},
Expand Down Expand Up @@ -57,6 +57,7 @@
"@viem/anvil": "^0.0.9",
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
"fs-extra": "^11.2.0",
"get-port": "^7.1.0",
"glob": "^10.3.10",
"jest": "^29.5.0",
Expand Down Expand Up @@ -101,6 +102,7 @@
"node": ">=18"
},
"jest": {
"slowTestThreshold": 300,
"extensionsToTreatAsEsm": [
".ts"
],
Expand Down
6 changes: 1 addition & 5 deletions yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ import {
} from '@aztec/noir-contracts.js';
import { getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token';

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

import { type BalancesFn, expectMapping, getBalancesFn, publicDeployAccounts, setup } from './fixtures/utils.js';

jest.setTimeout(100_000);

const TOKEN_NAME = 'BananaCoin';
const TOKEN_SYMBOL = 'BC';
const TOKEN_DECIMALS = 18n;
Expand Down Expand Up @@ -66,7 +62,7 @@ describe('e2e_dapp_subscription', () => {
let wallets: AccountWalletWithPrivateKey[];
let aztecNode: AztecNode;
let deployL1ContractsValues: DeployL1Contracts;
({ wallets, aztecNode, deployL1ContractsValues, logger, pxe } = await setup(3));
({ wallets, aztecNode, deployL1ContractsValues, logger, pxe } = await setup(3, {}, {}, true));

await publicDeployAccounts(wallets[0], wallets);

Expand Down
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_fees.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('e2e_fees', () => {
let bananaPrivateBalances: BalancesFn;

beforeAll(async () => {
const { wallets: _wallets, aztecNode, deployL1ContractsValues, logger, pxe } = await setup(3);
const { wallets: _wallets, aztecNode, deployL1ContractsValues, logger, pxe } = await setup(3, {}, {}, true);
wallets = _wallets;

await aztecNode.setConfig({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { TokenContractTest } from './token_contract_test.js';

describe('e2e_token_contract access control', () => {
const t = new TokenContractTest('access_control');

beforeAll(async () => {
await t.applyBaseSnapshots();
await t.setup();
});

afterAll(async () => {
await t.teardown();
});

afterEach(async () => {
await t.tokenSim.check();
});

it('Set admin', async () => {
await t.asset.methods.set_admin(t.accounts[1].address).send().wait();
expect(await t.asset.methods.admin().simulate()).toBe(t.accounts[1].address.toBigInt());
});

it('Add minter as admin', async () => {
await t.asset.withWallet(t.wallets[1]).methods.set_minter(t.accounts[1].address, true).send().wait();
expect(await t.asset.methods.is_minter(t.accounts[1].address).simulate()).toBe(true);
});

it('Revoke minter as admin', async () => {
await t.asset.withWallet(t.wallets[1]).methods.set_minter(t.accounts[1].address, false).send().wait();
expect(await t.asset.methods.is_minter(t.accounts[1].address).simulate()).toBe(false);
});

describe('failure cases', () => {
it('Set admin (not admin)', async () => {
await expect(t.asset.methods.set_admin(t.accounts[0].address).simulate()).rejects.toThrow(
'Assertion failed: caller is not admin',
);
});
it('Revoke minter not as admin', async () => {
await expect(t.asset.methods.set_minter(t.accounts[0].address, false).simulate()).rejects.toThrow(
'Assertion failed: caller is not admin',
);
});
});
});
225 changes: 225 additions & 0 deletions yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
import { Fr, computeAuthWitMessageHash } from '@aztec/aztec.js';

import { U128_UNDERFLOW_ERROR } from '../fixtures/index.js';
import { TokenContractTest } from './token_contract_test.js';

describe('e2e_token_contract burn', () => {
const t = new TokenContractTest('burn');
let { asset, accounts, tokenSim, wallets } = t;

beforeAll(async () => {
await t.applyBaseSnapshots();
await t.applyMintSnapshot();
await t.setup();
// Have to destructure again to ensure we have latest refs.
({ asset, accounts, tokenSim, wallets } = t);
});

afterAll(async () => {
await t.teardown();
});

afterEach(async () => {
await t.tokenSim.check();
});

describe('public', () => {
it('burn less than balance', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 / 2n;
expect(amount).toBeGreaterThan(0n);
await asset.methods.burn_public(accounts[0].address, amount, 0).send().wait();

tokenSim.burnPublic(accounts[0].address, amount);
});

it('burn on behalf of other', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 / 2n;
expect(amount).toBeGreaterThan(0n);
const nonce = Fr.random();

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce);
await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait();

await action.send().wait();

tokenSim.burnPublic(accounts[0].address, amount);

// Check that the message hash is no longer valid. Need to try to send since nullifiers are handled by sequencer.
const txReplay = asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).send();
await expect(txReplay.wait()).rejects.toThrow('Transaction ');
});

describe('failure cases', () => {
it('burn more than balance', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 + 1n;
const nonce = 0;
await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).simulate()).rejects.toThrow(
U128_UNDERFLOW_ERROR,
);
});

it('burn on behalf of self with non-zero nonce', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 - 1n;
expect(amount).toBeGreaterThan(0n);
const nonce = 1;
await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).simulate()).rejects.toThrow(
'Assertion failed: invalid nonce',
);
});

it('burn on behalf of other without "approval"', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 + 1n;
const nonce = Fr.random();
await expect(
asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).simulate(),
).rejects.toThrow('Assertion failed: Message not authorized by account');
});

it('burn more than balance on behalf of other', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 + 1n;
const nonce = Fr.random();
expect(amount).toBeGreaterThan(0n);

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce);
await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait();

await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR);
});

it('burn on behalf of other, wrong designated caller', async () => {
const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate();
const amount = balance0 + 2n;
const nonce = Fr.random();
expect(amount).toBeGreaterThan(0n);

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce);
await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait();

await expect(
asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).simulate(),
).rejects.toThrow('Assertion failed: Message not authorized by account');
});
});
});

describe('private', () => {
it('burn less than balance', async () => {
const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balance0 / 2n;
expect(amount).toBeGreaterThan(0n);
await asset.methods.burn(accounts[0].address, amount, 0).send().wait();
tokenSim.burnPrivate(accounts[0].address, amount);
});

it('burn on behalf of other', async () => {
const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balance0 / 2n;
const nonce = Fr.random();
expect(amount).toBeGreaterThan(0n);

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[1]).methods.burn(accounts[0].address, amount, nonce);

// Both wallets are connected to same node and PXE so we could just insert directly
// But doing it in two actions to show the flow.
const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action });
await wallets[1].addAuthWitness(witness);

await asset.withWallet(wallets[1]).methods.burn(accounts[0].address, amount, nonce).send().wait();
tokenSim.burnPrivate(accounts[0].address, amount);

// Perform the transfer again, should fail
const txReplay = asset.withWallet(wallets[1]).methods.burn(accounts[0].address, amount, nonce).send();
await expect(txReplay.wait()).rejects.toThrow('Transaction ');
});

describe('failure cases', () => {
it('burn more than balance', async () => {
const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balance0 + 1n;
expect(amount).toBeGreaterThan(0n);
await expect(asset.methods.burn(accounts[0].address, amount, 0).simulate()).rejects.toThrow(
'Assertion failed: Balance too low',
);
});

it('burn on behalf of self with non-zero nonce', async () => {
const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balance0 - 1n;
expect(amount).toBeGreaterThan(0n);
await expect(asset.methods.burn(accounts[0].address, amount, 1).simulate()).rejects.toThrow(
'Assertion failed: invalid nonce',
);
});

it('burn more than balance on behalf of other', async () => {
const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balance0 + 1n;
const nonce = Fr.random();
expect(amount).toBeGreaterThan(0n);

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[1]).methods.burn(accounts[0].address, amount, nonce);

// Both wallets are connected to same node and PXE so we could just insert directly
// But doing it in two actions to show the flow.
const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action });
await wallets[1].addAuthWitness(witness);

await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low');
});

it('burn on behalf of other without approval', async () => {
const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balance0 / 2n;
const nonce = Fr.random();
expect(amount).toBeGreaterThan(0n);

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[1]).methods.burn(accounts[0].address, amount, nonce);
const messageHash = computeAuthWitMessageHash(
accounts[1].address,
wallets[0].getChainId(),
wallets[0].getVersion(),
action.request(),
);

await expect(action.simulate()).rejects.toThrow(
`Unknown auth witness for message hash ${messageHash.toString()}`,
);
});

it('on behalf of other (invalid designated caller)', async () => {
const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate();
const amount = balancePriv0 + 2n;
const nonce = Fr.random();
expect(amount).toBeGreaterThan(0n);

// We need to compute the message we want to sign and add it to the wallet as approved
const action = asset.withWallet(wallets[2]).methods.burn(accounts[0].address, amount, nonce);
const expectedMessageHash = computeAuthWitMessageHash(
accounts[2].address,
wallets[0].getChainId(),
wallets[0].getVersion(),
action.request(),
);

const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action });
await wallets[2].addAuthWitness(witness);

await expect(action.simulate()).rejects.toThrow(
`Unknown auth witness for message hash ${expectedMessageHash.toString()}`,
);
});
});
});
});
Loading
Loading