Skip to content

Commit

Permalink
refactor!: account deploy not async anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
alexghr committed Apr 4, 2024
1 parent f61f732 commit d90f2d5
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 26 deletions.
2 changes: 1 addition & 1 deletion yarn-project/accounts/src/testing/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export async function deployInitialTestAccounts(pxe: PXE) {

const sentTxs: DeploySentTx[] = [];
for (const { account } of accounts) {
const deploymentMethod = await account.getDeployMethod();
const deploymentMethod = account.getDeployMethod();

// pxe needs to prove txs one-by-one
// this is because the tx use capsules and the capsule stack is a shared resource
Expand Down
11 changes: 5 additions & 6 deletions yarn-project/accounts/src/testing/create_account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@ export async function createAccounts(pxe: PXE, numberOfAccounts = 1): Promise<Ac
// Unfortunately the function below is not stateless and we call it here because it takes a long time to run and
// the results get stored within the account object. By calling it here we increase the probability of all the
// accounts being deployed in the same block because it makes the deploy() method basically instant.
await account.getDeployMethod().then(d =>
d.prove({
contractAddressSalt: account.salt,
}),
);
const d = account.getDeployMethod();
await d.prove({
contractAddressSalt: account.salt,
});
accounts.push(account);
}

// Send them and await them to be mined
const txs = await Promise.all(accounts.map(account => account.deploy()));
const txs = accounts.map(account => account.deploy());
await Promise.all(txs.map(tx => tx.wait({ interval: 0.1 })));
return Promise.all(accounts.map(account => account.getWallet()));
}
8 changes: 7 additions & 1 deletion yarn-project/aztec.js/src/account/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type CompleteAddress } from '@aztec/circuit-types';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type NodeInfo } from '@aztec/types/interfaces';

import { type AccountInterface } from './interface.js';
import { type AccountInterface, type AuthWitnessProvider } from './interface.js';

// docs:start:account-contract-interface
/**
Expand All @@ -29,5 +29,11 @@ export interface AccountContract {
* @returns An account interface instance for creating tx requests and authorizing actions.
*/
getInterface(address: CompleteAddress, nodeInfo: NodeInfo): AccountInterface;

/**
* Returns the auth witness provider for the given address.
* @param address - Address for which to create auth witnesses.
*/
getAuthWitnessProvider(address: CompleteAddress): AuthWitnessProvider;
}
// docs:end:account-contract-interface
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type TxHash, type TxReceipt } from '@aztec/circuit-types';
import { type PXE, type TxHash, type TxReceipt } from '@aztec/circuit-types';
import { type FieldsOf } from '@aztec/foundation/types';

