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: ensuring sandbox/aztec.js errors are clear #1185

Merged
merged 11 commits into from
Jul 26, 2023
4 changes: 2 additions & 2 deletions yarn-project/acir-simulator/src/acvm/acvm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ export async function acvm(
logger(`Oracle callback ${name}`);
const oracleFunction = callback[name as ORACLE_NAMES];
if (!oracleFunction) {
throw new Error(`Callback ${name} not found`);
throw new Error(`Oracle callback ${name} not found`);
}

const result = await oracleFunction.call(callback, ...args);
return [result];
} catch (err: any) {
logger(`Error in ACVM callback ${name}: ${err.message ?? err ?? 'Unknown'}`);
logger(`Error in oracle callback ${name}: ${err.message ?? err ?? 'Unknown'}`);
throw err;
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,16 @@ describe('AztecRpcServer', function () {

await expect(rpcServer.addAccount(privateKey, address, partialAddress)).rejects.toThrowError(/cannot be derived/);
});

it('cannot add the same account twice', async () => {
const keyPair = ConstantKeyPair.random(await Grumpkin.new());
const pubKey = keyPair.getPublicKey();
const partialAddress = Fr.random();
const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress);

await rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress);
await expect(async () =>
rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress),
).rejects.toThrow(`Account ${address} already exists`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,12 @@ export class AztecRPCServer implements AztecRPC {
): Promise<ExecutionRequest> {
const contract = await this.db.getContract(to);
if (!contract) {
throw new Error('Unknown contract.');
throw new Error(`Unknown contract ${to}! Add it to Aztec RPC server by calling server.addContracts(...)`);
benesjan marked this conversation as resolved.
Show resolved Hide resolved
}

const functionDao = contract.functions.find(f => f.name === functionName);
if (!functionDao) {
throw new Error('Unknown function.');
throw new Error(`Unknown function ${functionName}.`);
benesjan marked this conversation as resolved.
Show resolved Hide resolved
}

const flatArgs = encodeArguments(functionDao, args);
Expand Down
8 changes: 7 additions & 1 deletion yarn-project/aztec-rpc/src/contract_tree/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,13 @@ export class ContractTree {
public getFunctionAbi(functionSelector: Buffer) {
const abi = this.contract.functions.find(f => f.selector.equals(functionSelector));
if (!abi) {
throw new Error(`Unknown function: ${functionSelector.toString('hex')}.`);
throw new Error(
`Unknown function. Selector ${functionSelector.toString(
'hex',
)} not found in the ABI of contract ${this.contract.address.toString()}. Expected one of: ${this.contract.functions
.map(f => f.selector.toString('hex'))
.join(', ')}`,
);
}
return abi;
}
Expand Down
3 changes: 3 additions & 0 deletions yarn-project/aztec-rpc/src/database/memory_db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ export class MemoryDB extends MemoryContractDatabase implements Database {
publicKey: PublicKey,
partialAddress: PartialContractAddress,
): Promise<void> {
if (this.publicKeys.has(address.toBigInt())) {
throw new Error(`Account ${address} already exists`);
}
this.publicKeys.set(address.toBigInt(), [publicKey, partialAddress]);
return Promise.resolve();
}
Expand Down
5 changes: 4 additions & 1 deletion yarn-project/aztec-rpc/src/simulator_oracle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ export class SimulatorOracle implements DBOracle {
*/
async getPublicKey(address: AztecAddress): Promise<[PublicKey, PartialContractAddress]> {
const result = await this.db.getPublicKeyAndPartialAddress(address);
if (!result) throw new Error(`Unknown public key for address ${address.toString()}`);
if (!result)
throw new Error(
`Unknown public key for address ${address.toString()}. Add public key to Aztec RPC server by calling server.addPublicKeyAndPartialAddress(...)`,
);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ export class ContractFunctionInteraction {
protected contractAddress: AztecAddress,
protected functionDao: FunctionAbi,
protected args: any[],
) {}
) {
if (args.some(arg => arg === undefined || arg === null)) {
throw new Error('All function interaction arguments must be defined and not null. Received: ' + args);
}
}

/**
* Create an Aztec transaction instance by combining the transaction request and its signature.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { DeployMethod } from './deploy_method.js';

/**
* A class for deploying contract.
* @remarks Keeping this around even though we have noir contract types because it can be useful for non-TS users.
*/
export class ContractDeployer {
// TODO: remove this?
constructor(private abi: ContractAbi, private arc: AztecRPC, private publicKey?: PublicKey) {}

/**
Expand Down