@aztec/pxe 0.0.1-commit.6c91f13 → 0.0.1-commit.96bb3f7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/block_synchronizer/block_synchronizer.d.ts +4 -2
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +6 -3
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +4 -3
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +7 -6
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -2
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +5 -2
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.js +1 -2
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +2 -17
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +4 -32
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +3 -2
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +4 -2
- package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +10 -1
- package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +10 -1
- package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.d.ts +1 -1
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +11 -7
- package/dest/events/event_service.d.ts +2 -2
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +2 -2
- package/dest/job_coordinator/job_coordinator.d.ts +74 -0
- package/dest/job_coordinator/job_coordinator.d.ts.map +1 -0
- package/dest/job_coordinator/job_coordinator.js +93 -0
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +2 -2
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +2 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +3 -4
- package/dest/private_kernel/private_kernel_oracle.d.ts +3 -2
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts +2 -2
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle_impl.js +2 -3
- package/dest/pxe.d.ts +2 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +39 -20
- package/dest/storage/private_event_store/private_event_store.d.ts +7 -2
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +57 -14
- package/dest/storage/tagging_store/sender_tagging_store.js +1 -1
- package/dest/tagging/constants.d.ts +2 -0
- package/dest/tagging/constants.d.ts.map +1 -0
- package/dest/tagging/constants.js +10 -0
- package/dest/tagging/index.d.ts +2 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +1 -10
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +2 -2
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +2 -2
- package/package.json +16 -16
- package/src/block_synchronizer/block_synchronizer.ts +5 -2
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +10 -5
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +4 -0
- package/src/contract_function_simulator/oracle/private_execution.ts +0 -2
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +4 -36
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +2 -0
- package/src/entrypoints/client/bundle/utils.ts +7 -1
- package/src/entrypoints/client/lazy/utils.ts +7 -2
- package/src/entrypoints/pxe_creation_options.ts +2 -1
- package/src/entrypoints/server/utils.ts +11 -15
- package/src/events/event_service.ts +2 -0
- package/src/job_coordinator/job_coordinator.ts +149 -0
- package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +1 -2
- package/src/private_kernel/private_kernel_execution_prover.ts +2 -4
- package/src/private_kernel/private_kernel_oracle.ts +2 -1
- package/src/private_kernel/private_kernel_oracle_impl.ts +2 -8
- package/src/pxe.ts +64 -19
- package/src/storage/private_event_store/private_event_store.ts +68 -14
- package/src/storage/tagging_store/sender_tagging_store.ts +1 -1
- package/src/tagging/constants.ts +10 -0
- package/src/tagging/index.ts +1 -11
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +5 -2
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +1 -1
- package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +6 -2
|
@@ -7,6 +7,7 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
|
7
7
|
import type { PXEConfig } from '../config/index.js';
|
|
8
8
|
import type { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_store.js';
|
|
9
9
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
10
|
+
import type { PrivateEventStore } from '../storage/private_event_store/private_event_store.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* The BlockSynchronizer class orchestrates synchronization between PXE and Aztec node, maintaining an up-to-date
|
|
@@ -22,6 +23,7 @@ export class BlockSynchronizer implements L2BlockStreamEventHandler {
|
|
|
22
23
|
private node: AztecNode,
|
|
23
24
|
private anchorBlockStore: AnchorBlockStore,
|
|
24
25
|
private noteStore: NoteStore,
|
|
26
|
+
private privateEventStore: PrivateEventStore,
|
|
25
27
|
private l2TipsStore: L2TipsKVStore,
|
|
26
28
|
config: Partial<Pick<PXEConfig, 'l2BlockBatchSize'>> = {},
|
|
27
29
|
loggerOrSuffix?: string | Logger,
|
|
@@ -48,13 +50,13 @@ export class BlockSynchronizer implements L2BlockStreamEventHandler {
|
|
|
48
50
|
|
|
49
51
|
switch (event.type) {
|
|
50
52
|
case 'blocks-added': {
|
|
51
|
-
const lastBlock = event.blocks.at(-1)
|
|
53
|
+
const lastBlock = event.blocks.at(-1)!;
|
|
52
54
|
this.log.verbose(`Updated pxe last block to ${lastBlock.number}`, {
|
|
53
55
|
blockHash: lastBlock.hash(),
|
|
54
56
|
archive: lastBlock.archive.root.toString(),
|
|
55
57
|
header: lastBlock.header.toInspect(),
|
|
56
58
|
});
|
|
57
|
-
await this.anchorBlockStore.setHeader(lastBlock.
|
|
59
|
+
await this.anchorBlockStore.setHeader(lastBlock.header);
|
|
58
60
|
break;
|
|
59
61
|
}
|
|
60
62
|
case 'chain-pruned': {
|
|
@@ -62,6 +64,7 @@ export class BlockSynchronizer implements L2BlockStreamEventHandler {
|
|
|
62
64
|
// We first unnullify and then remove so that unnullified notes that were created after the block number end up deleted.
|
|
63
65
|
const lastSynchedBlockNumber = (await this.anchorBlockStore.getBlockHeader()).getBlockNumber();
|
|
64
66
|
await this.noteStore.rollbackNotesAndNullifiers(event.block.number, lastSynchedBlockNumber);
|
|
67
|
+
await this.privateEventStore.rollbackEventsAfterBlock(event.block.number, lastSynchedBlockNumber);
|
|
65
68
|
// Update the header to the last block.
|
|
66
69
|
const newHeader = await this.node.getBlockHeader(event.block.number);
|
|
67
70
|
if (!newHeader) {
|
|
@@ -123,6 +123,7 @@ export class ContractFunctionSimulator {
|
|
|
123
123
|
* @param senderForTags - The address that is used as a tagging sender when emitting private logs. Returned from
|
|
124
124
|
* the `privateGetSenderForTags` oracle.
|
|
125
125
|
* @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
|
|
126
|
+
* @param jobId - The job ID for staged writes.
|
|
126
127
|
* @returns The result of the execution.
|
|
127
128
|
*/
|
|
128
129
|
public async run(
|
|
@@ -131,13 +132,14 @@ export class ContractFunctionSimulator {
|
|
|
131
132
|
selector: FunctionSelector,
|
|
132
133
|
msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE),
|
|
133
134
|
anchorBlockHeader: BlockHeader,
|
|
134
|
-
senderForTags
|
|
135
|
-
scopes
|
|
135
|
+
senderForTags: AztecAddress | undefined,
|
|
136
|
+
scopes: AztecAddress[] | undefined,
|
|
137
|
+
jobId: string,
|
|
136
138
|
): Promise<PrivateExecutionResult> {
|
|
137
139
|
const simulatorSetupTimer = new Timer();
|
|
138
140
|
|
|
139
141
|
await this.contractStore.syncPrivateState(contractAddress, selector, privateSyncCall =>
|
|
140
|
-
this.runUtility(privateSyncCall, [], anchorBlockHeader, scopes),
|
|
142
|
+
this.runUtility(privateSyncCall, [], anchorBlockHeader, scopes, jobId),
|
|
141
143
|
);
|
|
142
144
|
|
|
143
145
|
await verifyCurrentClassId(contractAddress, this.aztecNode, this.contractStore, anchorBlockHeader);
|
|
@@ -174,7 +176,7 @@ export class ContractFunctionSimulator {
|
|
|
174
176
|
callContext,
|
|
175
177
|
anchorBlockHeader,
|
|
176
178
|
async call => {
|
|
177
|
-
await this.runUtility(call, [], anchorBlockHeader, scopes);
|
|
179
|
+
await this.runUtility(call, [], anchorBlockHeader, scopes, jobId);
|
|
178
180
|
},
|
|
179
181
|
request.authWitnesses,
|
|
180
182
|
request.capsules,
|
|
@@ -192,6 +194,7 @@ export class ContractFunctionSimulator {
|
|
|
192
194
|
this.senderAddressBookStore,
|
|
193
195
|
this.capsuleStore,
|
|
194
196
|
this.privateEventStore,
|
|
197
|
+
jobId,
|
|
195
198
|
0, // totalPublicArgsCount
|
|
196
199
|
startSideEffectCounter,
|
|
197
200
|
undefined, // log
|
|
@@ -261,7 +264,8 @@ export class ContractFunctionSimulator {
|
|
|
261
264
|
call: FunctionCall,
|
|
262
265
|
authwits: AuthWitness[],
|
|
263
266
|
anchorBlockHeader: BlockHeader,
|
|
264
|
-
scopes
|
|
267
|
+
scopes: AztecAddress[] | undefined,
|
|
268
|
+
jobId: string,
|
|
265
269
|
): Promise<Fr[]> {
|
|
266
270
|
await verifyCurrentClassId(call.to, this.aztecNode, this.contractStore, anchorBlockHeader);
|
|
267
271
|
|
|
@@ -286,6 +290,7 @@ export class ContractFunctionSimulator {
|
|
|
286
290
|
this.senderAddressBookStore,
|
|
287
291
|
this.capsuleStore,
|
|
288
292
|
this.privateEventStore,
|
|
293
|
+
jobId,
|
|
289
294
|
undefined,
|
|
290
295
|
scopes,
|
|
291
296
|
);
|
|
@@ -15,6 +15,7 @@ export class EventValidationRequest {
|
|
|
15
15
|
constructor(
|
|
16
16
|
public contractAddress: AztecAddress,
|
|
17
17
|
public eventTypeId: EventSelector,
|
|
18
|
+
public randomness: Fr,
|
|
18
19
|
public serializedEvent: Fr[],
|
|
19
20
|
public eventCommitment: Fr,
|
|
20
21
|
public txHash: TxHash,
|
|
@@ -27,6 +28,8 @@ export class EventValidationRequest {
|
|
|
27
28
|
const contractAddress = AztecAddress.fromField(reader.readField());
|
|
28
29
|
const eventTypeId = EventSelector.fromField(reader.readField());
|
|
29
30
|
|
|
31
|
+
const randomness = reader.readField();
|
|
32
|
+
|
|
30
33
|
const eventStorage = reader.readFieldArray(MAX_EVENT_SERIALIZED_LEN);
|
|
31
34
|
const eventLen = reader.readField().toNumber();
|
|
32
35
|
const serializedEvent = eventStorage.slice(0, eventLen);
|
|
@@ -38,6 +41,7 @@ export class EventValidationRequest {
|
|
|
38
41
|
return new EventValidationRequest(
|
|
39
42
|
contractAddress,
|
|
40
43
|
eventTypeId,
|
|
44
|
+
randomness,
|
|
41
45
|
serializedEvent,
|
|
42
46
|
eventCommitment,
|
|
43
47
|
txHash,
|
|
@@ -85,7 +85,6 @@ export async function executePrivateFunction(
|
|
|
85
85
|
|
|
86
86
|
const rawReturnValues = await privateExecutionOracle.privateLoadFromExecutionCache(publicInputs.returnsHash);
|
|
87
87
|
|
|
88
|
-
const noteHashLeafIndexMap = privateExecutionOracle.getNoteHashLeafIndexMap();
|
|
89
88
|
const newNotes = privateExecutionOracle.getNewNotes();
|
|
90
89
|
const noteHashNullifierCounterMap = privateExecutionOracle.getNoteHashNullifierCounterMap();
|
|
91
90
|
const offchainEffects = privateExecutionOracle.getOffchainEffects();
|
|
@@ -108,7 +107,6 @@ export async function executePrivateFunction(
|
|
|
108
107
|
Buffer.from(artifact.verificationKey!, 'base64'),
|
|
109
108
|
partialWitness,
|
|
110
109
|
publicInputs,
|
|
111
|
-
noteHashLeafIndexMap,
|
|
112
110
|
newNotes,
|
|
113
111
|
noteHashNullifierCounterMap,
|
|
114
112
|
rawReturnValues,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from '@aztec/stdlib/abi';
|
|
15
15
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
16
16
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
17
|
-
import {
|
|
17
|
+
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
18
18
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
19
19
|
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
20
20
|
import { type ContractClassLog, DirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs';
|
|
@@ -64,16 +64,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
64
64
|
* Users can also use this to get a clearer idea of what's happened during a simulation.
|
|
65
65
|
*/
|
|
66
66
|
private newNotes: NoteAndSlot[] = [];
|
|
67
|
-
/**
|
|
68
|
-
* Notes from previous transactions that are returned to the oracle call `getNotes` during this execution.
|
|
69
|
-
* The mapping maps from the unique siloed note hash to the index for notes created in private executions.
|
|
70
|
-
* It maps from siloed note hash to the index for notes created by public functions.
|
|
71
|
-
*
|
|
72
|
-
* They are not part of the ExecutionNoteCache and being forwarded to nested contexts via `extend()`
|
|
73
|
-
* because these notes are meant to be maintained on a per-call basis
|
|
74
|
-
* They should act as references for the read requests output by an app circuit via public inputs.
|
|
75
|
-
*/
|
|
76
|
-
private noteHashLeafIndexMap: Map<bigint, bigint> = new Map();
|
|
77
67
|
private noteHashNullifierCounterMap: Map<number, number> = new Map();
|
|
78
68
|
private contractClassLogs: CountedContractClassLog[] = [];
|
|
79
69
|
private offchainEffects: { data: Fr[] }[] = [];
|
|
@@ -104,6 +94,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
104
94
|
senderAddressBookStore: SenderAddressBookStore,
|
|
105
95
|
capsuleStore: CapsuleStore,
|
|
106
96
|
privateEventStore: PrivateEventStore,
|
|
97
|
+
jobId: string,
|
|
107
98
|
private totalPublicCalldataCount: number = 0,
|
|
108
99
|
protected sideEffectCounter: number = 0,
|
|
109
100
|
log = createLogger('simulator:client_execution_context'),
|
|
@@ -126,6 +117,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
126
117
|
senderAddressBookStore,
|
|
127
118
|
capsuleStore,
|
|
128
119
|
privateEventStore,
|
|
120
|
+
jobId,
|
|
129
121
|
log,
|
|
130
122
|
scopes,
|
|
131
123
|
);
|
|
@@ -160,14 +152,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
160
152
|
return toACVMWitness(0, fields);
|
|
161
153
|
}
|
|
162
154
|
|
|
163
|
-
/**
|
|
164
|
-
* The KernelProver will use this to fully populate witnesses and provide hints to the kernel circuit
|
|
165
|
-
* regarding which note hash each settled read request corresponds to.
|
|
166
|
-
*/
|
|
167
|
-
public getNoteHashLeafIndexMap() {
|
|
168
|
-
return this.noteHashLeafIndexMap;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
155
|
/**
|
|
172
156
|
* Get the data for the newly created notes.
|
|
173
157
|
*/
|
|
@@ -402,23 +386,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
402
386
|
.join(', ')}`,
|
|
403
387
|
);
|
|
404
388
|
|
|
405
|
-
const noteHashesAndIndexes = await Promise.all(
|
|
406
|
-
notes.map(async n => {
|
|
407
|
-
if (n.index !== undefined) {
|
|
408
|
-
const siloedNoteHash = await siloNoteHash(n.contractAddress, n.noteHash);
|
|
409
|
-
const uniqueNoteHash = await computeUniqueNoteHash(n.noteNonce, siloedNoteHash);
|
|
410
|
-
|
|
411
|
-
return { hash: uniqueNoteHash, index: n.index };
|
|
412
|
-
}
|
|
413
|
-
}),
|
|
414
|
-
);
|
|
415
|
-
|
|
416
|
-
noteHashesAndIndexes
|
|
417
|
-
.filter(n => n !== undefined)
|
|
418
|
-
.forEach(n => {
|
|
419
|
-
this.noteHashLeafIndexMap.set(n!.hash.toBigInt(), n!.index);
|
|
420
|
-
});
|
|
421
|
-
|
|
422
389
|
return notes;
|
|
423
390
|
}
|
|
424
391
|
|
|
@@ -586,6 +553,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
586
553
|
this.senderAddressBookStore,
|
|
587
554
|
this.capsuleStore,
|
|
588
555
|
this.privateEventStore,
|
|
556
|
+
this.jobId,
|
|
589
557
|
this.totalPublicCalldataCount,
|
|
590
558
|
sideEffectCounter,
|
|
591
559
|
this.log,
|
|
@@ -64,6 +64,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
64
64
|
protected readonly senderAddressBookStore: SenderAddressBookStore,
|
|
65
65
|
protected readonly capsuleStore: CapsuleStore,
|
|
66
66
|
protected readonly privateEventStore: PrivateEventStore,
|
|
67
|
+
protected readonly jobId: string,
|
|
67
68
|
protected log = createLogger('simulator:client_view_context'),
|
|
68
69
|
protected readonly scopes?: AztecAddress[],
|
|
69
70
|
) {}
|
|
@@ -412,6 +413,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
412
413
|
eventService.deliverEvent(
|
|
413
414
|
request.contractAddress,
|
|
414
415
|
request.eventTypeId,
|
|
416
|
+
request.randomness,
|
|
415
417
|
request.serializedEvent,
|
|
416
418
|
request.eventCommitment,
|
|
417
419
|
request.txHash,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BBPrivateKernelProver } from '@aztec/bb-prover/client';
|
|
1
2
|
import { BBBundlePrivateKernelProver } from '@aztec/bb-prover/client/bundle';
|
|
2
3
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -49,7 +50,12 @@ export async function createPXE(
|
|
|
49
50
|
? loggers.prover
|
|
50
51
|
: createLogger('pxe:bb:wasm:bundle' + (logSuffix ? `:${logSuffix}` : ''));
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
let prover;
|
|
54
|
+
if (options.proverOrOptions instanceof BBPrivateKernelProver) {
|
|
55
|
+
prover = options.proverOrOptions;
|
|
56
|
+
} else {
|
|
57
|
+
prover = new BBBundlePrivateKernelProver(simulator, { ...options.proverOrOptions, logger: proverLogger });
|
|
58
|
+
}
|
|
53
59
|
const protocolContractsProvider = new BundledProtocolContractsProvider();
|
|
54
60
|
|
|
55
61
|
const pxeLogger = loggers.pxe ? loggers.pxe : createLogger('pxe:service' + (logSuffix ? `:${logSuffix}` : ''));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BBPrivateKernelProver } from '@aztec/bb-prover/client';
|
|
1
2
|
import { BBLazyPrivateKernelProver } from '@aztec/bb-prover/client/lazy';
|
|
2
3
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -48,8 +49,12 @@ export async function createPXE(
|
|
|
48
49
|
? loggers.prover
|
|
49
50
|
: createLogger('pxe:bb:wasm:bundle' + (logSuffix ? `:${logSuffix}` : ''));
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
let prover;
|
|
53
|
+
if (options.proverOrOptions instanceof BBPrivateKernelProver) {
|
|
54
|
+
prover = options.proverOrOptions;
|
|
55
|
+
} else {
|
|
56
|
+
prover = new BBLazyPrivateKernelProver(simulator, { ...options.proverOrOptions, logger: proverLogger });
|
|
57
|
+
}
|
|
53
58
|
const protocolContractsProvider = new LazyProtocolContractsProvider();
|
|
54
59
|
|
|
55
60
|
const pxeLogger = loggers.pxe ? loggers.pxe : createLogger('pxe:service' + (logSuffix ? `:${logSuffix}` : ''));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BBPrivateKernelProverOptions } from '@aztec/bb-prover/client';
|
|
1
2
|
import type { Logger } from '@aztec/foundation/log';
|
|
2
3
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
3
4
|
import type { CircuitSimulator } from '@aztec/simulator/client';
|
|
@@ -6,7 +7,7 @@ import type { PrivateKernelProver } from '@aztec/stdlib/interfaces/client';
|
|
|
6
7
|
export type PXECreationOptions = {
|
|
7
8
|
loggers?: { store?: Logger; pxe?: Logger; prover?: Logger };
|
|
8
9
|
useLogSuffix?: boolean | string;
|
|
9
|
-
|
|
10
|
+
proverOrOptions?: PrivateKernelProver | BBPrivateKernelProverOptions;
|
|
10
11
|
store?: AztecAsyncKVStore;
|
|
11
12
|
simulator?: CircuitSimulator;
|
|
12
13
|
};
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
+
import { BBPrivateKernelProver } from '@aztec/bb-prover/client';
|
|
1
2
|
import { BBBundlePrivateKernelProver } from '@aztec/bb-prover/client/bundle';
|
|
2
3
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
3
|
-
import {
|
|
4
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
+
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
4
6
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
5
|
-
import {
|
|
6
|
-
type CircuitSimulator,
|
|
7
|
-
MemoryCircuitRecorder,
|
|
8
|
-
SimulatorRecorderWrapper,
|
|
9
|
-
WASMSimulator,
|
|
10
|
-
} from '@aztec/simulator/client';
|
|
7
|
+
import { MemoryCircuitRecorder, SimulatorRecorderWrapper, WASMSimulator } from '@aztec/simulator/client';
|
|
11
8
|
import { FileCircuitRecorder } from '@aztec/simulator/testing';
|
|
12
9
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
13
10
|
|
|
@@ -46,9 +43,6 @@ export async function createPXE(
|
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
if (!options.store) {
|
|
49
|
-
// TODO once https://github.com/AztecProtocol/aztec-packages/issues/13656 is fixed, we can remove this and always
|
|
50
|
-
// import the lmdb-v2 version
|
|
51
|
-
const { createStore } = await import('@aztec/kv-store/lmdb-v2');
|
|
52
46
|
const storeLogger = loggers.store
|
|
53
47
|
? loggers.store
|
|
54
48
|
: createLogger('pxe:data:lmdb' + (logSuffix ? `:${logSuffix}` : ''));
|
|
@@ -58,7 +52,13 @@ export async function createPXE(
|
|
|
58
52
|
? loggers.prover
|
|
59
53
|
: createLogger('pxe:bb:native' + (logSuffix ? `:${logSuffix}` : ''));
|
|
60
54
|
|
|
61
|
-
|
|
55
|
+
let prover;
|
|
56
|
+
if (options.proverOrOptions instanceof BBPrivateKernelProver) {
|
|
57
|
+
prover = options.proverOrOptions;
|
|
58
|
+
} else {
|
|
59
|
+
prover = new BBBundlePrivateKernelProver(simulator, { ...options.proverOrOptions, logger: proverLogger });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
62
|
const protocolContractsProvider = new BundledProtocolContractsProvider();
|
|
63
63
|
|
|
64
64
|
const pxeLogger = loggers.pxe ? loggers.pxe : createLogger('pxe:service' + (logSuffix ? `:${logSuffix}` : ''));
|
|
@@ -73,7 +73,3 @@ export async function createPXE(
|
|
|
73
73
|
);
|
|
74
74
|
return pxe;
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
function createProver(simulator: CircuitSimulator, logger?: Logger) {
|
|
78
|
-
return new BBBundlePrivateKernelProver(simulator, logger);
|
|
79
|
-
}
|
|
@@ -19,6 +19,7 @@ export class EventService {
|
|
|
19
19
|
public async deliverEvent(
|
|
20
20
|
contractAddress: AztecAddress,
|
|
21
21
|
selector: EventSelector,
|
|
22
|
+
randomness: Fr,
|
|
22
23
|
content: Fr[],
|
|
23
24
|
eventCommitment: Fr,
|
|
24
25
|
txHash: TxHash,
|
|
@@ -63,6 +64,7 @@ export class EventService {
|
|
|
63
64
|
|
|
64
65
|
return this.privateEventStore.storePrivateEventLog(
|
|
65
66
|
selector,
|
|
67
|
+
randomness,
|
|
66
68
|
content,
|
|
67
69
|
Number(nullifierIndex.data), // Index of the event commitment in the nullifier tree
|
|
68
70
|
{
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Interface that stores must implement to support staged writes.
|
|
7
|
+
*/
|
|
8
|
+
export interface StagedStore {
|
|
9
|
+
/** Unique name identifying this store (used for tracking staged stores from JobCoordinator) */
|
|
10
|
+
readonly storeName: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Commits staged data to main storage.
|
|
14
|
+
* Should be called within a transaction for atomicity.
|
|
15
|
+
*
|
|
16
|
+
* @param jobId - The job identifier
|
|
17
|
+
*/
|
|
18
|
+
commit(jobId: string): Promise<void>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Discards staged data without committing.
|
|
22
|
+
* Called on abort.
|
|
23
|
+
*
|
|
24
|
+
* @param jobId - The job identifier
|
|
25
|
+
*/
|
|
26
|
+
discardStaged(jobId: string): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* JobCoordinator manages job lifecycle and provides crash resilience for PXE operations.
|
|
31
|
+
*
|
|
32
|
+
* It uses a staged writes pattern:
|
|
33
|
+
* 1. When a job begins, a unique job ID is created
|
|
34
|
+
* 2. During the job, all writes go to staging (keyed by job ID)
|
|
35
|
+
* 3. On commit, staging is promoted to main storage
|
|
36
|
+
* 4. On abort, staged data is discarded
|
|
37
|
+
*
|
|
38
|
+
* Note: PXE should only rely on a single JobCoordinator instance, so it can eventually
|
|
39
|
+
* orchestrate concurrent jobs. Right now it doesn't make a difference because we're
|
|
40
|
+
* using a job queue with concurrency=1.
|
|
41
|
+
*/
|
|
42
|
+
export class JobCoordinator {
|
|
43
|
+
private readonly log = createLogger('pxe:job_coordinator');
|
|
44
|
+
|
|
45
|
+
/** The underlying KV store */
|
|
46
|
+
kvStore: AztecAsyncKVStore;
|
|
47
|
+
|
|
48
|
+
#currentJobId: string | undefined;
|
|
49
|
+
#stores: Map<string, StagedStore> = new Map();
|
|
50
|
+
|
|
51
|
+
constructor(kvStore: AztecAsyncKVStore) {
|
|
52
|
+
this.kvStore = kvStore;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Registers a staged store.
|
|
57
|
+
* Must be called during initialization for all stores that need staging support.
|
|
58
|
+
*/
|
|
59
|
+
registerStore(store: StagedStore): void {
|
|
60
|
+
if (this.#stores.has(store.storeName)) {
|
|
61
|
+
throw new Error(`Store "${store.storeName}" is already registered`);
|
|
62
|
+
}
|
|
63
|
+
this.#stores.set(store.storeName, store);
|
|
64
|
+
this.log.debug(`Registered staged store: ${store.storeName}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Registers multiple staged stores.
|
|
69
|
+
*/
|
|
70
|
+
registerStores(stores: StagedStore[]): void {
|
|
71
|
+
for (const store of stores) {
|
|
72
|
+
this.registerStore(store);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Begins a new job and returns a job ID for staged writes.
|
|
78
|
+
*
|
|
79
|
+
* @returns Job ID to pass to store operations
|
|
80
|
+
*/
|
|
81
|
+
beginJob(): string {
|
|
82
|
+
if (this.#currentJobId) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Cannot begin job: job ${this.#currentJobId} is already in progress. ` +
|
|
85
|
+
`This should not happen - ensure jobs are properly committed or aborted.`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const jobId = randomBytes(8).toString('hex');
|
|
90
|
+
this.#currentJobId = jobId;
|
|
91
|
+
|
|
92
|
+
this.log.debug(`Started job ${jobId}`);
|
|
93
|
+
return jobId;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Commits a job by promoting all staged data to main storage.
|
|
98
|
+
*
|
|
99
|
+
* @param jobId - The job ID returned from beginJob
|
|
100
|
+
*/
|
|
101
|
+
async commitJob(jobId: string): Promise<void> {
|
|
102
|
+
if (!this.#currentJobId || this.#currentJobId !== jobId) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Cannot commit job ${jobId}: no matching job in progress. ` + `Current job: ${this.#currentJobId ?? 'none'}`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.log.debug(`Committing job ${jobId}`);
|
|
109
|
+
|
|
110
|
+
// Commit all stores atomically in a single transaction.
|
|
111
|
+
// Each store's commit is a no-op if it has no staged data (but that's up to each store to handle).
|
|
112
|
+
await this.kvStore.transactionAsync(async () => {
|
|
113
|
+
for (const store of this.#stores.values()) {
|
|
114
|
+
await store.commit(jobId);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
this.#currentJobId = undefined;
|
|
119
|
+
this.log.debug(`Job ${jobId} committed successfully`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Aborts a job by discarding all staged data.
|
|
124
|
+
*
|
|
125
|
+
* @param jobId - The job ID returned from beginJob
|
|
126
|
+
*/
|
|
127
|
+
async abortJob(jobId: string): Promise<void> {
|
|
128
|
+
if (!this.#currentJobId || this.#currentJobId !== jobId) {
|
|
129
|
+
// Job may have already been aborted or never started properly
|
|
130
|
+
this.log.warn(`Abort called for job ${jobId} but current job is ${this.#currentJobId ?? 'none'}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.log.debug(`Aborting job ${jobId}`);
|
|
134
|
+
|
|
135
|
+
for (const store of this.#stores.values()) {
|
|
136
|
+
await store.discardStaged(jobId);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.#currentJobId = undefined;
|
|
140
|
+
this.log.debug(`Job ${jobId} aborted`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Checks if there's a job currently in progress.
|
|
145
|
+
*/
|
|
146
|
+
hasJobInProgress(): boolean {
|
|
147
|
+
return this.#currentJobId !== undefined;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -138,7 +138,7 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
async build(oracle: PrivateKernelOracle
|
|
141
|
+
async build(oracle: PrivateKernelOracle) {
|
|
142
142
|
if (privateKernelResetDimensionNames.every(name => !this.requestedDimensions[name])) {
|
|
143
143
|
throw new Error('Reset is not required.');
|
|
144
144
|
}
|
|
@@ -190,7 +190,6 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
190
190
|
this.previousKernel.validationRequests.noteHashReadRequests,
|
|
191
191
|
this.previousKernel.end.noteHashes,
|
|
192
192
|
this.noteHashResetActions,
|
|
193
|
-
noteHashLeafIndexMap,
|
|
194
193
|
),
|
|
195
194
|
await buildNullifierReadRequestHintsFromResetActions(
|
|
196
195
|
{ getNullifierMembershipWitness: getNullifierMembershipWitnessResolver(oracle) },
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
type PrivateCallExecutionResult,
|
|
29
29
|
type PrivateExecutionResult,
|
|
30
30
|
TxRequest,
|
|
31
|
-
collectNoteHashLeafIndexMap,
|
|
32
31
|
collectNoteHashNullifierCounterMap,
|
|
33
32
|
getFinalMinRevertibleSideEffectCounter,
|
|
34
33
|
} from '@aztec/stdlib/tx';
|
|
@@ -101,7 +100,6 @@ export class PrivateKernelExecutionProver {
|
|
|
101
100
|
|
|
102
101
|
const executionSteps: PrivateExecutionStep[] = [];
|
|
103
102
|
|
|
104
|
-
const noteHashLeafIndexMap = collectNoteHashLeafIndexMap(executionResult);
|
|
105
103
|
const noteHashNullifierCounterMap = collectNoteHashNullifierCounterMap(executionResult);
|
|
106
104
|
const minRevertibleSideEffectCounter = getFinalMinRevertibleSideEffectCounter(executionResult);
|
|
107
105
|
const splitCounter = isPrivateOnlyTx ? 0 : minRevertibleSideEffectCounter;
|
|
@@ -116,7 +114,7 @@ export class PrivateKernelExecutionProver {
|
|
|
116
114
|
);
|
|
117
115
|
while (resetBuilder.needsReset()) {
|
|
118
116
|
const witgenTimer = new Timer();
|
|
119
|
-
const privateInputs = await resetBuilder.build(this.oracle
|
|
117
|
+
const privateInputs = await resetBuilder.build(this.oracle);
|
|
120
118
|
output = generateWitnesses
|
|
121
119
|
? await this.proofCreator.generateResetOutput(privateInputs)
|
|
122
120
|
: await this.proofCreator.simulateReset(privateInputs);
|
|
@@ -224,7 +222,7 @@ export class PrivateKernelExecutionProver {
|
|
|
224
222
|
);
|
|
225
223
|
while (resetBuilder.needsReset()) {
|
|
226
224
|
const witgenTimer = new Timer();
|
|
227
|
-
const privateInputs = await resetBuilder.build(this.oracle
|
|
225
|
+
const privateInputs = await resetBuilder.build(this.oracle);
|
|
228
226
|
output = generateWitnesses
|
|
229
227
|
? await this.proofCreator.generateResetOutput(privateInputs)
|
|
230
228
|
: await this.proofCreator.simulateReset(privateInputs);
|
|
@@ -43,7 +43,8 @@ export interface PrivateKernelOracle {
|
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Returns a membership witness with the sibling path and leaf index in our private function indexed merkle tree.
|
|
46
|
-
*/
|
|
46
|
+
*/
|
|
47
|
+
getNoteHashMembershipWitness(noteHash: Fr): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined>;
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Returns a membership witness with the sibling path and leaf index in our nullifier indexed merkle tree.
|
|
@@ -2,7 +2,6 @@ import { NOTE_HASH_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, VK_TREE_HEIGHT } from '
|
|
|
2
2
|
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
3
|
import type { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import type { Tuple } from '@aztec/foundation/serialize';
|
|
6
5
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
7
6
|
import type { KeyStore } from '@aztec/key-store';
|
|
8
7
|
import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
@@ -70,13 +69,8 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
|
|
|
70
69
|
return Promise.resolve(new MembershipWitness(VK_TREE_HEIGHT, BigInt(leafIndex), getVKSiblingPath(leafIndex)));
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return new MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT>(
|
|
76
|
-
path.pathSize,
|
|
77
|
-
leafIndex,
|
|
78
|
-
path.toFields() as Tuple<Fr, typeof NOTE_HASH_TREE_HEIGHT>,
|
|
79
|
-
);
|
|
72
|
+
getNoteHashMembershipWitness(noteHash: Fr): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
73
|
+
return this.node.getNoteHashMembershipWitness(this.blockNumber, noteHash);
|
|
80
74
|
}
|
|
81
75
|
|
|
82
76
|
getNullifierMembershipWitness(nullifier: Fr): Promise<NullifierMembershipWitness | undefined> {
|