@aztec/pxe 0.40.1 → 0.42.0
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/config/index.d.ts.map +1 -1
- package/dest/config/index.js +5 -2
- package/dest/contract_data_oracle/index.d.ts +1 -0
- package/dest/contract_data_oracle/index.d.ts.map +1 -1
- package/dest/contract_data_oracle/index.js +7 -1
- package/dest/contract_data_oracle/private_functions_tree.d.ts.map +1 -1
- package/dest/contract_data_oracle/private_functions_tree.js +2 -2
- package/dest/database/kv_pxe_database.d.ts +1 -1
- package/dest/database/kv_pxe_database.js +2 -2
- package/dest/database/pxe_database.d.ts +5 -5
- package/dest/kernel_oracle/index.d.ts +7 -4
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +9 -4
- package/dest/kernel_prover/kernel_prover.d.ts +3 -0
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +51 -15
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.d.ts +3 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.d.ts.map +1 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.js +11 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.d.ts +5 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.d.ts.map +1 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.js +79 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.d.ts +4 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.d.ts.map +1 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.js +14 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.d.ts +1 -2
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.d.ts.map +1 -1
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.js +11 -53
- package/dest/kernel_prover/private_inputs_builders/index.d.ts +3 -1
- package/dest/kernel_prover/private_inputs_builders/index.d.ts.map +1 -1
- package/dest/kernel_prover/private_inputs_builders/index.js +4 -2
- package/dest/kernel_prover/proving_data_oracle.d.ts +7 -5
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
- package/dest/kernel_prover/test/test_circuit_prover.d.ts +2 -1
- package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/kernel_prover/test/test_circuit_prover.js +14 -3
- package/dest/note_processor/note_processor.d.ts +3 -2
- package/dest/note_processor/note_processor.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +3 -2
- package/dest/note_processor/produce_note_dao.js +4 -20
- package/dest/pxe_http/pxe_http_server.js +3 -3
- package/dest/pxe_service/create_pxe_service.d.ts +1 -1
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +7 -6
- package/dest/pxe_service/pxe_service.d.ts +10 -6
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +45 -73
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +4 -17
- package/dest/simulator/index.d.ts +2 -1
- package/dest/simulator/index.d.ts.map +1 -1
- package/dest/simulator/index.js +1 -1
- package/dest/simulator_oracle/index.d.ts +7 -5
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +10 -8
- package/dest/synchronizer/synchronizer.d.ts +9 -1
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +16 -8
- package/package.json +14 -14
- package/src/config/index.ts +11 -1
- package/src/contract_data_oracle/index.ts +7 -0
- package/src/contract_data_oracle/private_functions_tree.ts +3 -1
- package/src/database/kv_pxe_database.ts +2 -2
- package/src/database/pxe_database.ts +5 -5
- package/src/kernel_oracle/index.ts +16 -4
- package/src/kernel_prover/kernel_prover.ts +93 -24
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts +28 -0
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts +250 -0
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.ts +45 -0
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.ts +29 -126
- package/src/kernel_prover/private_inputs_builders/index.ts +3 -1
- package/src/kernel_prover/proving_data_oracle.ts +8 -5
- package/src/kernel_prover/test/test_circuit_prover.ts +24 -3
- package/src/note_processor/note_processor.ts +5 -4
- package/src/note_processor/produce_note_dao.ts +3 -19
- package/src/pxe_http/pxe_http_server.ts +2 -2
- package/src/pxe_service/create_pxe_service.ts +10 -7
- package/src/pxe_service/pxe_service.ts +55 -120
- package/src/pxe_service/test/pxe_test_suite.ts +1 -21
- package/src/simulator/index.ts +2 -1
- package/src/simulator_oracle/index.ts +13 -9
- package/src/synchronizer/synchronizer.ts +17 -14
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts +0 -4
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts.map +0 -1
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.js +0 -10
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.ts +0 -30
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BBNativeProofCreator } from '@aztec/bb-prover';
|
|
2
2
|
import { type AztecNode, type ProofCreator } from '@aztec/circuit-types';
|
|
3
3
|
import { randomBytes } from '@aztec/foundation/crypto';
|
|
4
|
-
import {
|
|
4
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
+
import { KeyStore } from '@aztec/key-store';
|
|
5
6
|
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
|
|
6
7
|
import { initStoreForRollup } from '@aztec/kv-store/utils';
|
|
7
8
|
import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
|
|
@@ -19,7 +20,7 @@ import { PXEService } from './pxe_service.js';
|
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Create and start an PXEService instance with the given AztecNode.
|
|
22
|
-
* If no keyStore or database is provided, it will use
|
|
23
|
+
* If no keyStore or database is provided, it will use KeyStore and MemoryDB as default values.
|
|
23
24
|
* Returns a Promise that resolves to the started PXEService instance.
|
|
24
25
|
*
|
|
25
26
|
* @param aztecNode - The AztecNode instance to be used by the server.
|
|
@@ -41,9 +42,7 @@ export async function createPXEService(
|
|
|
41
42
|
const keyStorePath = config.dataDirectory ? join(config.dataDirectory, 'pxe_key_store') : undefined;
|
|
42
43
|
const l1Contracts = await aztecNode.getL1ContractAddresses();
|
|
43
44
|
|
|
44
|
-
const keyStore = new
|
|
45
|
-
await initStoreForRollup(AztecLmdbStore.open(keyStorePath), l1Contracts.rollupAddress),
|
|
46
|
-
);
|
|
45
|
+
const keyStore = new KeyStore(await initStoreForRollup(AztecLmdbStore.open(keyStorePath), l1Contracts.rollupAddress));
|
|
47
46
|
const db = new KVPxeDatabase(await initStoreForRollup(AztecLmdbStore.open(pxeDbPath), l1Contracts.rollupAddress));
|
|
48
47
|
|
|
49
48
|
// (@PhilWindle) Temporary validation until WASM is implemented
|
|
@@ -54,7 +53,11 @@ export async function createPXEService(
|
|
|
54
53
|
}
|
|
55
54
|
prover = !config.proverEnabled
|
|
56
55
|
? new TestProofCreator()
|
|
57
|
-
: new BBNativeProofCreator(
|
|
56
|
+
: new BBNativeProofCreator(
|
|
57
|
+
config.bbBinaryPath!,
|
|
58
|
+
config.bbWorkingDirectory!,
|
|
59
|
+
createDebugLogger('aztec:pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : '')),
|
|
60
|
+
);
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
const server = new PXEService(keyStore, aztecNode, db, prover, config, logSuffix);
|
|
@@ -62,7 +65,7 @@ export async function createPXEService(
|
|
|
62
65
|
getCanonicalClassRegisterer(),
|
|
63
66
|
getCanonicalInstanceDeployer(),
|
|
64
67
|
getCanonicalMultiCallEntrypointContract(),
|
|
65
|
-
getCanonicalGasToken(
|
|
68
|
+
getCanonicalGasToken(),
|
|
66
69
|
getCanonicalKeyRegistry(),
|
|
67
70
|
]) {
|
|
68
71
|
await server.registerContract(contract);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type AuthWitness,
|
|
3
3
|
type AztecNode,
|
|
4
|
+
EncryptedNoteTxL2Logs,
|
|
4
5
|
EncryptedTxL2Logs,
|
|
5
6
|
ExtendedNote,
|
|
6
7
|
type FunctionCall,
|
|
7
8
|
type GetUnencryptedLogsResponse,
|
|
8
|
-
type KeyStore,
|
|
9
9
|
type L2Block,
|
|
10
10
|
type LogFilter,
|
|
11
11
|
MerkleTreeId,
|
|
12
12
|
type NoteFilter,
|
|
13
13
|
type PXE,
|
|
14
|
+
type PXEInfo,
|
|
14
15
|
type ProofCreator,
|
|
15
16
|
SimulatedTx,
|
|
16
17
|
SimulationError,
|
|
@@ -22,32 +23,32 @@ import {
|
|
|
22
23
|
UnencryptedTxL2Logs,
|
|
23
24
|
isNoirCallStackUnresolved,
|
|
24
25
|
} from '@aztec/circuit-types';
|
|
25
|
-
import { type TxPXEProcessingStats } from '@aztec/circuit-types/stats';
|
|
26
26
|
import {
|
|
27
27
|
AztecAddress,
|
|
28
|
-
CallRequest,
|
|
29
28
|
type CompleteAddress,
|
|
30
|
-
FunctionData,
|
|
31
|
-
MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
32
29
|
type PartialAddress,
|
|
33
|
-
type PrivateKernelTailCircuitPublicInputs,
|
|
34
|
-
type PublicCallRequest,
|
|
35
30
|
computeContractClassId,
|
|
36
31
|
getContractClassFromArtifact,
|
|
37
32
|
} from '@aztec/circuits.js';
|
|
38
33
|
import { computeNoteHashNonce, siloNullifier } from '@aztec/circuits.js/hash';
|
|
39
34
|
import { type ContractArtifact, type DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi';
|
|
40
|
-
import {
|
|
41
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
35
|
+
import { type Fq, Fr } from '@aztec/foundation/fields';
|
|
42
36
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
43
37
|
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
44
|
-
import {
|
|
38
|
+
import { type KeyStore } from '@aztec/key-store';
|
|
39
|
+
import { getCanonicalClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
|
|
40
|
+
import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token';
|
|
41
|
+
import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
|
|
42
|
+
import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry';
|
|
43
|
+
import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint';
|
|
45
44
|
import {
|
|
46
45
|
type AcirSimulator,
|
|
47
46
|
type ExecutionResult,
|
|
47
|
+
accumulateReturnValues,
|
|
48
48
|
collectEnqueuedPublicFunctionCalls,
|
|
49
49
|
collectPublicTeardownFunctionCall,
|
|
50
50
|
collectSortedEncryptedLogs,
|
|
51
|
+
collectSortedNoteEncryptedLogs,
|
|
51
52
|
collectSortedUnencryptedLogs,
|
|
52
53
|
resolveOpcodeLocations,
|
|
53
54
|
} from '@aztec/simulator';
|
|
@@ -71,7 +72,7 @@ export class PXEService implements PXE {
|
|
|
71
72
|
private contractDataOracle: ContractDataOracle;
|
|
72
73
|
private simulator: AcirSimulator;
|
|
73
74
|
private log: DebugLogger;
|
|
74
|
-
private
|
|
75
|
+
private packageVersion: string;
|
|
75
76
|
// serialize synchronizer and calls to proveTx.
|
|
76
77
|
// ensures that state is not changed while simulating
|
|
77
78
|
private jobQueue = new SerialQueue();
|
|
@@ -88,7 +89,7 @@ export class PXEService implements PXE {
|
|
|
88
89
|
this.synchronizer = new Synchronizer(node, db, this.jobQueue, logSuffix);
|
|
89
90
|
this.contractDataOracle = new ContractDataOracle(db);
|
|
90
91
|
this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle);
|
|
91
|
-
this.
|
|
92
|
+
this.packageVersion = getPackageInfo().version;
|
|
92
93
|
|
|
93
94
|
this.jobQueue.start();
|
|
94
95
|
}
|
|
@@ -159,6 +160,10 @@ export class PXEService implements PXE {
|
|
|
159
160
|
return this.db.getAuthWitness(messageHash);
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
async rotateNskM(account: AztecAddress, secretKey: Fq): Promise<void> {
|
|
164
|
+
await this.keyStore.rotateMasterNullifierKey(account, secretKey);
|
|
165
|
+
}
|
|
166
|
+
|
|
162
167
|
public addCapsule(capsule: Fr[]) {
|
|
163
168
|
return this.db.addCapsule(capsule);
|
|
164
169
|
}
|
|
@@ -207,14 +212,6 @@ export class PXEService implements PXE {
|
|
|
207
212
|
return Promise.resolve(account);
|
|
208
213
|
}
|
|
209
214
|
|
|
210
|
-
public async getRegisteredAccountPublicKeysHash(address: AztecAddress): Promise<Fr | undefined> {
|
|
211
|
-
const accounts = await this.keyStore.getAccounts();
|
|
212
|
-
if (!accounts.some(account => account.equals(address))) {
|
|
213
|
-
return undefined;
|
|
214
|
-
}
|
|
215
|
-
return this.keyStore.getPublicKeysHash(address);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
215
|
public async registerRecipient(recipient: CompleteAddress): Promise<void> {
|
|
219
216
|
const wasAdded = await this.db.addCompleteAddress(recipient);
|
|
220
217
|
|
|
@@ -428,25 +425,13 @@ export class PXEService implements PXE {
|
|
|
428
425
|
simulatePublic: boolean,
|
|
429
426
|
msgSender: AztecAddress | undefined = undefined,
|
|
430
427
|
): Promise<SimulatedTx> {
|
|
431
|
-
if (!txRequest.functionData.isPrivate) {
|
|
432
|
-
throw new Error(`Public entrypoints are not allowed`);
|
|
433
|
-
}
|
|
434
428
|
return await this.jobQueue.put(async () => {
|
|
435
|
-
const timer = new Timer();
|
|
436
429
|
const simulatedTx = await this.#simulateAndProve(txRequest, msgSender);
|
|
437
430
|
// We log only if the msgSender is undefined, as simulating with a different msgSender
|
|
438
431
|
// is unlikely to be a real transaction, and likely to be only used to read data.
|
|
439
432
|
// Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash)
|
|
440
433
|
// If we log, the `getTxHash` function will throw.
|
|
441
434
|
|
|
442
|
-
if (!msgSender) {
|
|
443
|
-
this.log.debug(`Processed private part of ${simulatedTx.tx.getTxHash()}`, {
|
|
444
|
-
eventName: 'tx-pxe-processing',
|
|
445
|
-
duration: timer.ms(),
|
|
446
|
-
...simulatedTx.tx.getStats(),
|
|
447
|
-
} satisfies TxPXEProcessingStats);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
435
|
if (simulatePublic) {
|
|
451
436
|
simulatedTx.publicOutput = await this.#simulatePublicCalls(simulatedTx.tx);
|
|
452
437
|
}
|
|
@@ -468,7 +453,7 @@ export class PXEService implements PXE {
|
|
|
468
453
|
return txHash;
|
|
469
454
|
}
|
|
470
455
|
|
|
471
|
-
public async
|
|
456
|
+
public async simulateUnconstrained(
|
|
472
457
|
functionName: string,
|
|
473
458
|
args: any[],
|
|
474
459
|
to: AztecAddress,
|
|
@@ -520,28 +505,49 @@ export class PXEService implements PXE {
|
|
|
520
505
|
}
|
|
521
506
|
|
|
522
507
|
return {
|
|
508
|
+
name: functionDao.name,
|
|
523
509
|
args: encodeArguments(functionDao, args),
|
|
524
|
-
|
|
510
|
+
selector: FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
|
|
511
|
+
type: functionDao.functionType,
|
|
525
512
|
to,
|
|
513
|
+
isStatic: functionDao.isStatic,
|
|
514
|
+
returnTypes: functionDao.returnTypes,
|
|
526
515
|
};
|
|
527
516
|
}
|
|
528
517
|
|
|
529
518
|
public async getNodeInfo(): Promise<NodeInfo> {
|
|
530
|
-
const [
|
|
519
|
+
const [nodeVersion, protocolVersion, chainId, contractAddresses, protocolContractAddresses] = await Promise.all([
|
|
520
|
+
this.node.getNodeVersion(),
|
|
531
521
|
this.node.getVersion(),
|
|
532
522
|
this.node.getChainId(),
|
|
533
523
|
this.node.getL1ContractAddresses(),
|
|
524
|
+
this.node.getProtocolContractAddresses(),
|
|
534
525
|
]);
|
|
535
526
|
|
|
536
527
|
const nodeInfo: NodeInfo = {
|
|
537
|
-
nodeVersion
|
|
528
|
+
nodeVersion,
|
|
538
529
|
chainId,
|
|
539
|
-
protocolVersion
|
|
530
|
+
protocolVersion,
|
|
540
531
|
l1ContractAddresses: contractAddresses,
|
|
532
|
+
protocolContractAddresses: protocolContractAddresses,
|
|
541
533
|
};
|
|
534
|
+
|
|
542
535
|
return nodeInfo;
|
|
543
536
|
}
|
|
544
537
|
|
|
538
|
+
public getPXEInfo(): Promise<PXEInfo> {
|
|
539
|
+
return Promise.resolve({
|
|
540
|
+
pxeVersion: this.packageVersion,
|
|
541
|
+
protocolContractAddresses: {
|
|
542
|
+
classRegisterer: getCanonicalClassRegistererAddress(),
|
|
543
|
+
gasToken: getCanonicalGasToken().address,
|
|
544
|
+
instanceDeployer: getCanonicalInstanceDeployer().address,
|
|
545
|
+
keyRegistry: getCanonicalKeyRegistryAddress(),
|
|
546
|
+
multiCallEntrypoint: getCanonicalMultiCallEntrypointAddress(),
|
|
547
|
+
},
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
|
|
545
551
|
/**
|
|
546
552
|
* Retrieves the simulation parameters required to run an ACIR simulation.
|
|
547
553
|
* This includes the contract address, function artifact, and historical tree roots.
|
|
@@ -551,14 +557,10 @@ export class PXEService implements PXE {
|
|
|
551
557
|
*/
|
|
552
558
|
async #getSimulationParameters(execRequest: FunctionCall | TxExecutionRequest) {
|
|
553
559
|
const contractAddress = (execRequest as FunctionCall).to ?? (execRequest as TxExecutionRequest).origin;
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
);
|
|
558
|
-
const debug = await this.contractDataOracle.getFunctionDebugMetadata(
|
|
559
|
-
contractAddress,
|
|
560
|
-
execRequest.functionData.selector,
|
|
561
|
-
);
|
|
560
|
+
const functionSelector =
|
|
561
|
+
(execRequest as FunctionCall).selector ?? (execRequest as TxExecutionRequest).functionSelector;
|
|
562
|
+
const functionArtifact = await this.contractDataOracle.getFunctionArtifact(contractAddress, functionSelector);
|
|
563
|
+
const debug = await this.contractDataOracle.getFunctionDebugMetadata(contractAddress, functionSelector);
|
|
562
564
|
|
|
563
565
|
return {
|
|
564
566
|
contractAddress,
|
|
@@ -665,24 +667,23 @@ export class PXEService implements PXE {
|
|
|
665
667
|
this.log.debug(`Executing kernel prover...`);
|
|
666
668
|
const { proof, publicInputs } = await kernelProver.prove(txExecutionRequest.toTxRequest(), executionResult);
|
|
667
669
|
|
|
670
|
+
const noteEncryptedLogs = new EncryptedNoteTxL2Logs([collectSortedNoteEncryptedLogs(executionResult)]);
|
|
668
671
|
const unencryptedLogs = new UnencryptedTxL2Logs([collectSortedUnencryptedLogs(executionResult)]);
|
|
669
672
|
const encryptedLogs = new EncryptedTxL2Logs([collectSortedEncryptedLogs(executionResult)]);
|
|
670
673
|
const enqueuedPublicFunctions = collectEnqueuedPublicFunctionCalls(executionResult);
|
|
671
674
|
const teardownPublicFunction = collectPublicTeardownFunctionCall(executionResult);
|
|
672
675
|
|
|
673
|
-
// HACK(#1639): Manually patches the ordering of the public call stack
|
|
674
|
-
// TODO(#757): Enforce proper ordering of enqueued public calls
|
|
675
|
-
await this.patchPublicCallStackOrdering(publicInputs, enqueuedPublicFunctions);
|
|
676
|
-
|
|
677
676
|
const tx = new Tx(
|
|
678
677
|
publicInputs,
|
|
679
678
|
proof.binaryProof,
|
|
679
|
+
noteEncryptedLogs,
|
|
680
680
|
encryptedLogs,
|
|
681
681
|
unencryptedLogs,
|
|
682
682
|
enqueuedPublicFunctions,
|
|
683
683
|
teardownPublicFunction,
|
|
684
684
|
);
|
|
685
|
-
|
|
685
|
+
|
|
686
|
+
return new SimulatedTx(tx, accumulateReturnValues(executionResult));
|
|
686
687
|
}
|
|
687
688
|
|
|
688
689
|
/**
|
|
@@ -722,76 +723,6 @@ export class PXEService implements PXE {
|
|
|
722
723
|
);
|
|
723
724
|
}
|
|
724
725
|
|
|
725
|
-
// HACK(#1639): this is a hack to fix ordering of public calls enqueued in the call stack. Since the private kernel
|
|
726
|
-
// cannot keep track of side effects that happen after or before a nested call, we override the public call stack
|
|
727
|
-
// it emits with whatever we got from the simulator collected enqueued calls. As a sanity check, we at least verify
|
|
728
|
-
// that the elements are the same, so we are only tweaking their ordering.
|
|
729
|
-
// See yarn-project/end-to-end/src/e2e_ordering.test.ts
|
|
730
|
-
// See https://github.com/AztecProtocol/aztec-packages/issues/1615
|
|
731
|
-
// TODO(#757): Enforce proper ordering of enqueued public calls
|
|
732
|
-
private async patchPublicCallStackOrdering(
|
|
733
|
-
publicInputs: PrivateKernelTailCircuitPublicInputs,
|
|
734
|
-
enqueuedPublicCalls: PublicCallRequest[],
|
|
735
|
-
) {
|
|
736
|
-
if (!publicInputs.forPublic) {
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
const enqueuedPublicCallStackItems = await Promise.all(enqueuedPublicCalls.map(c => c.toCallRequest()));
|
|
741
|
-
|
|
742
|
-
// Validate all items in enqueued public calls are in the kernel emitted stack
|
|
743
|
-
const enqueuedRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued =>
|
|
744
|
-
publicInputs.forPublic!.end.publicCallStack.find(item => item.equals(enqueued)),
|
|
745
|
-
);
|
|
746
|
-
|
|
747
|
-
const revertibleStackSize = arrayNonEmptyLength(publicInputs.forPublic.end.publicCallStack, item => item.isEmpty());
|
|
748
|
-
|
|
749
|
-
if (enqueuedRevertiblePublicCallStackItems.length !== revertibleStackSize) {
|
|
750
|
-
throw new Error(
|
|
751
|
-
`Enqueued revertible public function calls and revertible public call stack do not match.\nEnqueued calls: ${enqueuedRevertiblePublicCallStackItems
|
|
752
|
-
.map(h => h.hash.toString())
|
|
753
|
-
.join(', ')}\nPublic call stack: ${publicInputs.forPublic.end.publicCallStack
|
|
754
|
-
.map(i => i.toString())
|
|
755
|
-
.join(', ')}`,
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
// Override kernel output
|
|
760
|
-
publicInputs.forPublic.end.publicCallStack = padArrayEnd(
|
|
761
|
-
enqueuedRevertiblePublicCallStackItems,
|
|
762
|
-
CallRequest.empty(),
|
|
763
|
-
MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
764
|
-
);
|
|
765
|
-
|
|
766
|
-
// Do the same for non-revertible
|
|
767
|
-
|
|
768
|
-
const enqueuedNonRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued =>
|
|
769
|
-
publicInputs.forPublic!.endNonRevertibleData.publicCallStack.find(item => item.equals(enqueued)),
|
|
770
|
-
);
|
|
771
|
-
|
|
772
|
-
const nonRevertibleStackSize = arrayNonEmptyLength(
|
|
773
|
-
publicInputs.forPublic.endNonRevertibleData.publicCallStack,
|
|
774
|
-
item => item.isEmpty(),
|
|
775
|
-
);
|
|
776
|
-
|
|
777
|
-
if (enqueuedNonRevertiblePublicCallStackItems.length !== nonRevertibleStackSize) {
|
|
778
|
-
throw new Error(
|
|
779
|
-
`Enqueued non-revertible public function calls and non-revertible public call stack do not match.\nEnqueued calls: ${enqueuedNonRevertiblePublicCallStackItems
|
|
780
|
-
.map(h => h.hash.toString())
|
|
781
|
-
.join(', ')}\nPublic call stack: ${publicInputs.forPublic.endNonRevertibleData.publicCallStack
|
|
782
|
-
.map(i => i.toString())
|
|
783
|
-
.join(', ')}`,
|
|
784
|
-
);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
// Override kernel output
|
|
788
|
-
publicInputs.forPublic.endNonRevertibleData.publicCallStack = padArrayEnd(
|
|
789
|
-
enqueuedNonRevertiblePublicCallStackItems,
|
|
790
|
-
CallRequest.empty(),
|
|
791
|
-
MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
792
|
-
);
|
|
793
|
-
}
|
|
794
|
-
|
|
795
726
|
public async isGlobalStateSynchronized() {
|
|
796
727
|
return await this.synchronizer.isGlobalStateSynchronized();
|
|
797
728
|
}
|
|
@@ -804,6 +735,10 @@ export class PXEService implements PXE {
|
|
|
804
735
|
return Promise.resolve(this.synchronizer.getSyncStatus());
|
|
805
736
|
}
|
|
806
737
|
|
|
738
|
+
public getSyncStats() {
|
|
739
|
+
return Promise.resolve(this.synchronizer.getSyncStats());
|
|
740
|
+
}
|
|
741
|
+
|
|
807
742
|
public async isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
|
|
808
743
|
return !!(await this.node.getContractClass(id));
|
|
809
744
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type PXE,
|
|
3
|
-
TxExecutionRequest,
|
|
4
3
|
randomContractArtifact,
|
|
5
4
|
randomContractInstanceWithAddress,
|
|
6
5
|
randomDeployedContract,
|
|
@@ -9,11 +8,9 @@ import {
|
|
|
9
8
|
AztecAddress,
|
|
10
9
|
CompleteAddress,
|
|
11
10
|
Fr,
|
|
12
|
-
FunctionData,
|
|
13
11
|
INITIAL_L2_BLOCK_NUM,
|
|
14
12
|
Point,
|
|
15
13
|
PublicKeys,
|
|
16
|
-
TxContext,
|
|
17
14
|
getContractClassFromArtifact,
|
|
18
15
|
} from '@aztec/circuits.js';
|
|
19
16
|
|
|
@@ -126,24 +123,7 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
|
|
|
126
123
|
await expect(pxe.registerContract({ instance, artifact })).rejects.toThrow(/Artifact does not match/i);
|
|
127
124
|
});
|
|
128
125
|
|
|
129
|
-
|
|
130
|
-
const functionData = FunctionData.empty();
|
|
131
|
-
functionData.isPrivate = false;
|
|
132
|
-
const txExecutionRequest = TxExecutionRequest.from({
|
|
133
|
-
origin: AztecAddress.random(),
|
|
134
|
-
firstCallArgsHash: new Fr(0),
|
|
135
|
-
functionData,
|
|
136
|
-
txContext: TxContext.empty(),
|
|
137
|
-
argsOfCalls: [],
|
|
138
|
-
authWitnesses: [],
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
await expect(async () => await pxe.proveTx(txExecutionRequest, false)).rejects.toThrow(
|
|
142
|
-
'Public entrypoints are not allowed',
|
|
143
|
-
);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Note: Not testing a successful run of `proveTx`, `sendTx`, `getTxReceipt` and `viewTx` here as it requires
|
|
126
|
+
// Note: Not testing a successful run of `proveTx`, `sendTx`, `getTxReceipt` and `simulateUnconstrained` here as it requires
|
|
147
127
|
// a larger setup and it's sufficiently tested in the e2e tests.
|
|
148
128
|
|
|
149
129
|
it('throws when getting public storage for non-existent contract', async () => {
|
package/src/simulator/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type AztecNode
|
|
1
|
+
import { type AztecNode } from '@aztec/circuit-types';
|
|
2
|
+
import { type KeyStore } from '@aztec/key-store';
|
|
2
3
|
import { AcirSimulator } from '@aztec/simulator';
|
|
3
4
|
|
|
4
5
|
import { ContractDataOracle } from '../contract_data_oracle/index.js';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type AztecNode,
|
|
3
|
-
type KeyStore,
|
|
4
3
|
type L2Block,
|
|
5
4
|
MerkleTreeId,
|
|
6
5
|
type NoteStatus,
|
|
@@ -14,12 +13,14 @@ import {
|
|
|
14
13
|
type Fr,
|
|
15
14
|
type FunctionSelector,
|
|
16
15
|
type Header,
|
|
16
|
+
type KeyValidationRequest,
|
|
17
17
|
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
18
18
|
} from '@aztec/circuits.js';
|
|
19
19
|
import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash';
|
|
20
20
|
import { type FunctionArtifact, getFunctionArtifact } from '@aztec/foundation/abi';
|
|
21
21
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
22
|
-
import { type
|
|
22
|
+
import { type KeyStore } from '@aztec/key-store';
|
|
23
|
+
import { type DBOracle, MessageLoadOracleInputs } from '@aztec/simulator';
|
|
23
24
|
import { type ContractInstance } from '@aztec/types/contracts';
|
|
24
25
|
|
|
25
26
|
import { type ContractDataOracle } from '../contract_data_oracle/index.js';
|
|
@@ -37,17 +38,16 @@ export class SimulatorOracle implements DBOracle {
|
|
|
37
38
|
private log = createDebugLogger('aztec:pxe:simulator_oracle'),
|
|
38
39
|
) {}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountAddress, contractAddress);
|
|
43
|
-
return { masterNullifierPublicKey, appNullifierSecretKey };
|
|
41
|
+
getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest> {
|
|
42
|
+
return this.keyStore.getKeyValidationRequest(pkMHash, contractAddress);
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
async getCompleteAddress(
|
|
47
|
-
const completeAddress = await this.db.getCompleteAddress(
|
|
45
|
+
async getCompleteAddress(account: AztecAddress): Promise<CompleteAddress> {
|
|
46
|
+
const completeAddress = await this.db.getCompleteAddress(account);
|
|
48
47
|
if (!completeAddress) {
|
|
49
48
|
throw new Error(
|
|
50
|
-
`No public key registered for address ${
|
|
49
|
+
`No public key registered for address ${account}.
|
|
50
|
+
Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`,
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
return completeAddress;
|
|
@@ -230,4 +230,8 @@ export class SimulatorOracle implements DBOracle {
|
|
|
230
230
|
public async getBlockNumber(): Promise<number> {
|
|
231
231
|
return await this.aztecNode.getBlockNumber();
|
|
232
232
|
}
|
|
233
|
+
|
|
234
|
+
public getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string> {
|
|
235
|
+
return this.contractDataOracle.getDebugFunctionName(contractAddress, selector);
|
|
236
|
+
}
|
|
233
237
|
}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type AztecNode,
|
|
3
|
-
type KeyStore,
|
|
4
|
-
type L2Block,
|
|
5
|
-
L2BlockL2Logs,
|
|
6
|
-
MerkleTreeId,
|
|
7
|
-
type TxHash,
|
|
8
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { type AztecNode, type L2Block, L2BlockL2Logs, MerkleTreeId, type TxHash } from '@aztec/circuit-types';
|
|
9
2
|
import { type NoteProcessorCaughtUpStats } from '@aztec/circuit-types/stats';
|
|
10
3
|
import { type AztecAddress, type Fr, INITIAL_L2_BLOCK_NUM, type PublicKey } from '@aztec/circuits.js';
|
|
11
4
|
import { type SerialQueue } from '@aztec/foundation/fifo';
|
|
12
5
|
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
13
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
|
+
import { type KeyStore } from '@aztec/key-store';
|
|
14
8
|
|
|
15
9
|
import { type DeferredNoteDao } from '../database/deferred_note_dao.js';
|
|
16
10
|
import { type PxeDatabase } from '../database/index.js';
|
|
@@ -105,18 +99,19 @@ export class Synchronizer {
|
|
|
105
99
|
return false;
|
|
106
100
|
}
|
|
107
101
|
|
|
108
|
-
const
|
|
102
|
+
const noteEncryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
|
|
109
103
|
|
|
110
104
|
// Update latest tree roots from the most recent block
|
|
111
105
|
const latestBlock = blocks[blocks.length - 1];
|
|
112
106
|
await this.setHeaderFromBlock(latestBlock);
|
|
113
107
|
|
|
114
|
-
const logCount = L2BlockL2Logs.getTotalLogCount(
|
|
108
|
+
const logCount = L2BlockL2Logs.getTotalLogCount(noteEncryptedLogs);
|
|
115
109
|
this.log.debug(
|
|
116
110
|
`Forwarding ${logCount} encrypted logs and blocks to ${this.noteProcessors.length} note processors`,
|
|
117
111
|
);
|
|
118
112
|
for (const noteProcessor of this.noteProcessors) {
|
|
119
|
-
|
|
113
|
+
// TODO(#6830): pass in only the blocks
|
|
114
|
+
await noteProcessor.process(blocks, noteEncryptedLogs);
|
|
120
115
|
}
|
|
121
116
|
return true;
|
|
122
117
|
} catch (err) {
|
|
@@ -182,9 +177,9 @@ export class Synchronizer {
|
|
|
182
177
|
throw new Error('No blocks in processor catch up mode');
|
|
183
178
|
}
|
|
184
179
|
|
|
185
|
-
const
|
|
180
|
+
const noteEncryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
|
|
186
181
|
|
|
187
|
-
const logCount = L2BlockL2Logs.getTotalLogCount(
|
|
182
|
+
const logCount = L2BlockL2Logs.getTotalLogCount(noteEncryptedLogs);
|
|
188
183
|
this.log.debug(`Forwarding ${logCount} encrypted logs and blocks to note processors in catch up mode`);
|
|
189
184
|
|
|
190
185
|
for (const noteProcessor of catchUpGroup) {
|
|
@@ -202,7 +197,7 @@ export class Synchronizer {
|
|
|
202
197
|
blocks.length - index
|
|
203
198
|
} blocks`,
|
|
204
199
|
);
|
|
205
|
-
await noteProcessor.process(blocks.slice(index),
|
|
200
|
+
await noteProcessor.process(blocks.slice(index), noteEncryptedLogs.slice(index));
|
|
206
201
|
|
|
207
202
|
if (noteProcessor.status.syncedToBlock === toBlockNumber) {
|
|
208
203
|
// Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`.
|
|
@@ -325,6 +320,14 @@ export class Synchronizer {
|
|
|
325
320
|
};
|
|
326
321
|
}
|
|
327
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Returns the note processor stats.
|
|
325
|
+
* @returns The note processor stats for notes for each public key being tracked.
|
|
326
|
+
*/
|
|
327
|
+
public getSyncStats() {
|
|
328
|
+
return Object.fromEntries(this.noteProcessors.map(n => [n.masterIncomingViewingPublicKey.toString(), n.stats]));
|
|
329
|
+
}
|
|
330
|
+
|
|
328
331
|
/**
|
|
329
332
|
* Retry decoding any deferred notes for the specified contract address.
|
|
330
333
|
* @param contractAddress - the contract address that has just been added
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, PrivateKernelTailOutputs, ScopedNoteHash, ScopedNullifier } from '@aztec/circuits.js';
|
|
2
|
-
import { type Tuple } from '@aztec/foundation/serialize';
|
|
3
|
-
export declare function buildPrivateKernelTailOutputs(prevNoteHashes: Tuple<ScopedNoteHash, typeof MAX_NEW_NOTE_HASHES_PER_TX>, prevNullifiers: Tuple<ScopedNullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>): PrivateKernelTailOutputs;
|
|
4
|
-
//# sourceMappingURL=build_private_kernel_tail_outputs.d.ts.map
|
package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build_private_kernel_tail_outputs.d.ts","sourceRoot":"","sources":["../../../src/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,cAAc,EACd,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,OAAO,0BAA0B,CAAC,EACxE,cAAc,EAAE,KAAK,CAAC,eAAe,EAAE,OAAO,yBAAyB,CAAC,4BAiBzE"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, PrivateKernelTailOutputs, ScopedNoteHash, ScopedNullifier, } from '@aztec/circuits.js';
|
|
2
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
3
|
-
export function buildPrivateKernelTailOutputs(prevNoteHashes, prevNullifiers) {
|
|
4
|
-
// Propagate note hashes that are not linked to a nullifier.
|
|
5
|
-
// Note that note hashes can't link to the first nullifier (counter == 0).
|
|
6
|
-
const noteHashes = padArrayEnd(prevNoteHashes.filter(n => !n.nullifierCounter), ScopedNoteHash.empty(), MAX_NEW_NOTE_HASHES_PER_TX);
|
|
7
|
-
const nullifiers = padArrayEnd(prevNullifiers.filter(n => n.nullifiedNoteHash.isZero()), ScopedNullifier.empty(), MAX_NEW_NULLIFIERS_PER_TX);
|
|
8
|
-
return new PrivateKernelTailOutputs(noteHashes, nullifiers);
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRfcHJpdmF0ZV9rZXJuZWxfdGFpbF9vdXRwdXRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2tlcm5lbF9wcm92ZXIvcHJpdmF0ZV9pbnB1dHNfYnVpbGRlcnMvYnVpbGRfcHJpdmF0ZV9rZXJuZWxfdGFpbF9vdXRwdXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIseUJBQXlCLEVBQ3pCLHdCQUF3QixFQUN4QixjQUFjLEVBQ2QsZUFBZSxHQUNoQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUczRCxNQUFNLFVBQVUsNkJBQTZCLENBQzNDLGNBQXdFLEVBQ3hFLGNBQXdFO0lBRXhFLDREQUE0RDtJQUM1RCwwRUFBMEU7SUFDMUUsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUM1QixjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsRUFDL0MsY0FBYyxDQUFDLEtBQUssRUFBRSxFQUN0QiwwQkFBMEIsQ0FDM0IsQ0FBQztJQUVGLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FDNUIsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUN4RCxlQUFlLENBQUMsS0FBSyxFQUFFLEVBQ3ZCLHlCQUF5QixDQUMxQixDQUFDO0lBRUYsT0FBTyxJQUFJLHdCQUF3QixDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM5RCxDQUFDIn0=
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
3
|
-
MAX_NEW_NULLIFIERS_PER_TX,
|
|
4
|
-
PrivateKernelTailOutputs,
|
|
5
|
-
ScopedNoteHash,
|
|
6
|
-
ScopedNullifier,
|
|
7
|
-
} from '@aztec/circuits.js';
|
|
8
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
9
|
-
import { type Tuple } from '@aztec/foundation/serialize';
|
|
10
|
-
|
|
11
|
-
export function buildPrivateKernelTailOutputs(
|
|
12
|
-
prevNoteHashes: Tuple<ScopedNoteHash, typeof MAX_NEW_NOTE_HASHES_PER_TX>,
|
|
13
|
-
prevNullifiers: Tuple<ScopedNullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
14
|
-
) {
|
|
15
|
-
// Propagate note hashes that are not linked to a nullifier.
|
|
16
|
-
// Note that note hashes can't link to the first nullifier (counter == 0).
|
|
17
|
-
const noteHashes = padArrayEnd(
|
|
18
|
-
prevNoteHashes.filter(n => !n.nullifierCounter),
|
|
19
|
-
ScopedNoteHash.empty(),
|
|
20
|
-
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
const nullifiers = padArrayEnd(
|
|
24
|
-
prevNullifiers.filter(n => n.nullifiedNoteHash.isZero()),
|
|
25
|
-
ScopedNullifier.empty(),
|
|
26
|
-
MAX_NEW_NULLIFIERS_PER_TX,
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
return new PrivateKernelTailOutputs(noteHashes, nullifiers);
|
|
30
|
-
}
|