Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Aug 11, 2023
1 parent e66c970 commit 820c72b
Show file tree
Hide file tree
Showing 38 changed files with 231 additions and 254 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
import {
computeCallStackItemHash,
computeCommitmentNonce,
computeContractAddressFromPartial,
computeSecretMessageHash,
computeUniqueCommitment,
siloCommitment,
Expand All @@ -28,7 +27,7 @@ import { asyncMap } from '@aztec/foundation/async-map';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { toBufferBE } from '@aztec/foundation/bigint-buffer';
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr, Point } from '@aztec/foundation/fields';
import { Fr } from '@aztec/foundation/fields';
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
import { AppendOnlyTree, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class PrivateFunctionExecution {
getSecretKey: ([ownerX], [ownerY]) => this.context.getSecretKey(this.contractAddress, ownerX, ownerY),
getPublicKey: async ([acvmAddress]) => {
const address = frToAztecAddress(fromACVMField(acvmAddress));
const {publicKey, partialAddress} = await this.context.db.getRecipient(address);
const { publicKey, partialAddress } = await this.context.db.getRecipient(address);
return [publicKey.x, publicKey.y, partialAddress].map(toACVMField);
},
getNotes: ([slot], sortBy, sortOrder, [limit], [offset], [returnSize]) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { CircuitsWasm, CompleteAddress, ConstantHistoricBlockData, FunctionData, PrivateKey } from '@aztec/circuits.js';
import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { CompleteAddress, ConstantHistoricBlockData, FunctionData, PrivateKey } from '@aztec/circuits.js';
import { encodeArguments } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
Expand All @@ -14,14 +12,9 @@ import { DBOracle } from './db_oracle.js';
import { AcirSimulator } from './simulator.js';

describe('Unconstrained Execution test suite', () => {
let bbWasm: CircuitsWasm;
let oracle: ReturnType<typeof mock<DBOracle>>;
let acirSimulator: AcirSimulator;

beforeAll(async () => {
bbWasm = await CircuitsWasm.get();
});

beforeEach(() => {
oracle = mock<DBOracle>();
acirSimulator = new AcirSimulator(oracle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class UnconstrainedFunctionExecution {
getSecretKey: ([ownerX], [ownerY]) => this.context.getSecretKey(this.contractAddress, ownerX, ownerY),
getPublicKey: async ([acvmAddress]) => {
const address = frToAztecAddress(fromACVMField(acvmAddress));
const {publicKey, partialAddress} = await this.context.db.getRecipient(address);
const { publicKey, partialAddress } = await this.context.db.getRecipient(address);
return [publicKey.x, publicKey.y, partialAddress].map(toACVMField);
},
getNotes: ([slot], sortBy, sortOrder, [limit], [offset], [returnSize]) =>
Expand Down
12 changes: 5 additions & 7 deletions yarn-project/aztec-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { StructType } from '@aztec/foundation/abi';
import { JsonStringify } from '@aztec/foundation/json-rpc';
import { createConsoleLogger, createDebugLogger } from '@aztec/foundation/log';
import { SchnorrSingleKeyAccountContractAbi } from '@aztec/noir-contracts/artifacts';
import { ContractData, L2BlockL2Logs, PrivateKey, TxHash } from '@aztec/types';
import { CompleteAddress, ContractData, L2BlockL2Logs, PrivateKey, TxHash } from '@aztec/types';

import { Command } from 'commander';
import { mnemonicToAccount } from 'viem/accounts';
Expand Down Expand Up @@ -125,9 +125,7 @@ async function main() {
);
const accounts = await wallet.getAccounts();
log(`\nCreated account(s).`);
accounts.map((acc) =>
log(acc.toString()),
);
accounts.map(acc => log(acc.toString()));
});

program
Expand Down Expand Up @@ -265,8 +263,8 @@ async function main() {
});

program
.command('register-public-key')
.description("Register an account's public key to the RPC server")
.command('register-recipient')
.description('Register an account as a recipient in the Aztec RPC.')
.option('-a, --address <aztecAddress>', "The account's Aztec address.")
.option('-p, --public-key <publicKey>', 'The account public key.')
.option('-pa, --partial-address <partialAddress', 'The partially computed address of the account contract.')
Expand All @@ -277,7 +275,7 @@ async function main() {
const publicKey = Point.fromString(options.publicKey);
const partialAddress = Fr.fromString(options.partialAddress);

await client.addRecipient(address, publicKey, partialAddress);
await client.addRecipient(new CompleteAddress(address, publicKey, partialAddress));
log(`\nRegistered details for Address: ${options.address}\n`);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AztecAddress, CircuitsWasm, Fr, Point, PrivateKey } from '@aztec/circuits.js';
import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis';
import { AztecAddress, CompleteAddress, Fr, Point, PrivateKey } from '@aztec/circuits.js';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { ConstantKeyPair, TestKeyStore } from '@aztec/key-store';
import { AztecNode } from '@aztec/types';
Expand All @@ -11,7 +10,6 @@ import { RpcServerConfig } from '../index.js';
import { AztecRPCServer } from './aztec_rpc_server.js';

describe('AztecRpcServer', function () {
let wasm: CircuitsWasm;
let keyStore: TestKeyStore;
let db: MemoryDB;
let node: MockProxy<AztecNode>;
Expand All @@ -25,47 +23,37 @@ describe('AztecRpcServer', function () {
l2BlockPollingIntervalMS: 100,
};
rpcServer = new AztecRPCServer(keyStore, node, db, config);
wasm = await CircuitsWasm.get();
});

it('registers a public key in the db when adding a new account', async () => {
const keyPair = ConstantKeyPair.random(await Grumpkin.new());
const pubKey = keyPair.getPublicKey();
const partialAddress = Fr.random();
const address = computeContractAddressFromPartial(wasm, pubKey, partialAddress);
const completeAddress = await CompleteAddress.fromPrivateKey(await keyPair.getPrivateKey());

await rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress);
expect(await db.getRecipient(address)).toEqual([pubKey, partialAddress]);
await rpcServer.addAccount(await keyPair.getPrivateKey(), completeAddress);
expect(await db.getRecipient(completeAddress.address)).toEqual(completeAddress);
});

it('refuses to add an account with incorrect address for given partial address and privkey', async () => {
const privateKey = PrivateKey.random();
const partialAddress = Fr.random();
const address = AztecAddress.random();
const completeAddress = new CompleteAddress(AztecAddress.random(), Point.random(), Fr.random());

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

it('refuses to add an account with incorrect address for given partial address and pubkey', async () => {
const publicKey = Point.random();
const partialAddress = Fr.random();
const address = AztecAddress.random();
const completeAddress = new CompleteAddress(AztecAddress.random(), Point.random(), Fr.random());

await expect(rpcServer.addRecipient(address, publicKey, partialAddress)).rejects.toThrowError(
/cannot be derived/,
);
await expect(rpcServer.addRecipient(completeAddress)).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);
const completeAddress = await CompleteAddress.fromPrivateKey(await keyPair.getPrivateKey());

await rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress);
await expect(async () =>
rpcServer.addAccount(await keyPair.getPrivateKey(), address, partialAddress),
).rejects.toThrow(`Account ${address} already exists`);
await rpcServer.addAccount(await keyPair.getPrivateKey(), completeAddress);
await expect(async () => rpcServer.addAccount(await keyPair.getPrivateKey(), completeAddress)).rejects.toThrow(
`Account ${completeAddress.address} already exists`,
);
});

it('throws when getting public storage for non-existent contract', async () => {
Expand Down
17 changes: 8 additions & 9 deletions yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import {
CompleteAddress,
ConstantHistoricBlockData,
FunctionData,
PartialAddress,
PrivateKey,
PublicKey,
} from '@aztec/circuits.js';
import { computeContractAddressFromPartial } from '@aztec/circuits.js/abis';
import { encodeArguments } from '@aztec/foundation/abi';
Expand Down Expand Up @@ -105,12 +103,13 @@ export class AztecRPCServer implements AztecRPC {
this.log.info(`Added account ${completeAddress.toString()}`);
}

public async addRecipient(
recipientAddress: CompleteAddress

): Promise<void> {
public async addRecipient(recipientAddress: CompleteAddress): Promise<void> {
const wasm = await CircuitsWasm.get();
const expectedAddress = computeContractAddressFromPartial(wasm, recipientAddress.publicKey, recipientAddress.partialAddress);
const expectedAddress = computeContractAddressFromPartial(
wasm,
recipientAddress.publicKey,
recipientAddress.partialAddress,
);
if (!expectedAddress.equals(recipientAddress.address)) {
throw new Error(
`Address cannot be derived from pubkey and partial address (received ${recipientAddress.address.toString()}, derived ${expectedAddress.toString()})`,
Expand All @@ -134,8 +133,8 @@ export class AztecRPCServer implements AztecRPC {
return await this.db.getRecipients();
}

public async getPublicKeyAndPartialAddress(address: AztecAddress): Promise<[PublicKey, PartialAddress]> {
const result = await this.db.getPublicKeyAndPartialAddress(address);
public async getAccount(address: AztecAddress): Promise<CompleteAddress> {
const result = await this.db.getRecipient(address);
if (!result) {
throw new Error(`Unable to get public key for address ${address.toString()}`);
}
Expand Down
6 changes: 2 additions & 4 deletions yarn-project/aztec-rpc/src/database/database.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CompleteAddress, PartialAddress } from '@aztec/circuits.js';
import { CompleteAddress } from '@aztec/circuits.js';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { ContractDatabase, MerkleTreeId, PublicKey, TxHash } from '@aztec/types';
Expand Down Expand Up @@ -117,9 +117,7 @@ export interface Database extends ContractDatabase {
* @param recipientAddress - The complete address of the recipient.
* @returns Empty promise.
*/
addRecipient(
recipientAddress: CompleteAddress
): Promise<void>;
addRecipient(recipientAddress: CompleteAddress): Promise<void>;

/**
* Retrieves the complete address of the account corresponding to the provided aztec address.
Expand Down
4 changes: 1 addition & 3 deletions yarn-project/aztec-rpc/src/database/memory_db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database {
return Promise.resolve();
}

addRecipient(
recipient: CompleteAddress
): Promise<void> {
addRecipient(recipient: CompleteAddress): Promise<void> {
// Check if recipient is in recipients and throw an error if yes
const recipientIndex = this.recipients.findIndex(r => r.address.equals(recipient.address));
if (recipientIndex !== -1) {
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec-rpc/src/simulator_oracle/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CommitmentDataOracleInputs, DBOracle, MessageLoadOracleInputs } from '@aztec/acir-simulator';
import { AztecAddress, CircuitsWasm, CompleteAddress, EthAddress, Fr, PartialAddress, PrivateKey, PublicKey } from '@aztec/circuits.js';
import { AztecAddress, CircuitsWasm, CompleteAddress, EthAddress, Fr, PrivateKey, PublicKey } from '@aztec/circuits.js';
import { siloCommitment } from '@aztec/circuits.js/abis';
import { FunctionAbi } from '@aztec/foundation/abi';
import { DataCommitmentProvider, KeyStore, L1ToL2MessageProvider } from '@aztec/types';
Expand Down
14 changes: 7 additions & 7 deletions yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AztecAddress, Fr, PrivateKey } from '@aztec/circuits.js';
import { CompleteAddress, Fr, PrivateKey } from '@aztec/circuits.js';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { TestKeyStore } from '@aztec/key-store';
import { AztecNode, L2Block, MerkleTreeId } from '@aztec/types';
Expand Down Expand Up @@ -101,17 +101,17 @@ describe('Synchroniser', () => {

// Manually adding account to database so that we can call synchroniser.isAccountStateSynchronised
const keyStore = new TestKeyStore(await Grumpkin.new());
keyStore.addAccount(PrivateKey.random());
const pubKey = (await keyStore.getAccounts())[0];
const address = AztecAddress.random();
await database.addPublicKeyAndPartialAddress(address, pubKey, new Fr(0));
const privateKey = PrivateKey.random();
keyStore.addAccount(privateKey);
const completeAddress = await CompleteAddress.fromPrivateKey(privateKey);
await database.addRecipient(completeAddress);

// Add the account which will add the note processor to the synchroniser
synchroniser.addAccount(pubKey, keyStore);
synchroniser.addAccount(completeAddress.publicKey, keyStore);

await synchroniser.workNoteProcessorCatchUp();

expect(await synchroniser.isAccountStateSynchronised(address)).toBe(true);
expect(await synchroniser.isAccountStateSynchronised(completeAddress.address)).toBe(true);
});
});

Expand Down
7 changes: 3 additions & 4 deletions yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,11 @@ export class Synchroniser {
* retrieved information from contracts might be old/stale (e.g. old token balance).
*/
public async isAccountStateSynchronised(account: AztecAddress) {
const result = await this.db.getPublicKeyAndPartialAddress(account);
if (!result) {
const completeAddress = await this.db.getRecipient(account);
if (!completeAddress) {
return false;
}
const publicKey = result[0];
const processor = this.noteProcessors.find(x => x.publicKey.equals(publicKey));
const processor = this.noteProcessors.find(x => x.publicKey.equals(completeAddress.publicKey));
if (!processor) {
return false;
}
Expand Down
22 changes: 11 additions & 11 deletions yarn-project/aztec-sandbox/src/examples/private_token_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,37 +49,37 @@ async function main() {

wallet = await createAccounts(aztecRpcClient, SchnorrSingleKeyAccountContractAbi, privateKey, Fr.random(), 2);
const accounts = await aztecRpcClient.getAccounts();
const [ownerAddress, address2] = accounts;
const [owner, account2] = accounts;
logger(`Created ${accounts.length} accounts`);

logger(`Created Owner account ${ownerAddress.toString()}`);
logger(`Created Owner account ${owner.toString()}`);

const zkContract = await deployZKContract(ownerAddress);
const [balance1] = await zkContract.methods.getBalance(ownerAddress).view({ from: ownerAddress });
const zkContract = await deployZKContract(owner.address);
const [balance1] = await zkContract.methods.getBalance(owner.address).view({ from: owner.address });
logger(`Initial owner balance: ${balance1}`);

// Mint more tokens
logger(`Minting ${SECONDARY_AMOUNT} more coins`);
const mintTx = zkContract.methods.mint(SECONDARY_AMOUNT, ownerAddress).send({ origin: ownerAddress });
const mintTx = zkContract.methods.mint(SECONDARY_AMOUNT, owner.address).send({ origin: owner.address });
await mintTx.isMined({ interval: 0.5 });
const balanceAfterMint = await getBalance(zkContract, ownerAddress);
const balanceAfterMint = await getBalance(zkContract, owner.address);
logger(`Owner's balance is now: ${balanceAfterMint}`);

// Perform a transfer
logger(`Transferring ${SECONDARY_AMOUNT} tokens from owner to another account.`);
const transferTx = zkContract.methods
.transfer(SECONDARY_AMOUNT, ownerAddress, address2)
.send({ origin: ownerAddress });
.transfer(SECONDARY_AMOUNT, owner.address, account2.address)
.send({ origin: owner.address });
await transferTx.isMined({ interval: 0.5 });
const balanceAfterTransfer = await getBalance(zkContract, ownerAddress);
const receiverBalance = await getBalance(zkContract, address2);
const balanceAfterTransfer = await getBalance(zkContract, owner.address);
const receiverBalance = await getBalance(zkContract, account2.address);
logger(`Owner's balance is now ${balanceAfterTransfer}`);
logger(`The transfer receiver's balance is ${receiverBalance}`);
}

main()
.then(() => {
logger('Finished running successfuly.');
logger('Finished running successfully.');
process.exit(0);
})
.catch(err => {
Expand Down
Loading

0 comments on commit 820c72b

Please sign in to comment.