import { type Wallet } from '../account/index.js';
Expand All @@ -15,8 +15,8 @@ export type DeployAccountTxReceipt = FieldsOf<TxReceipt> & {
* A deployment transaction for an account contract sent to the network, extending SentTx with methods to get the resulting wallet.
*/
export class DeployAccountSentTx extends SentTx {
constructor(private wallet: Wallet, txHashPromise: Promise<TxHash>) {
super(wallet, txHashPromise);
constructor(pxe: PXE, txHashPromise: Promise<TxHash>, private getWalletPromise: Promise<Wallet>) {
super(pxe, txHashPromise);
}

/**
Expand All @@ -36,7 +36,8 @@ export class DeployAccountSentTx extends SentTx {
*/
public async wait(opts: WaitOpts = DefaultWaitOpts): Promise<DeployAccountTxReceipt> {
const receipt = await super.wait(opts);
await waitForAccountSynch(this.pxe, this.wallet.getCompleteAddress(), opts);
return { ...receipt, wallet: this.wallet };
const wallet = await this.getWalletPromise;
await waitForAccountSynch(this.pxe, wallet.getCompleteAddress(), opts);
return { ...receipt, wallet };
}
}
15 changes: 7 additions & 8 deletions yarn-project/aztec.js/src/account_manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,25 +119,25 @@ export class AccountManager {
* grained control on when to create, simulate, and send the deployment tx.
* @returns A DeployMethod instance that deploys this account contract.
*/
public async getDeployMethod() {
public getDeployMethod() {
if (!this.deployMethod) {
if (!this.isDeployable()) {
throw new Error(
`Account contract ${this.accountContract.getContractArtifact().name} does not require deployment.`,
);
}
await this.#register();
const encryptionPublicKey = this.getEncryptionPublicKey();
// We use a signerless wallet so we hit the account contract directly and it deploys itself.
// If we used getWallet, the deployment would get routed via the account contract entrypoint
// instead of directly hitting the initializer.
const args = this.accountContract.getDeploymentArgs() ?? [];
this.deployMethod = new DeployAccountMethod(
this.pxe,
await this.getAccount(),
this.accountContract.getAuthWitnessProvider(this.getCompleteAddress()),
encryptionPublicKey,
this.accountContract.getContractArtifact(),
args,
() => this.#register(),
);
}
return this.deployMethod;
Expand All @@ -151,14 +151,13 @@ export class AccountManager {
* @param fee - Fee to be paid for the deployment.
* @returns A SentTx object that can be waited to get the associated Wallet.
*/
public async deploy(fee?: FeeOptions): Promise<DeployAccountSentTx> {
const deployMethod = await this.getDeployMethod();
const wallet = await this.getWallet();
public deploy(fee?: FeeOptions): DeployAccountSentTx {
const deployMethod = this.getDeployMethod();
const sentTx = deployMethod.send({
contractAddressSalt: this.salt,
fee,
});
return new DeployAccountSentTx(wallet, sentTx.getTxHash());
return new DeployAccountSentTx(this.pxe, sentTx.getTxHash(), this.getWallet());
}

/**
Expand All @@ -169,7 +168,7 @@ export class AccountManager {
* @returns A Wallet instance.
*/
public async waitSetup(opts: WaitOpts = DefaultWaitOpts): Promise<AccountWalletWithPrivateKey> {
await (this.isDeployable() ? this.deploy().then(tx => tx.wait(opts)) : this.register());
await (this.isDeployable() ? this.deploy().wait(opts) : this.register());
return this.getWallet();
}

Expand Down
3 changes: 3 additions & 0 deletions yarn-project/aztec.js/src/contract/deploy_account_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class DeployAccountMethod<TContract extends ContractBase = Contract> exte
private publicKey: PublicKey,
private artifact: ContractArtifact,
private args: any[] = [],
private registerFn: () => Promise<void>,
initializerNameOrArtifact?: string | FunctionArtifact,
) {
super(pxe);
Expand All @@ -63,6 +64,8 @@ export class DeployAccountMethod<TContract extends ContractBase = Contract> exte
throw new Error('Account contract can not be initialized without an initializer');
}

await this.registerFn();

const feePayload = await EntrypointPayload.fromFeeOptions(options.fee);
const feeAuthWit = await this.authWitnessProvider.createAuthWit(feePayload.hash());
await this.pxe.addCapsule(feePayload.toFields());
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/cli/src/cmds/create_account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function createAccount(

const account = getSchnorrAccount(client, actualPrivateKey, actualPrivateKey, Fr.ZERO);
const { address, publicKey, partialAddress } = account.getCompleteAddress();
const tx = await account.deploy();
const tx = account.deploy();
const txHash = await tx.getTxHash();
debugLogger(`Account contract tx sent with hash ${txHash}`);
if (wait) {
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/end-to-end/src/e2e_fees.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -680,12 +680,12 @@ describe('e2e_fees', () => {
});

it('pays fee natively', async () => {
await (
await accountManager.deploy({
await accountManager
.deploy({
maxFee,
paymentMethod: await NativeFeePaymentMethod.create(await accountManager.getWallet()),
})
).wait();
.wait();

await expect(gasBalances(accountManager.getCompleteAddress().address, sequencerAddress)).resolves.toEqual([
initialGas - actualFee,
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_p2p_network.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ describe('e2e_p2p_network', () => {
const submitTxsTo = async (pxe: PXEService, account: AztecAddress, numTxs: number) => {
const txs: SentTx[] = [];
for (let i = 0; i < numTxs; i++) {
const tx = await getSchnorrAccount(pxe, GrumpkinScalar.random(), GrumpkinScalar.random(), Fr.random()).deploy();
const tx = getSchnorrAccount(pxe, GrumpkinScalar.random(), GrumpkinScalar.random(), Fr.random()).deploy();
logger(`Tx sent with hash ${await tx.getTxHash()}`);
const receipt = await tx.getReceipt();
expect(receipt).toEqual(
Expand Down

0 comments on commit d90f2d5

Please sign in to comment.