Skip to content

Commit

Permalink
chore: Lazy loading artifacts everywhere (#12285)
Browse files Browse the repository at this point in the history
This PR adds the *option* to lazily load JSON artifacts in all the
packages that were missing that functionality, further improving bundle
sizes for the browser and allowing us to finally put limits on our
example apps bundle sizes:

* `noir-protocol-circuits-types/vks`: now allow vk lazy imports via the
`LazyArtifactProvider` in the `/client` export, while maintaining the
bundled version for the server under `/server/vks`
* `accounts`: Now all exports provide a lazy version, e.g:
`@aztec/accounts/schnorr/lazy`. This has proven to be complicated due to
the testing import leaking into the browser (where type assertions are
not widely supported). Now there's also `/testing/lazy`. This testing
package is needed in the browser for the prefunded accounts.
* `protocol-contracts`: Now with a lazy version and exporting
`ProtocolContractProviders` so that PXE can be configured with bundled
and lazy versions.


Besides the type assertion issue, we absolutely want to keep bundled and
lazy versions because some environments don't play well with `await
import` (namely service workers in firefox)

---------

Co-authored-by: esau <152162806+sklppy88@users.noreply.github.com>
  • Loading branch information
Thunkar and sklppy88 authored Feb 26, 2025
1 parent 894273f commit 3cb6920
Show file tree
Hide file tree
Showing 98 changed files with 1,130 additions and 369 deletions.
2 changes: 1 addition & 1 deletion boxes/boxes/react/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createPXEClient, PXE } from '@aztec/aztec.js';
import { BoxReactContractArtifact } from '../artifacts/BoxReact';
import { getDeployedTestAccountsWallets } from '@aztec/accounts/testing';
import { getDeployedTestAccountsWallets } from '@aztec/accounts/testing/lazy';

export class PrivateEnv {
private constructor(private pxe: PXE) {}
Expand Down
2 changes: 1 addition & 1 deletion boxes/boxes/vanilla/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Fr, Wallet, createPXEClient } from '@aztec/aztec.js';

import { getDeployedTestAccountsWallets } from '@aztec/accounts/testing';
import { getDeployedTestAccountsWallets } from '@aztec/accounts/testing/lazy';
import { VanillaContract } from '../artifacts/Vanilla';

const pxe = createPXEClient(process.env.PXE_URL || 'http://localhost:8080');
Expand Down
1 change: 1 addition & 0 deletions boxes/boxes/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@aztec/bb-prover": "latest",
"@aztec/key-store": "latest",
"@aztec/kv-store": "latest",
"@aztec/protocol-contracts": "latest",
"@aztec/pxe": "latest",
"@aztec/simulator": "latest",
"@aztec/stdlib": "latest",
Expand Down
18 changes: 11 additions & 7 deletions boxes/boxes/vite/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getInitialTestAccounts } from "@aztec/accounts/testing";
import { getSchnorrAccount } from "@aztec/accounts/schnorr";
import { getInitialTestAccounts } from "@aztec/accounts/testing/lazy";
import { getSchnorrAccount } from "@aztec/accounts/schnorr/lazy";
import {
AccountWalletWithSecretKey,
createAztecNodeClient,
Expand All @@ -14,6 +14,7 @@ import { KVPxeDatabase } from "@aztec/pxe/database";
import { PXEService } from "@aztec/pxe/service";
import { WASMSimulator } from "@aztec/simulator/client";
import { BoxReactContractArtifact } from "../artifacts/BoxReact";
import { LazyProtocolContractsProvider } from "@aztec/protocol-contracts/providers/lazy";

export class PrivateEnv {
pxe: PXEService;
Expand All @@ -30,7 +31,7 @@ export class PrivateEnv {
const simulationProvider = new WASMSimulator();
const proofCreator = new BBWASMLazyPrivateKernelProver(
simulationProvider,
16,
16
);
const l1Contracts = await aztecNode.getL1ContractAddresses();
const configWithContracts = {
Expand All @@ -41,30 +42,33 @@ export class PrivateEnv {
const store = await createStore(
"pxe_data",
configWithContracts,
createLogger("pxe:data:idb"),
createLogger("pxe:data:idb")
);

const keyStore = new KeyStore(store);

const db = await KVPxeDatabase.create(store);
const tips = new L2TipsStore(store, "pxe");

const protocolContractsProvider = new LazyProtocolContractsProvider();

this.pxe = new PXEService(
keyStore,
aztecNode,
db,
tips,
proofCreator,
simulationProvider,
config,
protocolContractsProvider,
config
);
await this.pxe.init();
const [accountData] = await getInitialTestAccounts();
const account = await getSchnorrAccount(
this.pxe,
accountData.secret,
accountData.signingKey,
accountData.salt,
accountData.salt
);
await account.register();
this.wallet = await account.getWallet();
Expand All @@ -79,5 +83,5 @@ export const deployerEnv = new PrivateEnv();

const IGNORE_FUNCTIONS = ["constructor", "process_log", "sync_notes"];
export const filteredInterface = BoxReactContractArtifact.functions.filter(
(f) => !IGNORE_FUNCTIONS.includes(f.name),
(f) => !IGNORE_FUNCTIONS.includes(f.name)
);
7 changes: 7 additions & 0 deletions boxes/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ __metadata:
languageName: node
linkType: soft

"@aztec/protocol-contracts@link:../yarn-project/protocol-contracts::locator=aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/protocol-contracts@link:../yarn-project/protocol-contracts::locator=aztec-app%40workspace%3A."
languageName: node
linkType: soft

"@aztec/pxe@link:../yarn-project/pxe::locator=aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/pxe@link:../yarn-project/pxe::locator=aztec-app%40workspace%3A."
Expand Down Expand Up @@ -141,6 +147,7 @@ __metadata:
"@aztec/bb-prover": "npm:latest"
"@aztec/key-store": "npm:latest"
"@aztec/kv-store": "npm:latest"
"@aztec/protocol-contracts": "npm:latest"
"@aztec/pxe": "npm:latest"
"@aztec/simulator": "npm:latest"
"@aztec/stdlib": "npm:latest"
Expand Down
1 change: 1 addition & 0 deletions playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@aztec/foundation": "link:../yarn-project/foundation",
"@aztec/key-store": "link:../yarn-project/key-store",
"@aztec/kv-store": "link:../yarn-project/kv-store",
"@aztec/protocol-contracts": "link:../yarn-project/protocol-contracts",
"@aztec/pxe": "link:../yarn-project/pxe",
"@aztec/simulator": "link:../yarn-project/simulator",
"@aztec/stdlib": "link:../yarn-project/stdlib",
Expand Down
4 changes: 4 additions & 0 deletions playground/src/aztecEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { createContext } from "react";
import { NetworkDB, WalletDB } from "./utils/storage";
import { type ContractFunctionInteractionTx } from "./utils/txs";
import { type Logger, createLogger } from "@aztec/aztec.js/log";
import { LazyProtocolContractsProvider } from "@aztec/protocol-contracts/providers/lazy";

process.env = Object.keys(import.meta.env).reduce((acc, key) => {
acc[key.replace("VITE_", "")] = import.meta.env[key];
Expand Down Expand Up @@ -192,13 +193,16 @@ export class AztecEnv {
const db = await KVPxeDatabase.create(store);
const tips = new L2TipsStore(store, "pxe");

const protocolContractsProvider = new LazyProtocolContractsProvider();

const pxe = new PXEService(
keyStore,
aztecNode,
db,
tips,
proofCreator,
simulationProvider,
protocolContractsProvider,
config,
WebLogger.getInstance().createLogger("pxe:service")
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import DialogTitle from "@mui/material/DialogTitle";
import Dialog from "@mui/material/Dialog";
import { AccountWalletWithSecretKey, Fr } from "@aztec/aztec.js";
import { getSchnorrAccount } from "@aztec/accounts/schnorr";
import { getSchnorrAccount } from "@aztec/accounts/schnorr/lazy";
import {
Button,
CircularProgress,
Expand Down
4 changes: 2 additions & 2 deletions playground/src/components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import {
AztecAddress,
AccountManager,
} from "@aztec/aztec.js";
import { getInitialTestAccounts } from "@aztec/accounts/testing";
import { getInitialTestAccounts } from "@aztec/accounts/testing/lazy";
import { NetworkDB, WalletDB } from "../../utils/storage";
import { useContext, useEffect, useState } from "react";
import { CreateAccountDialog } from "./components/createAccountDialog";
import { getSchnorrAccount } from "@aztec/accounts/schnorr";
import { getSchnorrAccount } from "@aztec/accounts/schnorr/lazy";
import AddIcon from "@mui/icons-material/Add";
import { Button, Divider, Typography } from "@mui/material";
import {
Expand Down
7 changes: 7 additions & 0 deletions playground/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ __metadata:
languageName: node
linkType: soft

"@aztec/protocol-contracts@link:../yarn-project/protocol-contracts::locator=playground%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/protocol-contracts@link:../yarn-project/protocol-contracts::locator=playground%40workspace%3A."
languageName: node
linkType: soft

"@aztec/pxe@link:../yarn-project/pxe::locator=playground%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/pxe@link:../yarn-project/pxe::locator=playground%40workspace%3A."
Expand Down Expand Up @@ -3750,6 +3756,7 @@ __metadata:
"@aztec/foundation": "link:../yarn-project/foundation"
"@aztec/key-store": "link:../yarn-project/key-store"
"@aztec/kv-store": "link:../yarn-project/kv-store"
"@aztec/protocol-contracts": "link:../yarn-project/protocol-contracts"
"@aztec/pxe": "link:../yarn-project/pxe"
"@aztec/simulator": "link:../yarn-project/simulator"
"@aztec/stdlib": "link:../yarn-project/stdlib"
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/accounts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
"./dapp": "./dest/dapp/index.js",
"./defaults": "./dest/defaults/index.js",
"./ecdsa": "./dest/ecdsa/index.js",
"./ecdsa/lazy": "./dest/ecdsa/lazy.js",
"./schnorr": "./dest/schnorr/index.js",
"./schnorr/lazy": "./dest/schnorr/lazy.js",
"./single_key": "./dest/single_key/index.js",
"./single_key/lazy": "./dest/single_key/lazy.js",
"./testing": "./dest/testing/index.js",
"./testing/lazy": "./dest/testing/lazy.js",
"./utils": "./dest/utils/index.js"
},
"typedocOptions": {
Expand Down
7 changes: 2 additions & 5 deletions yarn-project/accounts/src/defaults/account_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ import { DefaultAccountInterface } from '../defaults/account_interface.js';
export abstract class DefaultAccountContract implements AccountContract {
abstract getAuthWitnessProvider(address: CompleteAddress): AuthWitnessProvider;
abstract getDeploymentArgs(): Promise<any[] | undefined>;
abstract getContractArtifact(): Promise<ContractArtifact>;

constructor(private artifact: ContractArtifact) {}

getContractArtifact(): ContractArtifact {
return this.artifact;
}
constructor() {}

getInterface(address: CompleteAddress, nodeInfo: NodeInfo): AccountInterface {
return new DefaultAccountInterface(this.getAuthWitnessProvider(address), address, nodeInfo);
Expand Down
6 changes: 4 additions & 2 deletions yarn-project/accounts/src/defaults/account_interface.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { AztecAddress, NodeInfo } from '@aztec/aztec.js';
import { type AccountInterface, type AuthWitnessProvider, CompleteAddress } from '@aztec/aztec.js/account';
import type { AccountInterface, AuthWitnessProvider } from '@aztec/aztec.js/account';
import type { EntrypointInterface, ExecutionRequestInit } from '@aztec/aztec.js/entrypoint';
import { DefaultAccountEntrypoint } from '@aztec/entrypoints/account';
import { Fr } from '@aztec/foundation/fields';
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
import { CompleteAddress } from '@aztec/stdlib/contract';
import type { NodeInfo } from '@aztec/stdlib/contract';
import type { TxExecutionRequest } from '@aztec/stdlib/tx';

/**
Expand Down
8 changes: 4 additions & 4 deletions yarn-project/accounts/src/ecdsa/ecdsa_k/account_contract.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type { AuthWitnessProvider } from '@aztec/aztec.js/account';
import { Ecdsa } from '@aztec/foundation/crypto';
import type { Fr } from '@aztec/foundation/fields';
import type { ContractArtifact } from '@aztec/stdlib/abi';
import { AuthWitness } from '@aztec/stdlib/auth-witness';
import { CompleteAddress } from '@aztec/stdlib/contract';

import { DefaultAccountContract } from '../../defaults/account_contract.js';
import { EcdsaKAccountContractArtifact } from './artifact.js';

/**
* Account contract that authenticates transactions using ECDSA signatures
* verified against a secp256k1 public key stored in an immutable encrypted note.
* This abstract version does not provide a way to retrieve the artifact, as it
* can be implemented with or without lazy loading.
*/
export class EcdsaKAccountContract extends DefaultAccountContract {
export abstract class EcdsaKBaseAccountContract extends DefaultAccountContract {
constructor(private signingPrivateKey: Buffer) {
super(EcdsaKAccountContractArtifact as ContractArtifact);
super();
}

async getDeploymentArgs() {
Expand Down
7 changes: 0 additions & 7 deletions yarn-project/accounts/src/ecdsa/ecdsa_k/artifact.ts

This file was deleted.

28 changes: 24 additions & 4 deletions yarn-project/accounts/src/ecdsa/ecdsa_k/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,36 @@
*
* @packageDocumentation
*/
import type { AztecAddress, Fr } from '@aztec/aztec.js';
import { AccountManager, type Salt } from '@aztec/aztec.js/account';
import { type AccountWallet, getWallet } from '@aztec/aztec.js/wallet';
import { Fr } from '@aztec/foundation/fields';
import type { ContractArtifact } from '@aztec/stdlib/abi';
import { loadContractArtifact } from '@aztec/stdlib/abi';
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { PXE } from '@aztec/stdlib/interfaces/client';
import type { NoirCompiledContract } from '@aztec/stdlib/noir';

import { EcdsaKAccountContract } from './account_contract.js';
import EcdsaKAccountContractJson from '../../../artifacts/EcdsaKAccount.json' assert { type: 'json' };
import { EcdsaKBaseAccountContract } from './account_contract.js';

export { EcdsaKAccountContractArtifact } from './artifact.js';
export { EcdsaKAccountContract };
export const EcdsaKAccountContractArtifact: ContractArtifact = loadContractArtifact(
EcdsaKAccountContractJson as NoirCompiledContract,
);

/**
* Account contract that authenticates transactions using ECDSA signatures
* verified against a secp256k1 public key stored in an immutable encrypted note.
* Eagerly loads the contract artifact
*/
export class EcdsaKAccountContract extends EcdsaKBaseAccountContract {
constructor(signingPrivateKey: Buffer) {
super(signingPrivateKey);
}

override getContractArtifact(): Promise<ContractArtifact> {
return Promise.resolve(EcdsaKAccountContractArtifact);
}
}
/**
* Creates an Account that relies on an ECDSA signing key for authentication.
* @param pxe - An PXE server instance.
Expand Down
66 changes: 66 additions & 0 deletions yarn-project/accounts/src/ecdsa/ecdsa_k/lazy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* The `@aztec/accounts/ecdsa` export provides an ECDSA account contract implementation, that uses an ECDSA private key for authentication, and a Grumpkin key for encryption.
* Consider using this account type when working with integrations with Ethereum wallets.
*
* @packageDocumentation
*/
import { AccountManager, type Salt } from '@aztec/aztec.js/account';
import { type AccountWallet, getWallet } from '@aztec/aztec.js/wallet';
import { Fr } from '@aztec/foundation/fields';
import type { ContractArtifact } from '@aztec/stdlib/abi';
import { loadContractArtifact } from '@aztec/stdlib/abi';
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { PXE } from '@aztec/stdlib/interfaces/client';

import { EcdsaKBaseAccountContract } from './account_contract.js';

/**
* Lazily loads the contract artifact
* @returns The contract artifact for the ecdsa K account contract
*/
export async function getEcdsaKAccountContractArtifact() {
const { default: ecdsaKAccountContractJson } = await import('../../../artifacts/EcdsaKAccount.json');
return loadContractArtifact(ecdsaKAccountContractJson);
}

/**
* Account contract that authenticates transactions using ECDSA signatures
* verified against a secp256k1 public key stored in an immutable encrypted note.
* Lazily loads the contract artifact
*/
export class EcdsaKAccountContract extends EcdsaKBaseAccountContract {
constructor(signingPrivateKey: Buffer) {
super(signingPrivateKey);
}

override getContractArtifact(): Promise<ContractArtifact> {
return getEcdsaKAccountContractArtifact();
}
}
/**
* Creates an Account that relies on an ECDSA signing key for authentication.
* @param pxe - An PXE server instance.
* @param secretKey - Secret key used to derive all the keystore keys.
* @param signingPrivateKey - Secp256k1 key used for signing transactions.
* @param salt - Deployment salt.
* @returns An account manager initialized with the account contract and its deployment params
*/
export function getEcdsaKAccount(
pxe: PXE,
secretKey: Fr,
signingPrivateKey: Buffer,
salt?: Salt,
): Promise<AccountManager> {
return AccountManager.create(pxe, secretKey, new EcdsaKAccountContract(signingPrivateKey), salt);
}

/**
* Gets a wallet for an already registered account using ECDSA signatures.
* @param pxe - An PXE server instance.
* @param address - Address for the account.
* @param signingPrivateKey - ECDSA key used for signing transactions.
* @returns A wallet for this account that can be used to interact with a contract instance.
*/
export function getEcdsaKWallet(pxe: PXE, address: AztecAddress, signingPrivateKey: Buffer): Promise<AccountWallet> {
return getWallet(pxe, address, new EcdsaKAccountContract(signingPrivateKey));
}
2 changes: 2 additions & 0 deletions yarn-project/accounts/src/ecdsa/lazy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ecdsa_k/lazy.js';
export * from './ssh_ecdsa_r/lazy.js';
Loading

1 comment on commit 3cb6920

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'P2P Testbench'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 3cb6920 Previous: 894273f Ratio
normal-degree-50-nodes - minDelay 206 ms 123 ms 1.67

This comment was automatically generated by workflow using github-action-benchmark.

CC: @Maddiaa0

Please sign in to comment.