@aztec/pxe 0.24.0 → 0.26.2
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.js +2 -2
- package/dest/database/deferred_note_dao.d.ts +4 -4
- package/dest/database/deferred_note_dao.d.ts.map +1 -1
- package/dest/database/deferred_note_dao.js +5 -5
- package/dest/database/pxe_database_test_suite.js +4 -4
- package/dest/kernel_oracle/index.d.ts +1 -0
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +4 -1
- package/dest/kernel_prover/hints_builder.d.ts +36 -0
- package/dest/kernel_prover/hints_builder.d.ts.map +1 -0
- package/dest/kernel_prover/hints_builder.js +115 -0
- package/dest/kernel_prover/kernel_prover.d.ts +2 -24
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +26 -97
- package/dest/kernel_prover/proof_creator.d.ts +1 -1
- package/dest/kernel_prover/proof_creator.js +3 -3
- package/dest/kernel_prover/proving_data_oracle.d.ts +2 -0
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
- package/dest/note_processor/note_processor.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +14 -13
- package/dest/note_processor/produce_note_dao.d.ts +2 -2
- package/dest/note_processor/produce_note_dao.d.ts.map +1 -1
- package/dest/note_processor/produce_note_dao.js +5 -5
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +7 -6
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +3 -2
- package/dest/pxe_service/pxe_service.d.ts +5 -3
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +47 -40
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +3 -3
- package/dest/simulator_oracle/index.d.ts +7 -4
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +17 -8
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +14 -42
- package/package.json +13 -13
- package/src/config/index.ts +1 -1
- package/src/database/deferred_note_dao.ts +3 -3
- package/src/database/pxe_database_test_suite.ts +3 -3
- package/src/kernel_oracle/index.ts +4 -0
- package/src/kernel_prover/hints_builder.ts +170 -0
- package/src/kernel_prover/kernel_prover.ts +56 -135
- package/src/kernel_prover/proof_creator.ts +3 -3
- package/src/kernel_prover/proving_data_oracle.ts +3 -0
- package/src/note_processor/note_processor.ts +15 -22
- package/src/note_processor/produce_note_dao.ts +4 -4
- package/src/pxe_http/pxe_http_server.ts +7 -5
- package/src/pxe_service/create_pxe_service.ts +2 -1
- package/src/pxe_service/pxe_service.ts +70 -57
- package/src/pxe_service/test/pxe_test_suite.ts +8 -6
- package/src/simulator_oracle/index.ts +19 -7
- package/src/synchronizer/synchronizer.ts +14 -56
|
@@ -10,18 +10,17 @@ import {
|
|
|
10
10
|
GetUnencryptedLogsResponse,
|
|
11
11
|
KeyStore,
|
|
12
12
|
L2Block,
|
|
13
|
-
L2Tx,
|
|
14
13
|
LogFilter,
|
|
15
14
|
MerkleTreeId,
|
|
16
15
|
NoteFilter,
|
|
17
16
|
PXE,
|
|
18
17
|
SimulationError,
|
|
19
18
|
Tx,
|
|
19
|
+
TxEffect,
|
|
20
20
|
TxExecutionRequest,
|
|
21
21
|
TxHash,
|
|
22
22
|
TxL2Logs,
|
|
23
23
|
TxReceipt,
|
|
24
|
-
TxStatus,
|
|
25
24
|
getNewContractPublicFunctions,
|
|
26
25
|
isNoirCallStackUnresolved,
|
|
27
26
|
} from '@aztec/circuit-types';
|
|
@@ -32,7 +31,8 @@ import {
|
|
|
32
31
|
CompleteAddress,
|
|
33
32
|
FunctionData,
|
|
34
33
|
GrumpkinPrivateKey,
|
|
35
|
-
|
|
34
|
+
MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
35
|
+
MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
36
36
|
PartialAddress,
|
|
37
37
|
PrivateKernelTailCircuitPublicInputs,
|
|
38
38
|
PublicCallRequest,
|
|
@@ -41,9 +41,9 @@ import {
|
|
|
41
41
|
computeSaltedInitializationHash,
|
|
42
42
|
getContractClassFromArtifact,
|
|
43
43
|
} from '@aztec/circuits.js';
|
|
44
|
-
import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/
|
|
44
|
+
import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash';
|
|
45
45
|
import { DecodedReturn, encodeArguments } from '@aztec/foundation/abi';
|
|
46
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
46
|
+
import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection';
|
|
47
47
|
import { Fr } from '@aztec/foundation/fields';
|
|
48
48
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
49
49
|
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
collectUnencryptedLogs,
|
|
57
57
|
resolveOpcodeLocations,
|
|
58
58
|
} from '@aztec/simulator';
|
|
59
|
-
import { ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
59
|
+
import { ContractClassWithId, ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
60
60
|
import { NodeInfo } from '@aztec/types/interfaces';
|
|
61
61
|
|
|
62
62
|
import { PXEServiceConfig, getPackageInfo } from '../config/index.js';
|
|
@@ -162,6 +162,11 @@ export class PXEService implements PXE {
|
|
|
162
162
|
return this.db.getContractInstance(address);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
public async getContractClass(id: Fr): Promise<ContractClassWithId | undefined> {
|
|
166
|
+
const artifact = await this.db.getContractArtifact(id);
|
|
167
|
+
return artifact && getContractClassFromArtifact(artifact);
|
|
168
|
+
}
|
|
169
|
+
|
|
165
170
|
public async registerAccount(privKey: GrumpkinPrivateKey, partialAddress: PartialAddress): Promise<CompleteAddress> {
|
|
166
171
|
const completeAddress = CompleteAddress.fromPrivateKeyAndPartialAddress(privKey, partialAddress);
|
|
167
172
|
const wasAdded = await this.db.addCompleteAddress(completeAddress);
|
|
@@ -330,17 +335,17 @@ export class PXEService implements PXE {
|
|
|
330
335
|
* @remarks More than a single nonce may be returned since there might be more than one nonce for a given note.
|
|
331
336
|
*/
|
|
332
337
|
private async getNoteNonces(note: ExtendedNote): Promise<Fr[]> {
|
|
333
|
-
const tx = await this.node.
|
|
338
|
+
const tx = await this.node.getTxEffect(note.txHash);
|
|
334
339
|
if (!tx) {
|
|
335
340
|
throw new Error(`Unknown tx: ${note.txHash}`);
|
|
336
341
|
}
|
|
337
342
|
|
|
338
343
|
const nonces: Fr[] = [];
|
|
339
|
-
const firstNullifier = tx.
|
|
340
|
-
const
|
|
341
|
-
for (let i = 0; i <
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
+
const firstNullifier = tx.nullifiers[0];
|
|
345
|
+
const hashes = tx.noteHashes;
|
|
346
|
+
for (let i = 0; i < hashes.length; ++i) {
|
|
347
|
+
const hash = hashes[i];
|
|
348
|
+
if (hash.equals(Fr.ZERO)) {
|
|
344
349
|
break;
|
|
345
350
|
}
|
|
346
351
|
|
|
@@ -354,11 +359,11 @@ export class PXEService implements PXE {
|
|
|
354
359
|
);
|
|
355
360
|
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)
|
|
356
361
|
// Remove this once notes added from public also include nonces.
|
|
357
|
-
if (
|
|
362
|
+
if (hash.equals(siloedNoteHash)) {
|
|
358
363
|
nonces.push(Fr.ZERO);
|
|
359
364
|
break;
|
|
360
365
|
}
|
|
361
|
-
if (
|
|
366
|
+
if (hash.equals(uniqueSiloedNoteHash)) {
|
|
362
367
|
nonces.push(nonce);
|
|
363
368
|
}
|
|
364
369
|
}
|
|
@@ -391,7 +396,7 @@ export class PXEService implements PXE {
|
|
|
391
396
|
|
|
392
397
|
const timer = new Timer();
|
|
393
398
|
const tx = await this.#simulateAndProve(txRequest, newContract);
|
|
394
|
-
this.log(`Processed private part of ${tx.
|
|
399
|
+
this.log(`Processed private part of ${tx.getTxHash()}`, {
|
|
395
400
|
eventName: 'tx-pxe-processing',
|
|
396
401
|
duration: timer.ms(),
|
|
397
402
|
...tx.getStats(),
|
|
@@ -399,15 +404,15 @@ export class PXEService implements PXE {
|
|
|
399
404
|
if (simulatePublic) {
|
|
400
405
|
await this.#simulatePublicCalls(tx);
|
|
401
406
|
}
|
|
402
|
-
this.log.info(`Executed local simulation for ${
|
|
407
|
+
this.log.info(`Executed local simulation for ${tx.getTxHash()}`);
|
|
403
408
|
|
|
404
409
|
return tx;
|
|
405
410
|
});
|
|
406
411
|
}
|
|
407
412
|
|
|
408
413
|
public async sendTx(tx: Tx): Promise<TxHash> {
|
|
409
|
-
const txHash =
|
|
410
|
-
if (await this.node.
|
|
414
|
+
const txHash = tx.getTxHash();
|
|
415
|
+
if (await this.node.getTxEffect(txHash)) {
|
|
411
416
|
throw new Error(`A settled tx with equal hash ${txHash.toString()} exists.`);
|
|
412
417
|
}
|
|
413
418
|
this.log.info(`Sending transaction ${txHash}`);
|
|
@@ -432,38 +437,12 @@ export class PXEService implements PXE {
|
|
|
432
437
|
});
|
|
433
438
|
}
|
|
434
439
|
|
|
435
|
-
public
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
// We first check if the tx is in pending (instead of first checking if it is mined) because if we first check
|
|
439
|
-
// for mined and then for pending there could be a race condition where the tx is mined between the two checks
|
|
440
|
-
// and we would incorrectly return a TxReceipt with status DROPPED
|
|
441
|
-
const pendingTx = await this.node.getPendingTxByHash(txHash);
|
|
442
|
-
if (pendingTx) {
|
|
443
|
-
txReceipt = new TxReceipt(txHash, TxStatus.PENDING, '');
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const settledTx = await this.node.getTx(txHash);
|
|
447
|
-
if (settledTx) {
|
|
448
|
-
const deployedContractAddress = settledTx.newContractData.find(
|
|
449
|
-
c => !c.contractAddress.equals(AztecAddress.ZERO),
|
|
450
|
-
)?.contractAddress;
|
|
451
|
-
|
|
452
|
-
txReceipt = new TxReceipt(
|
|
453
|
-
txHash,
|
|
454
|
-
TxStatus.MINED,
|
|
455
|
-
'',
|
|
456
|
-
settledTx.blockHash.toBuffer(),
|
|
457
|
-
settledTx.blockNumber,
|
|
458
|
-
deployedContractAddress,
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return txReceipt;
|
|
440
|
+
public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
441
|
+
return this.node.getTxReceipt(txHash);
|
|
463
442
|
}
|
|
464
443
|
|
|
465
|
-
public
|
|
466
|
-
return
|
|
444
|
+
public getTxEffect(txHash: TxHash): Promise<TxEffect | undefined> {
|
|
445
|
+
return this.node.getTxEffect(txHash);
|
|
467
446
|
}
|
|
468
447
|
|
|
469
448
|
async getBlockNumber(): Promise<number> {
|
|
@@ -647,6 +626,9 @@ export class PXEService implements PXE {
|
|
|
647
626
|
const kernelProver = new KernelProver(kernelOracle);
|
|
648
627
|
this.log(`Executing kernel prover...`);
|
|
649
628
|
const { proof, publicInputs } = await kernelProver.prove(txExecutionRequest.toTxRequest(), executionResult);
|
|
629
|
+
this.log(
|
|
630
|
+
`Needs setup: ${publicInputs.needsSetup}, needs app logic: ${publicInputs.needsAppLogic}, needs teardown: ${publicInputs.needsTeardown}`,
|
|
631
|
+
);
|
|
650
632
|
|
|
651
633
|
const encryptedLogs = new TxL2Logs(collectEncryptedLogs(executionResult));
|
|
652
634
|
const unencryptedLogs = new TxL2Logs(collectUnencryptedLogs(executionResult));
|
|
@@ -714,27 +696,54 @@ export class PXEService implements PXE {
|
|
|
714
696
|
enqueuedPublicCalls: PublicCallRequest[],
|
|
715
697
|
) {
|
|
716
698
|
const enqueuedPublicCallStackItems = await Promise.all(enqueuedPublicCalls.map(c => c.toCallRequest()));
|
|
717
|
-
const { publicCallStack } = publicInputs.end;
|
|
718
699
|
|
|
719
700
|
// Validate all items in enqueued public calls are in the kernel emitted stack
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
true,
|
|
701
|
+
const enqueuedRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued =>
|
|
702
|
+
publicInputs.end.publicCallStack.find(item => item.equals(enqueued)),
|
|
723
703
|
);
|
|
724
704
|
|
|
725
|
-
|
|
705
|
+
const revertibleStackSize = arrayNonEmptyLength(publicInputs.end.publicCallStack, item => item.isEmpty());
|
|
706
|
+
|
|
707
|
+
if (enqueuedRevertiblePublicCallStackItems.length !== revertibleStackSize) {
|
|
726
708
|
throw new Error(
|
|
727
|
-
`Enqueued public function calls and public call stack do not match.\nEnqueued calls: ${
|
|
709
|
+
`Enqueued revertible public function calls and revertible public call stack do not match.\nEnqueued calls: ${enqueuedRevertiblePublicCallStackItems
|
|
728
710
|
.map(h => h.hash.toString())
|
|
729
|
-
.join(', ')}\nPublic call stack: ${publicCallStack.map(i => i.toString()).join(', ')}`,
|
|
711
|
+
.join(', ')}\nPublic call stack: ${publicInputs.end.publicCallStack.map(i => i.toString()).join(', ')}`,
|
|
730
712
|
);
|
|
731
713
|
}
|
|
732
714
|
|
|
733
715
|
// Override kernel output
|
|
734
716
|
publicInputs.end.publicCallStack = padArrayEnd(
|
|
735
|
-
|
|
717
|
+
enqueuedRevertiblePublicCallStackItems,
|
|
718
|
+
CallRequest.empty(),
|
|
719
|
+
MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
720
|
+
);
|
|
721
|
+
|
|
722
|
+
// Do the same for non-revertible
|
|
723
|
+
|
|
724
|
+
const enqueuedNonRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued =>
|
|
725
|
+
publicInputs.endNonRevertibleData.publicCallStack.find(item => item.equals(enqueued)),
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
const nonRevertibleStackSize = arrayNonEmptyLength(publicInputs.endNonRevertibleData.publicCallStack, item =>
|
|
729
|
+
item.isEmpty(),
|
|
730
|
+
);
|
|
731
|
+
|
|
732
|
+
if (enqueuedNonRevertiblePublicCallStackItems.length !== nonRevertibleStackSize) {
|
|
733
|
+
throw new Error(
|
|
734
|
+
`Enqueued non-revertible public function calls and non-revertible public call stack do not match.\nEnqueued calls: ${enqueuedNonRevertiblePublicCallStackItems
|
|
735
|
+
.map(h => h.hash.toString())
|
|
736
|
+
.join(', ')}\nPublic call stack: ${publicInputs.endNonRevertibleData.publicCallStack
|
|
737
|
+
.map(i => i.toString())
|
|
738
|
+
.join(', ')}`,
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Override kernel output
|
|
743
|
+
publicInputs.endNonRevertibleData.publicCallStack = padArrayEnd(
|
|
744
|
+
enqueuedNonRevertiblePublicCallStackItems,
|
|
736
745
|
CallRequest.empty(),
|
|
737
|
-
|
|
746
|
+
MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
738
747
|
);
|
|
739
748
|
}
|
|
740
749
|
|
|
@@ -753,4 +762,8 @@ export class PXEService implements PXE {
|
|
|
753
762
|
public getKeyStore() {
|
|
754
763
|
return this.keyStore;
|
|
755
764
|
}
|
|
765
|
+
|
|
766
|
+
public async isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
|
|
767
|
+
return !!(await this.node.getContractClass(id));
|
|
768
|
+
}
|
|
756
769
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { DeployedContract, PXE, TxExecutionRequest, randomDeployedContract } from '@aztec/circuit-types';
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
+
AztecAddress,
|
|
4
|
+
CompleteAddress,
|
|
5
|
+
Fr,
|
|
6
|
+
FunctionData,
|
|
3
7
|
INITIAL_L2_BLOCK_NUM,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from '@aztec/circuit-types';
|
|
8
|
-
import { AztecAddress, CompleteAddress, Fr, FunctionData, Point, TxContext } from '@aztec/circuits.js';
|
|
8
|
+
Point,
|
|
9
|
+
TxContext,
|
|
10
|
+
} from '@aztec/circuits.js';
|
|
9
11
|
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
10
12
|
import { ConstantKeyPair } from '@aztec/key-store';
|
|
11
13
|
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { FunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi';
|
|
20
20
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
21
21
|
import { DBOracle, KeyPair, MessageLoadOracleInputs } from '@aztec/simulator';
|
|
22
|
+
import { ContractInstance } from '@aztec/types/contracts';
|
|
22
23
|
|
|
23
24
|
import { ContractDataOracle } from '../contract_data_oracle/index.js';
|
|
24
25
|
import { PxeDatabase } from '../database/index.js';
|
|
@@ -52,6 +53,14 @@ export class SimulatorOracle implements DBOracle {
|
|
|
52
53
|
return completeAddress;
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
async getContractInstance(address: AztecAddress): Promise<ContractInstance> {
|
|
57
|
+
const instance = await this.db.getContractInstance(address);
|
|
58
|
+
if (!instance) {
|
|
59
|
+
throw new Error(`No contract instance found for address ${address.toString()}`);
|
|
60
|
+
}
|
|
61
|
+
return instance;
|
|
62
|
+
}
|
|
63
|
+
|
|
55
64
|
async getAuthWitness(messageHash: Fr): Promise<Fr[]> {
|
|
56
65
|
const witness = await this.db.getAuthWitness(messageHash);
|
|
57
66
|
if (!witness) {
|
|
@@ -119,19 +128,18 @@ export class SimulatorOracle implements DBOracle {
|
|
|
119
128
|
}
|
|
120
129
|
|
|
121
130
|
/**
|
|
122
|
-
* Retrieves the L1ToL2Message associated with a specific
|
|
123
|
-
* Throws an error if the
|
|
131
|
+
* Retrieves the L1ToL2Message associated with a specific entry key
|
|
132
|
+
* Throws an error if the entry key is not found
|
|
124
133
|
*
|
|
125
|
-
* @param
|
|
134
|
+
* @param entryKey - The key of the message to be retrieved
|
|
126
135
|
* @returns A promise that resolves to the message data, a sibling path and the
|
|
127
136
|
* index of the message in the l1ToL2MessageTree
|
|
128
137
|
*/
|
|
129
|
-
async
|
|
130
|
-
const messageAndIndex = await this.aztecNode.getL1ToL2MessageAndIndex(
|
|
131
|
-
const message = messageAndIndex.message;
|
|
138
|
+
async getL1ToL2MembershipWitness(entryKey: Fr): Promise<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> {
|
|
139
|
+
const messageAndIndex = await this.aztecNode.getL1ToL2MessageAndIndex(entryKey);
|
|
132
140
|
const index = messageAndIndex.index;
|
|
133
141
|
const siblingPath = await this.aztecNode.getL1ToL2MessageSiblingPath('latest', index);
|
|
134
|
-
return new MessageLoadOracleInputs(
|
|
142
|
+
return new MessageLoadOracleInputs(index, siblingPath);
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
/**
|
|
@@ -168,6 +176,10 @@ export class SimulatorOracle implements DBOracle {
|
|
|
168
176
|
}
|
|
169
177
|
}
|
|
170
178
|
|
|
179
|
+
public async getNullifierMembershipWitnessAtLatestBlock(nullifier: Fr) {
|
|
180
|
+
return this.getNullifierMembershipWitness(await this.getBlockNumber(), nullifier);
|
|
181
|
+
}
|
|
182
|
+
|
|
171
183
|
public getNullifierMembershipWitness(
|
|
172
184
|
blockNumber: number,
|
|
173
185
|
nullifier: Fr,
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AztecNode,
|
|
3
|
-
INITIAL_L2_BLOCK_NUM,
|
|
4
|
-
KeyStore,
|
|
5
|
-
L2BlockContext,
|
|
6
|
-
L2BlockL2Logs,
|
|
7
|
-
LogType,
|
|
8
|
-
MerkleTreeId,
|
|
9
|
-
TxHash,
|
|
10
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { AztecNode, KeyStore, L2BlockContext, L2BlockL2Logs, MerkleTreeId, TxHash } from '@aztec/circuit-types';
|
|
11
2
|
import { NoteProcessorCaughtUpStats } from '@aztec/circuit-types/stats';
|
|
12
|
-
import { AztecAddress, Fr, PublicKey } from '@aztec/circuits.js';
|
|
3
|
+
import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, PublicKey } from '@aztec/circuits.js';
|
|
13
4
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
14
5
|
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
15
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
@@ -102,38 +93,12 @@ export class Synchronizer {
|
|
|
102
93
|
protected async work(limit = 1): Promise<boolean> {
|
|
103
94
|
const from = this.getSynchedBlockNumber() + 1;
|
|
104
95
|
try {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (!encryptedLogs.length) {
|
|
96
|
+
const blocks = await this.node.getBlocks(from, limit);
|
|
97
|
+
if (blocks.length === 0) {
|
|
108
98
|
return false;
|
|
109
99
|
}
|
|
110
100
|
|
|
111
|
-
|
|
112
|
-
if (!unencryptedLogs.length) {
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Note: If less than `limit` encrypted logs is returned, then we fetch only that number of blocks.
|
|
117
|
-
const blocks = await this.node.getBlocks(from, encryptedLogs.length);
|
|
118
|
-
if (!blocks.length) {
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (blocks.length !== encryptedLogs.length) {
|
|
123
|
-
// "Trim" the encrypted logs to match the number of blocks.
|
|
124
|
-
encryptedLogs = encryptedLogs.slice(0, blocks.length);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (blocks.length !== unencryptedLogs.length) {
|
|
128
|
-
// "Trim" the unencrypted logs to match the number of blocks.
|
|
129
|
-
unencryptedLogs = unencryptedLogs.slice(0, blocks.length);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// attach logs to blocks
|
|
133
|
-
blocks.forEach((block, i) => {
|
|
134
|
-
block.attachLogs(encryptedLogs[i], LogType.ENCRYPTED);
|
|
135
|
-
block.attachLogs(unencryptedLogs[i], LogType.UNENCRYPTED);
|
|
136
|
-
});
|
|
101
|
+
const encryptedLogs = blocks.flatMap(block => block.body.encryptedLogs);
|
|
137
102
|
|
|
138
103
|
// Wrap blocks in block contexts & only keep those that match our query
|
|
139
104
|
const blockContexts = blocks.filter(block => block.number >= from).map(block => new L2BlockContext(block));
|
|
@@ -166,15 +131,19 @@ export class Synchronizer {
|
|
|
166
131
|
|
|
167
132
|
// filter out note processors that are already caught up
|
|
168
133
|
// and sort them by the block number they are lagging behind in ascending order
|
|
169
|
-
|
|
134
|
+
const noteProcessorsToCatchUp: NoteProcessor[] = [];
|
|
135
|
+
|
|
136
|
+
this.noteProcessorsToCatchUp.forEach(noteProcessor => {
|
|
170
137
|
if (noteProcessor.status.syncedToBlock >= toBlockNumber) {
|
|
171
138
|
// Note processor is ahead of main sync, nothing to do
|
|
172
139
|
this.noteProcessors.push(noteProcessor);
|
|
173
|
-
|
|
140
|
+
} else {
|
|
141
|
+
noteProcessorsToCatchUp.push(noteProcessor);
|
|
174
142
|
}
|
|
175
|
-
return true;
|
|
176
143
|
});
|
|
177
144
|
|
|
145
|
+
this.noteProcessorsToCatchUp = noteProcessorsToCatchUp;
|
|
146
|
+
|
|
178
147
|
if (!this.noteProcessorsToCatchUp.length) {
|
|
179
148
|
// No note processors to catch up, nothing to do here,
|
|
180
149
|
// but we return true to continue with the normal flow.
|
|
@@ -200,25 +169,14 @@ export class Synchronizer {
|
|
|
200
169
|
}
|
|
201
170
|
|
|
202
171
|
try {
|
|
203
|
-
|
|
204
|
-
if (!encryptedLogs.length) {
|
|
205
|
-
// This should never happen because this function should only be called when the note processor is lagging
|
|
206
|
-
// behind main sync.
|
|
207
|
-
throw new Error('No encrypted logs in processor catch up mode');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Note: If less than `limit` encrypted logs is returned, then we fetch only that number of blocks.
|
|
211
|
-
const blocks = await this.node.getBlocks(from, encryptedLogs.length);
|
|
172
|
+
const blocks = await this.node.getBlocks(from, limit);
|
|
212
173
|
if (!blocks.length) {
|
|
213
174
|
// This should never happen because this function should only be called when the note processor is lagging
|
|
214
175
|
// behind main sync.
|
|
215
176
|
throw new Error('No blocks in processor catch up mode');
|
|
216
177
|
}
|
|
217
178
|
|
|
218
|
-
|
|
219
|
-
// "Trim" the encrypted logs to match the number of blocks.
|
|
220
|
-
encryptedLogs = encryptedLogs.slice(0, blocks.length);
|
|
221
|
-
}
|
|
179
|
+
const encryptedLogs = blocks.flatMap(block => block.body.encryptedLogs);
|
|
222
180
|
|
|
223
181
|
const blockContexts = blocks.map(block => new L2BlockContext(block));
|
|
224
182
|
|