diff --git a/aztec-up/bin/docker-compose.sandbox.yml b/aztec-up/bin/docker-compose.sandbox.yml index 186ba3dec69..999aa567685 100644 --- a/aztec-up/bin/docker-compose.sandbox.yml +++ b/aztec-up/bin/docker-compose.sandbox.yml @@ -28,7 +28,6 @@ services: P2P_BLOCK_CHECK_INTERVAL_MS: 50 SEQ_TX_POLLING_INTERVAL_MS: 50 WS_BLOCK_CHECK_INTERVAL_MS: 50 - PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 PXE_PORT: ${PXE_PORT:-8080} PORT: ${AZTEC_NODE_PORT:-8080} diff --git a/boxes/boxes/vite/src/config.ts b/boxes/boxes/vite/src/config.ts index e17120a3fc5..bced26cc094 100644 --- a/boxes/boxes/vite/src/config.ts +++ b/boxes/boxes/vite/src/config.ts @@ -24,7 +24,10 @@ export class PrivateEnv { accountContract; account: AccountManager; - constructor(private secretKey: Fr, private nodeURL: string) {} + constructor( + private secretKey: Fr, + private nodeURL: string, + ) {} async init() { const config = getPXEServiceConfig(); @@ -33,20 +36,20 @@ export class PrivateEnv { const proofCreator = new TestPrivateKernelProver(); this.pxe = await this.createPXEService(aztecNode, config, proofCreator); const encryptionPrivateKey = deriveMasterIncomingViewingSecretKey( - this.secretKey + this.secretKey, ); this.accountContract = new SingleKeyAccountContract(encryptionPrivateKey); this.account = new AccountManager( this.pxe, this.secretKey, - this.accountContract + this.accountContract, ); } async createPXEService( aztecNode: AztecNode, config: PXEServiceConfig, - proofCreator?: PrivateKernelProver + proofCreator?: PrivateKernelProver, ) { const l1Contracts = await aztecNode.getL1ContractAddresses(); const configWithContracts = { @@ -57,7 +60,7 @@ export class PrivateEnv { const store = await createStore( "pxe_data", configWithContracts, - createLogger("pxe:data:indexeddb") + createLogger("pxe:data:indexeddb"), ); const keyStore = new KeyStore(store); @@ -65,16 +68,16 @@ export class PrivateEnv { const db = await KVPxeDatabase.create(store); const tips = new L2TipsStore(store, "pxe"); - const server = new PXEService( + const pxe = new PXEService( keyStore, aztecNode, db, tips, proofCreator, - config + config, ); - await server.start(); - return server; + await pxe.init(); + return pxe; } async getWallet() { @@ -85,7 +88,7 @@ export class PrivateEnv { export const deployerEnv = new PrivateEnv( SECRET_KEY, - process.env.PXE_URL || "http://localhost:8080" + process.env.PXE_URL || "http://localhost:8080", ); const IGNORE_FUNCTIONS = [ @@ -94,5 +97,5 @@ const IGNORE_FUNCTIONS = [ "sync_notes", ]; export const filteredInterface = BoxReactContractArtifact.functions.filter( - (f) => !IGNORE_FUNCTIONS.includes(f.name) + (f) => !IGNORE_FUNCTIONS.includes(f.name), ); diff --git a/boxes/docker-compose.yml b/boxes/docker-compose.yml index b06cca7ebc8..a19c72fbc17 100644 --- a/boxes/docker-compose.yml +++ b/boxes/docker-compose.yml @@ -17,7 +17,6 @@ services: P2P_BLOCK_CHECK_INTERVAL_MS: 50 SEQ_TX_POLLING_INTERVAL_MS: 50 WS_BLOCK_CHECK_INTERVAL_MS: 50 - PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 depends_on: - ethereum diff --git a/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md b/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md index ce0f32341b5..d00ef025751 100644 --- a/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md +++ b/docs/docs/reference/developer_references/sandbox_reference/sandbox-reference.md @@ -37,7 +37,6 @@ ARCHIVER_POLLING_INTERVAL_MS=50 P2P_BLOCK_CHECK_INTERVAL_MS=50 SEQ_TX_POLLING_INTERVAL_MS=50 WS_BLOCK_CHECK_INTERVAL_MS=50 -PXE_BLOCK_POLLING_INTERVAL_MS=50 ARCHIVER_VIEM_POLLING_INTERVAL_MS=500 ``` @@ -90,7 +89,6 @@ Variables like `TEST_ACCOUNTS` & `PXE_PORT` are valid here as described above. AZTEC_NODE_URL='http://localhost:8079' # The address of an Aztec Node URL that the PXE will connect to (default: http://localhost:8079) PXE_PORT=8080 # The port that the PXE will be listening to (default: 8080) TEST_ACCOUNTS='true' # Option to deploy 3 test account when sandbox starts. (default: true) -PXE_BLOCK_POLLING_INTERVAL_MS=50 # Interval to check for new L2 blocks. (default: 50) PXE_L2_STARTING_BLOCK=1 # L2 Block to start synching the PXE from (default: 1) ``` diff --git a/spartan/aztec-network/templates/pxe.yaml b/spartan/aztec-network/templates/pxe.yaml index b4ba7d10c12..e91bbd2a10a 100644 --- a/spartan/aztec-network/templates/pxe.yaml +++ b/spartan/aztec-network/templates/pxe.yaml @@ -108,8 +108,8 @@ spec: - -c - | curl -s -X POST -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"pxe_isGlobalStateSynchronized","params":[],"id":67}' \ - 127.0.0.1:{{ .Values.pxe.service.nodePort }} | grep -q '"result":true' + -d '{"jsonrpc":"2.0","method":"pxe_getNodeInfo","params":[],"id":67}' \ + 127.0.0.1:{{ .Values.pxe.service.nodePort }} | grep -q '"protocolVersion":1' initialDelaySeconds: {{ .Values.pxe.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.pxe.readinessProbe.periodSeconds }} timeoutSeconds: {{ .Values.pxe.readinessProbe.timeoutSeconds }} diff --git a/yarn-project/aztec.js/src/contract/sent_tx.test.ts b/yarn-project/aztec.js/src/contract/sent_tx.test.ts index c2bf65adb6a..c0f7daf8a57 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.test.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.test.ts @@ -23,22 +23,8 @@ describe('SentTx', () => { pxe.getTxReceipt.mockResolvedValue(txReceipt); }); - it('waits for all notes of the accounts to be available', async () => { - pxe.getSyncStatus.mockResolvedValueOnce({ blocks: 25 }).mockResolvedValueOnce({ blocks: 25 }); - - const actual = await sentTx.wait({ timeout: 1, interval: 0.4 }); - expect(actual).toEqual(txReceipt); - }); - - it('does not wait for notes sync', async () => { - pxe.getSyncStatus.mockResolvedValue({ blocks: 19 }); - const actual = await sentTx.wait({ timeout: 1, interval: 0.4, waitForNotesAvailable: false }); - expect(actual).toEqual(txReceipt); - }); - it('throws if tx is dropped', async () => { pxe.getTxReceipt.mockResolvedValue({ ...txReceipt, status: TxStatus.DROPPED } as TxReceipt); - pxe.getSyncStatus.mockResolvedValue({ blocks: 19 }); await expect(sentTx.wait({ timeout: 1, interval: 0.4, ignoreDroppedReceiptsFor: 0 })).rejects.toThrow(/dropped/); }); diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index b7803975b16..99c4eec8650 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -14,11 +14,6 @@ export type WaitOpts = { interval?: number; /** Whether to wait for the tx to be proven. */ proven?: boolean; - /** - * Whether to wait for the node to notify that the block in which this tx was mined is available to fetch notes from. - * If false, then any queries that depend on state set by this transaction may return stale data. Defaults to true. - **/ - waitForNotesAvailable?: boolean; /** Whether to include information useful for debugging/testing in the receipt. */ debug?: boolean; /** Whether to accept a revert as a status code for the tx when waiting for it. If false, will throw if the tx reverts. */ @@ -31,7 +26,6 @@ export const DefaultWaitOpts: WaitOpts = { provenTimeout: 600, interval: 1, debug: false, - waitForNotesAvailable: true, }; /** @@ -124,16 +118,7 @@ export class SentTx { } return undefined; } - // If we don't care about waiting for notes to be synced, return the receipt - const waitForNotesAvailable = opts?.waitForNotesAvailable ?? DefaultWaitOpts.waitForNotesAvailable; - if (!waitForNotesAvailable) { - return txReceipt; - } - // Check if all sync blocks on the PXE Service are greater or equal than the block in which the tx was mined - const { blocks } = await this.pxe.getSyncStatus(); - const targetBlock = txReceipt.blockNumber!; - const areNotesAvailable = blocks >= targetBlock; - return areNotesAvailable ? txReceipt : undefined; + return txReceipt; }, 'isMined', opts?.timeout ?? DefaultWaitOpts.timeout, diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 4c42ac375de..c4a15950273 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -149,7 +149,6 @@ export { type PXE, type PartialAddress, type PublicKey, - type SyncStatus, } from '@aztec/circuit-types'; // TODO: These kinds of things have no place on our public api. diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 35694b490f5..e455ee4c0be 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -10,7 +10,6 @@ import { type PXEInfo, type PrivateExecutionResult, type SiblingPath, - type SyncStatus, type Tx, type TxExecutionRequest, type TxHash, @@ -170,12 +169,6 @@ export abstract class BaseWallet implements Wallet { getNodeInfo(): Promise { return this.pxe.getNodeInfo(); } - isGlobalStateSynchronized() { - return this.pxe.isGlobalStateSynchronized(); - } - getSyncStatus(): Promise { - return this.pxe.getSyncStatus(); - } addAuthWitness(authWitness: AuthWitness) { return this.pxe.addAuthWitness(authWitness); } diff --git a/yarn-project/aztec/docker-compose.yml b/yarn-project/aztec/docker-compose.yml index 3fe35cd42f8..7d158f93f30 100644 --- a/yarn-project/aztec/docker-compose.yml +++ b/yarn-project/aztec/docker-compose.yml @@ -29,7 +29,6 @@ services: P2P_BLOCK_CHECK_INTERVAL_MS: 50 SEQ_TX_POLLING_INTERVAL_MS: 50 WS_BLOCK_CHECK_INTERVAL_MS: 50 - PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 volumes: - ./log:/usr/src/yarn-project/aztec/log:rw diff --git a/yarn-project/aztec/src/cli/cmds/start_pxe.ts b/yarn-project/aztec/src/cli/cmds/start_pxe.ts index f1d8681982c..55bea808d2d 100644 --- a/yarn-project/aztec/src/cli/cmds/start_pxe.ts +++ b/yarn-project/aztec/src/cli/cmds/start_pxe.ts @@ -117,8 +117,5 @@ export async function addPXE( // Add PXE to services list services.pxe = [pxe, PXESchema]; - // Add PXE stop function to signal handlers - signalHandlers.push(pxe.stop); - return pxe; } diff --git a/yarn-project/aztec/src/sandbox.ts b/yarn-project/aztec/src/sandbox.ts index 0545db16714..d720894da3a 100644 --- a/yarn-project/aztec/src/sandbox.ts +++ b/yarn-project/aztec/src/sandbox.ts @@ -157,7 +157,6 @@ export async function createSandbox(config: Partial = {}) { } const stop = async () => { - await pxe.stop(); await node.stop(); await watcher?.stop(); }; diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts index aac66847624..03098a3095c 100644 --- a/yarn-project/bot/src/factory.ts +++ b/yarn-project/bot/src/factory.ts @@ -6,7 +6,6 @@ import { type DeployOptions, createLogger, createPXEClient, - retryUntil, } from '@aztec/aztec.js'; import { type AztecNode, type FunctionCall, type PXE } from '@aztec/circuit-types'; import { Fr, deriveSigningKey } from '@aztec/circuits.js'; @@ -67,16 +66,6 @@ export class BotFactory { if (isInit) { this.log.info(`Account at ${account.getAddress().toString()} already initialized`); const wallet = await account.register(); - const blockNumber = await this.pxe.getBlockNumber(); - await retryUntil( - async () => { - const status = await this.pxe.getSyncStatus(); - return blockNumber <= status.blocks; - }, - 'pxe synch', - 3600, - 1, - ); return wallet; } else { this.log.info(`Initializing account at ${account.getAddress().toString()}`); diff --git a/yarn-project/circuit-types/src/interfaces/index.ts b/yarn-project/circuit-types/src/interfaces/index.ts index 3f05c960e1b..2b880ad7550 100644 --- a/yarn-project/circuit-types/src/interfaces/index.ts +++ b/yarn-project/circuit-types/src/interfaces/index.ts @@ -18,7 +18,6 @@ export * from './proving-job.js'; export * from './pxe.js'; export * from './server_circuit_prover.js'; export * from './service.js'; -export * from './sync-status.js'; export * from './world_state.js'; export * from './prover-broker.js'; export * from './p2p.js'; diff --git a/yarn-project/circuit-types/src/interfaces/pxe.test.ts b/yarn-project/circuit-types/src/interfaces/pxe.test.ts index 8530f731bd1..9bf3ca99f59 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.test.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.test.ts @@ -43,7 +43,6 @@ import { Tx, TxHash, TxProvingResult, TxReceipt, TxSimulationResult } from '../t import { TxEffect } from '../tx_effect.js'; import { TxExecutionRequest } from '../tx_execution_request.js'; import { type EventMetadataDefinition, type PXE, type PXEInfo, PXESchema } from './pxe.js'; -import { type SyncStatus } from './sync-status.js'; jest.setTimeout(12_000); @@ -258,16 +257,6 @@ describe('PXESchema', () => { expect(result).toEqual(await handler.getPXEInfo()); }); - it('isGlobalStateSynchronized', async () => { - const result = await context.client.isGlobalStateSynchronized(); - expect(result).toBe(true); - }); - - it('getSyncStatus', async () => { - const result = await context.client.getSyncStatus(); - expect(result).toEqual(await handler.getSyncStatus()); - }); - it('getContractInstance', async () => { const result = await context.client.getContractInstance(address); expect(result).toEqual(instance); @@ -502,14 +491,6 @@ class MockPXE implements PXE { pxeVersion: '1.0', }); } - isGlobalStateSynchronized(): Promise { - return Promise.resolve(true); - } - getSyncStatus(): Promise { - return Promise.resolve({ - blocks: 1, - }); - } getContractInstance(address: AztecAddress): Promise { expect(address).toEqual(this.address); return Promise.resolve(this.instance); diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 363511bad80..62c99eb84ba 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -43,7 +43,6 @@ import { SiblingPath } from '../sibling_path/sibling_path.js'; import { Tx, TxHash, TxProvingResult, TxReceipt, TxSimulationResult } from '../tx/index.js'; import { TxEffect } from '../tx_effect.js'; import { TxExecutionRequest } from '../tx_execution_request.js'; -import { type SyncStatus, SyncStatusSchema } from './sync-status.js'; // docs:start:pxe-interface /** @@ -351,22 +350,6 @@ export interface PXE { */ getPXEInfo(): Promise; - /** - * Checks whether all the blocks were processed (tree roots updated, txs updated with block info, etc.). - * @returns True if there are no outstanding blocks to be synched. - * @remarks This indicates that blocks and transactions are synched even if notes are not. Compares local block number with the block number from aztec node. - * @deprecated Use `getSyncStatus` instead. - */ - isGlobalStateSynchronized(): Promise; - - /** - * Returns the latest block that has been synchronized globally and for each account. The global block number - * indicates whether global state has been updated up to that block, whereas each address indicates up to which - * block the private state has been synced for that account. - * @returns The latest block synchronized for blocks, and the latest block synched for notes for each public key being tracked. - */ - getSyncStatus(): Promise; - /** * Returns a Contract Instance given its address, which includes the contract class identifier, * initialization hash, deployment salt, and public keys hash. @@ -540,8 +523,6 @@ export const PXESchema: ApiSchemaFor = { getProvenBlockNumber: z.function().returns(z.number()), getNodeInfo: z.function().returns(NodeInfoSchema), getPXEInfo: z.function().returns(PXEInfoSchema), - isGlobalStateSynchronized: z.function().returns(z.boolean()), - getSyncStatus: z.function().returns(SyncStatusSchema), getContractInstance: z .function() .args(schemas.AztecAddress) diff --git a/yarn-project/circuit-types/src/interfaces/sync-status.ts b/yarn-project/circuit-types/src/interfaces/sync-status.ts deleted file mode 100644 index b85a13620d6..00000000000 --- a/yarn-project/circuit-types/src/interfaces/sync-status.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { type ZodFor } from '@aztec/foundation/schemas'; - -import { z } from 'zod'; - -/** Provides up to which block has been synced by different components. */ -export type SyncStatus = { - /** Up to which block has been synched for blocks and txs. */ - blocks: number; -}; - -export const SyncStatusSchema = z.object({ - blocks: z.number(), -}) satisfies ZodFor; diff --git a/yarn-project/cli-wallet/src/bin/index.ts b/yarn-project/cli-wallet/src/bin/index.ts index bcdbb4d50a1..1147134a56f 100644 --- a/yarn-project/cli-wallet/src/bin/index.ts +++ b/yarn-project/cli-wallet/src/bin/index.ts @@ -2,7 +2,6 @@ import { Fr, computeSecretHash, fileURLToPath } from '@aztec/aztec.js'; import { LOCALHOST } from '@aztec/cli/cli-utils'; import { type LogFn, createConsoleLogger, createLogger } from '@aztec/foundation/log'; import { AztecLmdbStore } from '@aztec/kv-store/lmdb'; -import { type PXEService } from '@aztec/pxe'; import { Argument, Command, Option } from 'commander'; import { readFileSync } from 'fs'; @@ -94,11 +93,6 @@ async function main() { await pxeWrapper.init(nodeUrl, join(dataDir, 'pxe')); } db.init(AztecLmdbStore.open(dataDir)); - }) - .hook('postAction', async () => { - if (pxeWrapper.getPXE()) { - await (pxeWrapper.getPXE() as PXEService).stop(); - } }); injectCommands(program, userLog, debugLogger, db, pxeWrapper); diff --git a/yarn-project/cli/src/cmds/pxe/get_block.ts b/yarn-project/cli/src/cmds/pxe/get_block.ts index d1584950ff1..f2951a9c8f6 100644 --- a/yarn-project/cli/src/cmds/pxe/get_block.ts +++ b/yarn-project/cli/src/cmds/pxe/get_block.ts @@ -3,29 +3,8 @@ import { type LogFn, type Logger } from '@aztec/foundation/log'; import { inspectBlock } from '../../utils/inspect.js'; -export async function getBlock( - rpcUrl: string, - maybeBlockNumber: number | undefined, - follow: boolean, - debugLogger: Logger, - log: LogFn, -) { +export async function getBlock(rpcUrl: string, maybeBlockNumber: number | undefined, debugLogger: Logger, log: LogFn) { const client = await createCompatibleClient(rpcUrl, debugLogger); const blockNumber = maybeBlockNumber ?? (await client.getBlockNumber()); await inspectBlock(client, blockNumber, log, { showTxs: true }); - - if (follow) { - let lastBlock = blockNumber; - setInterval(async () => { - const newBlock = await client.getBlockNumber(); - if (newBlock > lastBlock) { - const { blocks } = await client.getSyncStatus(); - if (blocks >= newBlock) { - log(''); - await inspectBlock(client, newBlock, log, { showTxs: true }); - lastBlock = newBlock; - } - } - }, 1000); - } } diff --git a/yarn-project/cli/src/cmds/pxe/index.ts b/yarn-project/cli/src/cmds/pxe/index.ts index e6e1f862725..dc8a7a4bb6a 100644 --- a/yarn-project/cli/src/cmds/pxe/index.ts +++ b/yarn-project/cli/src/cmds/pxe/index.ts @@ -54,11 +54,10 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: Logger .command('get-block') .description('Gets info for a given block or latest.') .argument('[blockNumber]', 'Block height', parseOptionalInteger) - .option('-f, --follow', 'Keep polling for new blocks') .addOption(pxeOption) .action(async (blockNumber, options) => { const { getBlock } = await import('./get_block.js'); - await getBlock(options.rpcUrl, blockNumber, options.follow, debugLogger, log); + await getBlock(options.rpcUrl, blockNumber, debugLogger, log); }); program diff --git a/yarn-project/end-to-end/scripts/docker-compose-no-sandbox.yml b/yarn-project/end-to-end/scripts/docker-compose-no-sandbox.yml index 2fbbabb4d6d..b219e4d01de 100644 --- a/yarn-project/end-to-end/scripts/docker-compose-no-sandbox.yml +++ b/yarn-project/end-to-end/scripts/docker-compose-no-sandbox.yml @@ -18,7 +18,6 @@ services: P2P_BLOCK_CHECK_INTERVAL_MS: 50 SEQ_TX_POLLING_INTERVAL_MS: 50 WS_BLOCK_CHECK_INTERVAL_MS: 50 - PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 ENABLE_GAS: ${ENABLE_GAS:-''} JOB_NAME: ${JOB_NAME:-''} diff --git a/yarn-project/end-to-end/scripts/docker-compose-wallet.yml b/yarn-project/end-to-end/scripts/docker-compose-wallet.yml index b1a421ed575..d7e4541e7fb 100644 --- a/yarn-project/end-to-end/scripts/docker-compose-wallet.yml +++ b/yarn-project/end-to-end/scripts/docker-compose-wallet.yml @@ -18,7 +18,6 @@ services: P2P_BLOCK_CHECK_INTERVAL_MS: 50 SEQ_TX_POLLING_INTERVAL_MS: 50 WS_BLOCK_CHECK_INTERVAL_MS: 50 - PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 ENABLE_GAS: ${ENABLE_GAS:-} HARDWARE_CONCURRENCY: ${HARDWARE_CONCURRENCY:-} diff --git a/yarn-project/end-to-end/scripts/docker-compose.yml b/yarn-project/end-to-end/scripts/docker-compose.yml index 4a96de1088d..eae41741bb5 100644 --- a/yarn-project/end-to-end/scripts/docker-compose.yml +++ b/yarn-project/end-to-end/scripts/docker-compose.yml @@ -18,7 +18,6 @@ services: P2P_BLOCK_CHECK_INTERVAL_MS: 50 SEQ_TX_POLLING_INTERVAL_MS: 50 WS_BLOCK_CHECK_INTERVAL_MS: 50 - PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 ENABLE_GAS: ${ENABLE_GAS:-} HARDWARE_CONCURRENCY: ${HARDWARE_CONCURRENCY:-} diff --git a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts index adc29c28d63..167548937a7 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts @@ -9,7 +9,7 @@ import { type BenchmarkingContract } from '@aztec/noir-contracts.js/Benchmarking import { type SequencerClient } from '@aztec/sequencer-client'; import { type EndToEndContext } from '../fixtures/utils.js'; -import { benchmarkSetup, getFolderSize, makeDataDirectory, sendTxs, waitNewPXESynced } from './utils.js'; +import { benchmarkSetup, createNewPXE, getFolderSize, makeDataDirectory, sendTxs } from './utils.js'; const BLOCK_SIZE = BENCHMARK_HISTORY_BLOCK_SIZE; const CHAIN_LENGTHS = BENCHMARK_HISTORY_CHAIN_LENGTHS; @@ -69,7 +69,7 @@ describe('benchmarks/process_history', () => { // Create a new pxe and measure how much time it takes it to sync with failed and successful decryption // Skip the first two blocks used for setup (create account contract and deploy benchmarking contract) context.logger.info(`Starting new pxe`); - const pxe = await waitNewPXESynced(node, contract, INITIAL_L2_BLOCK_NUM + setupBlockCount); + const pxe = await createNewPXE(node, contract, INITIAL_L2_BLOCK_NUM + setupBlockCount); // Register the owner account and wait until it's synced so we measure how much time it took context.logger.info(`Registering owner account on new pxe`); @@ -81,8 +81,7 @@ describe('benchmarks/process_history', () => { context.logger.info(`Registering fresh account on new pxe`); await pxe.registerAccount(Fr.random(), Fr.random()); - // Stop the external node and pxe - await pxe.stop(); + // Stop the external node await node.stop(); lastBlock = chainLength; diff --git a/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts index d77451f317f..49a09404359 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts @@ -177,9 +177,6 @@ describe('benchmarks/proving', () => { }); afterAll(async () => { - for (const pxe of provingPxes) { - await pxe.stop(); - } await ctx.teardown(); await acvmCleanup(); await bbCleanup(); diff --git a/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts index 21612ccbe85..97d7fb4b17b 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts @@ -5,7 +5,7 @@ import { type BenchmarkingContract } from '@aztec/noir-contracts.js/Benchmarking import { type SequencerClient } from '@aztec/sequencer-client'; import { type EndToEndContext } from '../fixtures/utils.js'; -import { benchmarkSetup, sendTxs, waitNewPXESynced } from './utils.js'; +import { benchmarkSetup, createNewPXE, sendTxs } from './utils.js'; describe('benchmarks/publish_rollup', () => { let context: EndToEndContext; @@ -41,7 +41,7 @@ describe('benchmarks/publish_rollup', () => { // Spin up a new pxe and sync it, we'll use it to test sync times of new accounts for the last block context.logger.info(`Starting new pxe`); - const pxe = await waitNewPXESynced(node, contract, blockNumber! - 1); + const pxe = await createNewPXE(node, contract, blockNumber! - 1); // Register the owner account and wait until it's synced so we measure how much time it took context.logger.info(`Registering owner account on new pxe`); @@ -53,8 +53,7 @@ describe('benchmarks/publish_rollup', () => { context.logger.info(`Registering fresh account on new pxe`); await pxe.registerAccount(Fr.random(), Fr.random()); - // Stop the external node and pxe - await pxe.stop(); + // Stop the external node await node.stop(); }, 20 * 60_000, diff --git a/yarn-project/end-to-end/src/benchmarks/utils.ts b/yarn-project/end-to-end/src/benchmarks/utils.ts index 5dbebfa26ce..05c90892ae7 100644 --- a/yarn-project/end-to-end/src/benchmarks/utils.ts +++ b/yarn-project/end-to-end/src/benchmarks/utils.ts @@ -1,5 +1,5 @@ import { type AztecNodeConfig, type AztecNodeService } from '@aztec/aztec-node'; -import { type AztecNode, BatchCall, INITIAL_L2_BLOCK_NUM, type SentTx, retryUntil, sleep } from '@aztec/aztec.js'; +import { type AztecNode, BatchCall, INITIAL_L2_BLOCK_NUM, type SentTx, sleep } from '@aztec/aztec.js'; import { times } from '@aztec/foundation/collection'; import { randomInt } from '@aztec/foundation/crypto'; import { BenchmarkingContract } from '@aztec/noir-contracts.js/Benchmarking'; @@ -90,13 +90,13 @@ export async function sendTxs( } /** - * Creates a new PXE and awaits until it's synced with the node. + * Creates a new PXE * @param node - Node to connect the pxe to. * @param contract - Benchmark contract to add to the pxe. * @param startingBlock - First l2 block to process. * @returns The new PXE. */ -export async function waitNewPXESynced( +export async function createNewPXE( node: AztecNode, contract: BenchmarkingContract, startingBlock: number = INITIAL_L2_BLOCK_NUM, @@ -111,6 +111,5 @@ export async function waitNewPXESynced( } as PXEServiceConfig; const pxe = await createPXEService(node, pxeConfig); await pxe.registerContract(contract); - await retryUntil(() => pxe.isGlobalStateSynchronized(), 'pxe-global-sync'); return pxe; } diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index 87528585bd1..eaa70fa10ff 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -8,7 +8,6 @@ import { type Logger, type PXE, type Wallet, - retryUntil, sleep, } from '@aztec/aztec.js'; import { ChildContract, TestContract, TokenContract } from '@aztec/noir-contracts.js'; @@ -57,8 +56,7 @@ describe('e2e_2_pxes', () => { await teardownA(); }); - // TODO #10296 - it.skip('transfers funds from user A to B via PXE A followed by transfer from B to A via PXE B', async () => { + it('transfers funds from user A to B via PXE A followed by transfer from B to A via PXE B', async () => { const initialBalance = 987n; const transferAmount1 = 654n; const transferAmount2 = 323n; @@ -103,21 +101,12 @@ describe('e2e_2_pxes', () => { return contract.instance; }; - const awaitServerSynchronized = async (server: PXE) => { - const isServerSynchronized = async () => { - return await server.isGlobalStateSynchronized(); - }; - await retryUntil(isServerSynchronized, 'server sync', 10); - }; - const getChildStoredValue = (child: { address: AztecAddress }, pxe: PXE) => pxe.getPublicStorageAt(child.address, new Fr(1)); it('user calls a public function on a contract deployed by a different user using a different PXE', async () => { const childCompleteAddress = await deployChildContractViaServerA(); - await awaitServerSynchronized(pxeA); - // Add Child to PXE B await pxeB.registerContract({ artifact: ChildContract.artifact, @@ -129,8 +118,6 @@ describe('e2e_2_pxes', () => { const childContractWithWalletB = await ChildContract.at(childCompleteAddress.address, walletB); await childContractWithWalletB.methods.pub_inc_value(newValueToSet).send().wait({ interval: 0.1 }); - await awaitServerSynchronized(pxeA); - const storedValueOnB = await getChildStoredValue(childCompleteAddress, pxeB); expect(storedValueOnB).toEqual(newValueToSet); diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index 38ff8cce2e1..942e558d83e 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -483,14 +483,6 @@ describe('e2e_block_building', () => { // PXE should have cleared out the 30-note from tx2, but reapplied the 20-note from tx1 expect(await contract.methods.summed_values(ownerAddress).simulate()).toEqual(21n); - // PXE should be synced to the block number on the new chain - await retryUntil( - async () => (await pxe.getSyncStatus()).blocks === newTx1Receipt.blockNumber, - 'wait for pxe block header sync', - 15, - 1, - ); - // And we should be able to send a new tx on the new chain logger.info('Sending new tx on reorgd chain'); const tx3 = await contract.methods.create_note(ownerAddress, ownerAddress, 10).send().wait(); diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts index 7a0507a6e63..6743a7ef2c4 100644 --- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts +++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts @@ -247,7 +247,6 @@ async function teardown(context: SubsystemsContext | undefined) { getLogger().info('Tearing down subsystems'); await context.proverNode?.stop(); await context.aztecNode.stop(); - await context.pxe.stop(); await context.acvmConfig?.cleanup(); await context.anvil.stop(); await context.watcher.stop(); diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 8c71ccb4d9a..b8954d38cd1 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -42,7 +42,7 @@ import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node'; -import { PXEService, type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; +import { type PXEService, type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { type SequencerClient, TestL1Publisher } from '@aztec/sequencer-client'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { createAndStartTelemetryClient, getConfigEnvVars as getTelemetryConfig } from '@aztec/telemetry-client/start'; @@ -146,9 +146,7 @@ export async function setupPXEService( const pxeServiceConfig = { ...getPXEServiceConfig(), ...opts }; const pxe = await createPXEService(aztecNode, pxeServiceConfig, useLogSuffix, proofCreator); - const teardown = async () => { - await pxe.stop(); - }; + const teardown = async () => {}; return { pxe, @@ -445,9 +443,6 @@ export async function setup( if (aztecNode instanceof AztecNodeService) { await aztecNode?.stop(); } - if (pxe instanceof PXEService) { - await pxe?.stop(); - } if (acvmConfig?.cleanup) { // remove the temp directory created for the acvm diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index cb43781825f..ea13f2f9711 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -126,7 +126,6 @@ export type EnvVar = | 'PROVER_REQUIRED_CONFIRMATIONS' | 'PROVER_TEST_DELAY_MS' | 'PROVER_CACHE_DIR' - | 'PXE_BLOCK_POLLING_INTERVAL_MS' | 'PXE_L2_STARTING_BLOCK' | 'PXE_PROVER_ENABLED' | 'QUOTE_PROVIDER_BASIS_POINT_FEE' diff --git a/yarn-project/pxe/src/bin/index.ts b/yarn-project/pxe/src/bin/index.ts index 5ba7ce5aa0e..66f451dae92 100644 --- a/yarn-project/pxe/src/bin/index.ts +++ b/yarn-project/pxe/src/bin/index.ts @@ -5,7 +5,7 @@ import { createLogger } from '@aztec/foundation/log'; import { getPXEServiceConfig } from '../config/index.js'; import { startPXEHttpServer } from '../pxe_http/index.js'; -import { createPXEService } from '../utils/index.js'; +import { createPXEService } from '../utils/create_pxe_service.js'; const { PXE_PORT = 8080, AZTEC_NODE_URL = 'http://localhost:8079' } = process.env; @@ -23,9 +23,8 @@ async function main() { const nodeRpcClient = createAztecNodeClient(AZTEC_NODE_URL); const pxeService = await createPXEService(nodeRpcClient, pxeConfig); - const shutdown = async () => { + const shutdown = () => { logger.info('Shutting down...'); - await pxeService.stop(); process.exit(0); }; diff --git a/yarn-project/pxe/src/config/index.ts b/yarn-project/pxe/src/config/index.ts index 4841f7ce6fd..7eeb270453f 100644 --- a/yarn-project/pxe/src/config/index.ts +++ b/yarn-project/pxe/src/config/index.ts @@ -28,8 +28,6 @@ export interface KernelProverConfig { * Configuration settings for the PXE. */ export interface PXEConfig { - /** The interval to wait between polling for new blocks. */ - l2BlockPollingIntervalMS: number; /** L2 block to start scanning from for new accounts */ l2StartingBlock: number; } @@ -47,11 +45,6 @@ export type CliPXEOptions = { export const pxeConfigMappings: ConfigMappingsType = { ...dataConfigMappings, - l2BlockPollingIntervalMS: { - env: 'PXE_BLOCK_POLLING_INTERVAL_MS', - description: 'The interval to wait between polling for new blocks.', - ...numberConfigHelper(1_000), - }, l2StartingBlock: { env: 'PXE_L2_STARTING_BLOCK', ...numberConfigHelper(INITIAL_L2_BLOCK_NUM), diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 866d2df92c7..5439afa717b 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -46,7 +46,6 @@ export class KVPxeDatabase implements PxeDatabase { #nullifiedNotesByTxHash: AztecAsyncMultiMap; #nullifiedNotesByAddressPoint: AztecAsyncMultiMap; #nullifiedNotesByNullifier: AztecAsyncMap; - #syncedBlockPerPublicKey: AztecAsyncMap; #contractArtifacts: AztecAsyncMap; #contractInstances: AztecAsyncMap; #db: AztecAsyncKVStore; @@ -79,7 +78,6 @@ export class KVPxeDatabase implements PxeDatabase { this.#contractInstances = db.openMap('contracts_instances'); this.#synchronizedBlock = db.openSingleton('header'); - this.#syncedBlockPerPublicKey = db.openMap('synced_block_per_public_key'); this.#notes = db.openMap('notes'); this.#nullifiedNotes = db.openMap('nullified_notes'); @@ -564,14 +562,6 @@ export class KVPxeDatabase implements PxeDatabase { return true; } - getSynchedBlockNumberForAccount(account: AztecAddress): Promise { - return this.#syncedBlockPerPublicKey.getAsync(account.toString()); - } - - setSynchedBlockNumberForAccount(account: AztecAddress, blockNumber: number): Promise { - return this.#syncedBlockPerPublicKey.set(account.toString(), blockNumber); - } - async estimateSize(): Promise { const incomingNotesSize = (await this.getIncomingNotes({})).reduce((sum, note) => sum + note.getSize(), 0); diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index 0b24e77b99a..4f2fd1557f2 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -160,19 +160,6 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD */ getCompleteAddresses(): Promise; - /** - * Updates up to which block number we have processed notes for a given public key. - * @param account - The account to set the synched block number for. - * @param blockNumber - The block number to set. - */ - setSynchedBlockNumberForAccount(account: AztecAddress, blockNumber: number): Promise; - - /** - * Get the synched block number for a given public key. - * @param account - The account to get the synched block number for. - */ - getSynchedBlockNumberForAccount(account: AztecAddress): Promise; - /** * Returns the estimated size in bytes of this db. * @returns The estimated size in bytes of this db. diff --git a/yarn-project/pxe/src/index.ts b/yarn-project/pxe/src/index.ts index d0bdaa737a6..e97f38565f2 100644 --- a/yarn-project/pxe/src/index.ts +++ b/yarn-project/pxe/src/index.ts @@ -1,6 +1,7 @@ export * from './pxe_service/index.js'; export * from './pxe_http/index.js'; export * from './config/index.js'; +export * from './utils/create_pxe_service.js'; export { Tx, TxHash } from '@aztec/circuit-types'; @@ -10,7 +11,6 @@ export * from '@aztec/foundation/eth-address'; export * from '@aztec/foundation/aztec-address'; export * from '@aztec/key-store'; export * from './database/index.js'; -export * from './utils/index.js'; export { ContractDataOracle } from './contract_data_oracle/index.js'; export { PrivateFunctionsTree } from './contract_data_oracle/private_functions_tree.js'; export { SimulatorOracle } from './simulator_oracle/index.js'; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 9c63173a600..f2b1f419909 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -56,7 +56,6 @@ import { } from '@aztec/foundation/abi'; import { Fr, type Point } from '@aztec/foundation/fields'; import { type Logger, createLogger } from '@aztec/foundation/log'; -import { SerialQueue } from '@aztec/foundation/queue'; import { type KeyStore } from '@aztec/key-store'; import { type L2TipsStore } from '@aztec/kv-store/stores'; import { @@ -89,9 +88,6 @@ export class PXEService implements PXE { private simulator: AcirSimulator; private log: Logger; private packageVersion: string; - // serialize synchronizer and calls to proveTx. - // ensures that state is not changed while simulating - private jobQueue = new SerialQueue(); constructor( private keyStore: KeyStore, @@ -107,8 +103,6 @@ export class PXEService implements PXE { this.contractDataOracle = new ContractDataOracle(db); this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle); this.packageVersion = getPackageInfo().version; - - this.jobQueue.start(); } /** @@ -116,27 +110,12 @@ export class PXEService implements PXE { * * @returns A promise that resolves when the server has started successfully. */ - public async start() { - await this.synchronizer.start(); + public async init() { await this.#registerProtocolContracts(); const info = await this.getNodeInfo(); this.log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.protocolVersion}`); } - /** - * Stops the PXE Service, halting processing of new transactions and shutting down the synchronizer. - * This function ensures that all ongoing tasks are completed before stopping the server. - * It is useful for gracefully shutting down the server during maintenance or restarts. - * - * @returns A Promise resolving once the server has been stopped successfully. - */ - public async stop() { - await this.jobQueue.cancel(); - this.log.info('Cancelled Job Queue'); - await this.synchronizer.stop(); - this.log.info('Stopped Synchronizer'); - } - isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise { return this.node.isL1ToL2MessageSynced(l1ToL2Message); } @@ -484,22 +463,16 @@ export class PXEService implements PXE { return result.publicInputs; } - public proveTx( + public async proveTx( txRequest: TxExecutionRequest, privateExecutionResult: PrivateExecutionResult, ): Promise { - return this.jobQueue - .put(async () => { - const { publicInputs, clientIvcProof } = await this.#prove( - txRequest, - this.proofCreator, - privateExecutionResult, - ); - return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!); - }) - .catch(err => { - throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult)); - }); + try { + const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult); + return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!); + } catch (err: any) { + throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult)); + } } // TODO(#7456) Prevent msgSender being defined here for the first call @@ -511,78 +484,77 @@ export class PXEService implements PXE { profile: boolean = false, scopes?: AztecAddress[], ): Promise { - return await this.jobQueue - .put(async () => { - const txInfo = { - origin: txRequest.origin, - functionSelector: txRequest.functionSelector, - simulatePublic, - msgSender, - chainId: txRequest.txContext.chainId, - version: txRequest.txContext.version, - authWitnesses: txRequest.authWitnesses.map(w => w.requestHash), - }; - this.log.verbose( - `Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`, - txInfo, - ); - const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes); - - let publicInputs: PrivateKernelTailCircuitPublicInputs; - let profileResult; - if (profile) { - ({ publicInputs, profileResult } = await this.#profileKernelProver( - txRequest, - this.proofCreator, - privateExecutionResult, - )); - } else { - publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult); - } + try { + const txInfo = { + origin: txRequest.origin, + functionSelector: txRequest.functionSelector, + simulatePublic, + msgSender, + chainId: txRequest.txContext.chainId, + version: txRequest.txContext.version, + authWitnesses: txRequest.authWitnesses.map(w => w.requestHash), + }; + this.log.verbose( + `Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`, + txInfo, + ); + await this.synchronizer.sync(); + const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes); - const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs); - const simulatedTx = privateSimulationResult.toSimulatedTx(); - let publicOutput: PublicSimulationOutput | undefined; - if (simulatePublic) { - publicOutput = await this.#simulatePublicCalls(simulatedTx); - } + let publicInputs: PrivateKernelTailCircuitPublicInputs; + let profileResult; + if (profile) { + ({ publicInputs, profileResult } = await this.#profileKernelProver( + txRequest, + this.proofCreator, + privateExecutionResult, + )); + } else { + publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult); + } - if (!skipTxValidation) { - if (!(await this.node.isValidTx(simulatedTx, true))) { - throw new Error('The simulated transaction is unable to be added to state and is invalid.'); - } + const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs); + const simulatedTx = privateSimulationResult.toSimulatedTx(); + let publicOutput: PublicSimulationOutput | undefined; + if (simulatePublic) { + publicOutput = await this.#simulatePublicCalls(simulatedTx); + } + + if (!skipTxValidation) { + if (!(await this.node.isValidTx(simulatedTx, true))) { + throw new Error('The simulated transaction is unable to be added to state and is invalid.'); } + } - this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()}`, { - txHash: simulatedTx.tryGetTxHash(), - ...txInfo, - ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}), - ...(publicOutput - ? { - gasUsed: publicOutput.gasUsed, - revertCode: publicOutput.txEffect.revertCode.getCode(), - revertReason: publicOutput.revertReason, - } - : {}), - }); - - return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput( - privateSimulationResult, - publicOutput, - profileResult, - ); - }) - .catch(err => { - throw this.contextualizeError( - err, - inspect(txRequest), - `simulatePublic=${simulatePublic}`, - `msgSender=${msgSender?.toString() ?? 'undefined'}`, - `skipTxValidation=${skipTxValidation}`, - `profile=${profile}`, - `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`, - ); + this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()}`, { + txHash: simulatedTx.tryGetTxHash(), + ...txInfo, + ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}), + ...(publicOutput + ? { + gasUsed: publicOutput.gasUsed, + revertCode: publicOutput.txEffect.revertCode.getCode(), + revertReason: publicOutput.revertReason, + } + : {}), }); + + return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput( + privateSimulationResult, + publicOutput, + profileResult, + ); + } catch (err: any) { + throw this.contextualizeError( + err, + inspect(txRequest), + `simulatePublic=${simulatePublic}`, + `msgSender=${msgSender?.toString() ?? 'undefined'}`, + `skipTxValidation=${skipTxValidation}`, + `profile=${profile}`, + `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`, + ); + } } public async sendTx(tx: Tx): Promise { @@ -605,24 +577,22 @@ export class PXEService implements PXE { _from?: AztecAddress, scopes?: AztecAddress[], ): Promise { - // all simulations must be serialized w.r.t. the synchronizer - return await this.jobQueue - .put(async () => { - // TODO - Should check if `from` has the permission to call the view function. - const functionCall = await this.#getFunctionCall(functionName, args, to); - const executionResult = await this.#simulateUnconstrained(functionCall, scopes); - - // TODO - Return typed result based on the function artifact. - return executionResult; - }) - .catch(err => { - const stringifiedArgs = args.map(arg => arg.toString()).join(', '); - throw this.contextualizeError( - err, - `simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`, - `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`, - ); - }); + try { + await this.synchronizer.sync(); + // TODO - Should check if `from` has the permission to call the view function. + const functionCall = await this.#getFunctionCall(functionName, args, to); + const executionResult = await this.#simulateUnconstrained(functionCall, scopes); + + // TODO - Return typed result based on the function artifact. + return executionResult; + } catch (err: any) { + const stringifiedArgs = args.map(arg => arg.toString()).join(', '); + throw this.contextualizeError( + err, + `simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`, + `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`, + ); + } } public getTxReceipt(txHash: TxHash): Promise { @@ -726,7 +696,7 @@ export class PXEService implements PXE { await this.db.addContractInstance(instance); registered[name] = address.toString(); } - this.log.info(`Registered protocol contracts in pxe`, registered); + this.log.verbose(`Registered protocol contracts in pxe`, registered); } /** @@ -840,19 +810,14 @@ export class PXEService implements PXE { } /** - * Simulate a transaction, generate a kernel proof, and create a private transaction object. - * The function takes in a transaction request, simulates it, and then generates a kernel proof - * using the simulation result. Finally, it creates a private - * transaction object with the generated proof and public inputs. If a new contract address is provided, - * the function will also include the new contract's public functions in the transaction object. + * Generate a kernel proof, and create a private kernel output. + * The function takes in a transaction execution request, and the result of private execution + * and then generates a kernel proof. * * @param txExecutionRequest - The transaction request to be simulated and proved. * @param proofCreator - The proof creator to use for proving the execution. - * @param msgSender - (Optional) The message sender to use for the simulation. - * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all. - * @returns An object that contains: - * A private transaction object containing the proof, public inputs, and encrypted logs. - * The return values of the private execution + * @param privateExecutionResult - The result of the private execution + * @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled. */ async #prove( txExecutionRequest: TxExecutionRequest, @@ -867,14 +832,6 @@ export class PXEService implements PXE { return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult); } - public async isGlobalStateSynchronized() { - return await this.synchronizer.isGlobalStateSynchronized(); - } - - public getSyncStatus() { - return Promise.resolve(this.synchronizer.getSyncStatus()); - } - public async isContractClassPubliclyRegistered(id: Fr): Promise { return !!(await this.node.getContractClass(id)); } diff --git a/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts b/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts index 678f6c4bb76..d0dc0103bbf 100644 --- a/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts +++ b/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts @@ -22,7 +22,6 @@ async function createPXEService(): Promise { const db = await KVPxeDatabase.create(kvStore); const tips = new L2TipsStore(kvStore, 'pxe'); const config: PXEServiceConfig = { - l2BlockPollingIntervalMS: 100, l2StartingBlock: INITIAL_L2_BLOCK_NUM, dataDirectory: undefined, dataStoreMapSizeKB: 1024 * 1024, @@ -67,7 +66,6 @@ describe('PXEService', () => { tips = new L2TipsStore(kvStore, 'pxe'); db = await KVPxeDatabase.create(kvStore); config = { - l2BlockPollingIntervalMS: 100, l2StartingBlock: INITIAL_L2_BLOCK_NUM, proverEnabled: false, dataDirectory: undefined, diff --git a/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts b/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts index c5fc6219e01..686c5b9f9a1 100644 --- a/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts +++ b/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts @@ -115,8 +115,5 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise) => expect(typeof nodeInfo.l1ChainId).toEqual('number'); expect(nodeInfo.l1ContractAddresses.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/); }); - - // Note: Not testing `isGlobalStateSynchronized`, `isAccountStateSynchronized` and `getSyncStatus` as these methods - // only call synchronizer. }); }; diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index b6866e9a28c..d05451f87ec 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -231,7 +231,7 @@ export class SimulatorOracle implements DBOracle { * @returns A Promise that resolves to a BlockHeader object. */ getBlockHeader(): Promise { - return Promise.resolve(this.db.getBlockHeader()); + return this.db.getBlockHeader(); } /** diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index a4f13e1d019..225787866df 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -12,14 +12,12 @@ import { type PXEConfig } from '../config/index.js'; import { type PxeDatabase } from '../database/index.js'; /** - * The Synchronizer class manages the synchronization of note processors and interacts with the Aztec node - * to obtain encrypted logs, blocks, and other necessary information for the accounts. - * It provides methods to start or stop the synchronization process, add new accounts, retrieve account - * details, and fetch transactions by hash. The Synchronizer ensures that it maintains the note processors - * in sync with the blockchain while handling retries and errors gracefully. + * The Synchronizer class manages the synchronization with the aztec node, allowing PXE to retrieve the + * latest block header and handle reorgs. + * It provides methods to trigger a sync and get the block number we are syncec to + * details, and fetch transactions by hash. */ export class Synchronizer implements L2BlockStreamEventHandler { - private running = false; private initialSyncBlockNumber = INITIAL_L2_BLOCK_NUM - 1; private log: Logger; protected readonly blockStream: L2BlockStream; @@ -28,16 +26,15 @@ export class Synchronizer implements L2BlockStreamEventHandler { private node: AztecNode, private db: PxeDatabase, private l2TipsStore: L2TipsStore, - config: Partial> = {}, + config: Partial> = {}, logSuffix?: string, ) { this.log = createLogger(logSuffix ? `pxe:synchronizer:${logSuffix}` : 'pxe:synchronizer'); this.blockStream = this.createBlockStream(config); } - protected createBlockStream(config: Partial>) { + protected createBlockStream(config: Partial>) { return new L2BlockStream(this.node, this.l2TipsStore, this, createLogger('pxe:block_stream'), { - pollIntervalMS: config.l2BlockPollingIntervalMS, startingBlock: config.l2StartingBlock, }); } @@ -73,19 +70,10 @@ export class Synchronizer implements L2BlockStreamEventHandler { } /** - * Starts the synchronization process by fetching encrypted logs and blocks from a specified position. - * Continuously processes the fetched data for all note processors until stopped. If there is no data - * available, it retries after a specified interval. - * - * @param limit - The maximum number of encrypted, unencrypted logs and blocks to fetch in each iteration. - * @param retryInterval - The time interval (in ms) to wait before retrying if no data is available. + * Syncs PXE and the node by dowloading the metadata of the latest blocks, allowing simulations to use + * recent data (e.g. notes), and handling any reorgs that might have occurred. */ - public async start() { - if (this.running) { - return; - } - this.running = true; - + public async sync() { let currentHeader; try { @@ -97,54 +85,10 @@ export class Synchronizer implements L2BlockStreamEventHandler { // REFACTOR: We should know the header of the genesis block without having to request it from the node. await this.db.setHeader(await this.node.getBlockHeader(0)); } - - await this.trigger(); - this.log.info('Initial sync complete'); - this.blockStream.start(); - this.log.debug('Started loop'); - } - - /** - * Stops the synchronizer gracefully, interrupting any ongoing sleep and waiting for the current - * iteration to complete before setting the running state to false. Once stopped, the synchronizer - * will no longer process blocks or encrypted logs and must be restarted using the start method. - * - * @returns A promise that resolves when the synchronizer has successfully stopped. - */ - public async stop() { - this.running = false; - await this.blockStream.stop(); - this.log.info('Stopped'); - } - - /** Triggers a single run. */ - public async trigger() { await this.blockStream.sync(); } - private async getSynchedBlockNumber() { + public async getSynchedBlockNumber() { return (await this.db.getBlockNumber()) ?? this.initialSyncBlockNumber; } - - /** - * Checks whether all the blocks were processed (tree roots updated, txs updated with block info, etc.). - * @returns True if there are no outstanding blocks to be synched. - * @remarks This indicates that blocks and transactions are synched even if notes are not. - * @remarks Compares local block number with the block number from aztec node. - */ - public async isGlobalStateSynchronized() { - const latest = await this.node.getBlockNumber(); - return latest <= (await this.getSynchedBlockNumber()); - } - - /** - * Returns the latest block that has been synchronized by the synchronizer and each account. - * @returns The latest block synchronized for blocks, and the latest block synched for notes for each public key being tracked. - */ - public async getSyncStatus() { - const lastBlockNumber = await this.getSynchedBlockNumber(); - return { - blocks: lastBlockNumber, - }; - } } diff --git a/yarn-project/pxe/src/pxe_service/create_pxe_service.ts b/yarn-project/pxe/src/utils/create_pxe_service.ts similarity index 93% rename from yarn-project/pxe/src/pxe_service/create_pxe_service.ts rename to yarn-project/pxe/src/utils/create_pxe_service.ts index bd168463788..773c7fa08aa 100644 --- a/yarn-project/pxe/src/pxe_service/create_pxe_service.ts +++ b/yarn-project/pxe/src/utils/create_pxe_service.ts @@ -9,7 +9,7 @@ import { L2TipsStore } from '@aztec/kv-store/stores'; import { type PXEServiceConfig } from '../config/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js'; -import { PXEService } from './pxe_service.js'; +import { PXEService } from '../pxe_service/pxe_service.js'; /** * Create and start an PXEService instance with the given AztecNode. @@ -47,9 +47,9 @@ export async function createPXEService( const tips = new L2TipsStore(store, 'pxe'); const prover = proofCreator ?? (await createProver(config, logSuffix)); - const server = new PXEService(keyStore, aztecNode, db, tips, prover, config, logSuffix); - await server.start(); - return server; + const pxe = new PXEService(keyStore, aztecNode, db, tips, prover, config, logSuffix); + await pxe.init(); + return pxe; } function createProver(config: PXEServiceConfig, logSuffix?: string) { diff --git a/yarn-project/pxe/src/utils/index.ts b/yarn-project/pxe/src/utils/index.ts deleted file mode 100644 index f971258aca0..00000000000 --- a/yarn-project/pxe/src/utils/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { BBNativePrivateKernelProver } from '@aztec/bb-prover'; -import { type AztecNode, type PrivateKernelProver } from '@aztec/circuit-types'; -import { randomBytes } from '@aztec/foundation/crypto'; -import { createLogger } from '@aztec/foundation/log'; -import { KeyStore } from '@aztec/key-store'; -import { createStore } from '@aztec/kv-store/lmdb'; -import { L2TipsStore } from '@aztec/kv-store/stores'; - -import { type PXEServiceConfig } from '../config/index.js'; -import { KVPxeDatabase } from '../database/kv_pxe_database.js'; -import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js'; -import { PXEService } from '../pxe_service/pxe_service.js'; - -/** - * Create and start an PXEService instance with the given AztecNode. - * If no keyStore or database is provided, it will use KeyStore and MemoryDB as default values. - * Returns a Promise that resolves to the started PXEService instance. - * - * @param aztecNode - The AztecNode instance to be used by the server. - * @param config - The PXE Service Config to use - * @param options - (Optional) Optional information for creating an PXEService. - * @param proofCreator - An optional proof creator to use in place of any other configuration - * @returns A Promise that resolves to the started PXEService instance. - */ -export async function createPXEService( - aztecNode: AztecNode, - config: PXEServiceConfig, - useLogSuffix: string | boolean | undefined = undefined, - proofCreator?: PrivateKernelProver, -) { - const logSuffix = - typeof useLogSuffix === 'boolean' ? (useLogSuffix ? randomBytes(3).toString('hex') : undefined) : useLogSuffix; - - const l1Contracts = await aztecNode.getL1ContractAddresses(); - const configWithContracts = { - ...config, - l1Contracts, - } as PXEServiceConfig; - - const keyStore = new KeyStore( - await createStore('pxe_key_store', configWithContracts, createLogger('pxe:keystore:lmdb')), - ); - - const store = await createStore('pxe_data', configWithContracts, createLogger('pxe:data:lmdb')); - - const db = await KVPxeDatabase.create(store); - const tips = new L2TipsStore(store, 'pxe'); - - const prover = proofCreator ?? (await createProver(config, logSuffix)); - const server = new PXEService(keyStore, aztecNode, db, tips, prover, config, logSuffix); - await server.start(); - return server; -} - -function createProver(config: PXEServiceConfig, logSuffix?: string) { - if (!config.proverEnabled) { - return new TestPrivateKernelProver(); - } - - // (@PhilWindle) Temporary validation until WASM is implemented - if (!config.bbBinaryPath || !config.bbWorkingDirectory) { - throw new Error(`Prover must be configured with binary path and working directory`); - } - const bbConfig = config as Required> & PXEServiceConfig; - const log = createLogger('pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : '')); - return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, log); -}