@aztec/pxe 0.86.0 → 0.87.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/package_info.js +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +39 -8
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.d.ts +0 -1
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +0 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.js +7 -19
- package/dest/pxe_service/error_enriching.d.ts.map +1 -1
- package/dest/pxe_service/error_enriching.js +17 -10
- package/dest/pxe_service/pxe_service.d.ts +5 -5
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +123 -36
- package/dest/storage/note_data_provider/note_dao.d.ts +0 -2
- package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +1 -1
- package/dest/test/pxe_test_suite.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/config/package_info.ts +1 -1
- package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +2 -2
- package/src/private_kernel/private_kernel_execution_prover.ts +32 -4
- package/src/private_kernel/private_kernel_oracle_impl.ts +2 -3
- package/src/pxe_oracle_interface/pxe_oracle_interface.ts +8 -20
- package/src/pxe_service/error_enriching.ts +22 -12
- package/src/pxe_service/pxe_service.ts +185 -56
- package/src/storage/note_data_provider/note_data_provider.ts +22 -20
- package/src/synchronizer/synchronizer.ts +1 -1
|
@@ -16,35 +16,45 @@ export async function enrichSimulationError(
|
|
|
16
16
|
contractDataProvider: ContractDataProvider,
|
|
17
17
|
logger: Logger,
|
|
18
18
|
) {
|
|
19
|
-
// Maps contract addresses to the set of function
|
|
19
|
+
// Maps contract addresses to the set of function selectors that were in error.
|
|
20
20
|
// Map and Set do reference equality for their keys instead of value equality, so we store the string
|
|
21
21
|
// representation to get e.g. different contract address objects with the same address value to match.
|
|
22
|
-
const mentionedFunctions: Map<string, Set<
|
|
22
|
+
const mentionedFunctions: Map<string, Set<FunctionSelector>> = new Map();
|
|
23
23
|
|
|
24
|
-
err.getCallStack().forEach(({ contractAddress,
|
|
24
|
+
err.getCallStack().forEach(({ contractAddress, functionSelector }) => {
|
|
25
25
|
if (!mentionedFunctions.has(contractAddress.toString())) {
|
|
26
26
|
mentionedFunctions.set(contractAddress.toString(), new Set());
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
if (functionSelector) {
|
|
29
|
+
mentionedFunctions.get(contractAddress.toString())!.add(functionSelector);
|
|
30
|
+
}
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
await Promise.all(
|
|
32
|
-
[...mentionedFunctions.entries()].map(async ([contractAddress,
|
|
34
|
+
[...mentionedFunctions.entries()].map(async ([contractAddress, fnSelectors]) => {
|
|
33
35
|
const parsedContractAddress = AztecAddress.fromString(contractAddress);
|
|
34
36
|
const contract = await contractDataProvider.getContract(parsedContractAddress);
|
|
35
37
|
if (contract) {
|
|
36
38
|
err.enrichWithContractName(parsedContractAddress, contract.name);
|
|
37
|
-
for
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
// Map from function selector to function name. It uses a stringified key for the same reason as mentionedFunctions.
|
|
40
|
+
const selectorToNameMap: Map<string, string> = new Map();
|
|
41
|
+
await Promise.all(
|
|
42
|
+
contract.functions.map(async fn => {
|
|
43
|
+
const selector = await FunctionSelector.fromNameAndParameters(fn);
|
|
44
|
+
selectorToNameMap.set(selector.toString(), fn.name);
|
|
45
|
+
}),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
for (const fnSelector of fnSelectors) {
|
|
49
|
+
if (selectorToNameMap.has(fnSelector.toString())) {
|
|
40
50
|
err.enrichWithFunctionName(
|
|
41
51
|
parsedContractAddress,
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
fnSelector,
|
|
53
|
+
selectorToNameMap.get(fnSelector.toString())!,
|
|
44
54
|
);
|
|
45
55
|
} else {
|
|
46
56
|
logger.warn(
|
|
47
|
-
`Could not find function artifact in contract ${contract.name} for function '${
|
|
57
|
+
`Could not find function artifact in contract ${contract.name} for function '${fnSelector}' when enriching error callstack`,
|
|
48
58
|
);
|
|
49
59
|
}
|
|
50
60
|
}
|
|
@@ -85,7 +95,7 @@ export async function enrichPublicSimulationError(
|
|
|
85
95
|
try {
|
|
86
96
|
// Public functions are simulated as a single Brillig entry point.
|
|
87
97
|
// Thus, we can safely assume here that the Brillig function id is `0`.
|
|
88
|
-
const parsedCallStack = resolveOpcodeLocations(noirCallStack, debugInfo, 0);
|
|
98
|
+
const parsedCallStack = resolveOpcodeLocations(noirCallStack, debugInfo.debugSymbols, debugInfo.files, 0);
|
|
89
99
|
err.setNoirCallStack(parsedCallStack);
|
|
90
100
|
} catch (err) {
|
|
91
101
|
logger.warn(
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
} from '@aztec/protocol-contracts';
|
|
15
15
|
import { AcirSimulator, type SimulationProvider, readCurrentClassId } from '@aztec/simulator/client';
|
|
16
16
|
import {
|
|
17
|
-
type AbiDecoded,
|
|
18
17
|
type ContractArtifact,
|
|
19
18
|
EventSelector,
|
|
20
19
|
FunctionCall,
|
|
@@ -57,7 +56,9 @@ import {
|
|
|
57
56
|
type IndexedTxEffect,
|
|
58
57
|
PrivateExecutionResult,
|
|
59
58
|
PrivateSimulationResult,
|
|
59
|
+
type ProvingTimings,
|
|
60
60
|
PublicSimulationOutput,
|
|
61
|
+
type SimulationTimings,
|
|
61
62
|
Tx,
|
|
62
63
|
TxExecutionRequest,
|
|
63
64
|
type TxHash,
|
|
@@ -65,6 +66,7 @@ import {
|
|
|
65
66
|
TxProvingResult,
|
|
66
67
|
type TxReceipt,
|
|
67
68
|
TxSimulationResult,
|
|
69
|
+
UtilitySimulationResult,
|
|
68
70
|
} from '@aztec/stdlib/tx';
|
|
69
71
|
|
|
70
72
|
import { inspect } from 'util';
|
|
@@ -91,6 +93,8 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
91
93
|
* A Private eXecution Environment (PXE) implementation.
|
|
92
94
|
*/
|
|
93
95
|
export class PXEService implements PXE {
|
|
96
|
+
#nodeInfo?: NodeInfo;
|
|
97
|
+
|
|
94
98
|
private constructor(
|
|
95
99
|
private node: AztecNode,
|
|
96
100
|
private synchronizer: Synchronizer,
|
|
@@ -648,23 +652,52 @@ export class PXEService implements PXE {
|
|
|
648
652
|
|
|
649
653
|
public proveTx(
|
|
650
654
|
txRequest: TxExecutionRequest,
|
|
651
|
-
privateExecutionResult
|
|
655
|
+
privateExecutionResult?: PrivateExecutionResult,
|
|
652
656
|
): Promise<TxProvingResult> {
|
|
653
657
|
// We disable proving concurrently mostly out of caution, since it accesses some of our stores. Proving is so
|
|
654
658
|
// computationally demanding that it'd be rare for someone to try to do it concurrently regardless.
|
|
655
659
|
return this.#putInJobQueue(async () => {
|
|
660
|
+
const totalTimer = new Timer();
|
|
656
661
|
try {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
662
|
+
let syncTime: number | undefined;
|
|
663
|
+
if (!privateExecutionResult) {
|
|
664
|
+
const syncTimer = new Timer();
|
|
665
|
+
await this.synchronizer.sync();
|
|
666
|
+
syncTime = syncTimer.ms();
|
|
667
|
+
privateExecutionResult = await this.#executePrivate(txRequest);
|
|
668
|
+
}
|
|
669
|
+
const {
|
|
670
|
+
publicInputs,
|
|
671
|
+
clientIvcProof,
|
|
672
|
+
executionSteps,
|
|
673
|
+
timings: { proving } = {},
|
|
674
|
+
} = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
675
|
+
simulate: false,
|
|
676
|
+
skipFeeEnforcement: false,
|
|
677
|
+
profileMode: 'none',
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
const totalTime = totalTimer.ms();
|
|
681
|
+
|
|
682
|
+
const perFunction = executionSteps.map(({ functionName, timings: { witgen } }) => ({
|
|
683
|
+
functionName,
|
|
684
|
+
time: witgen,
|
|
685
|
+
}));
|
|
686
|
+
|
|
687
|
+
const timings: ProvingTimings = {
|
|
688
|
+
total: totalTime,
|
|
689
|
+
sync: syncTime,
|
|
690
|
+
proving,
|
|
691
|
+
perFunction,
|
|
692
|
+
unaccounted:
|
|
693
|
+
totalTime - ((syncTime ?? 0) + (proving ?? 0) + perFunction.reduce((acc, { time }) => acc + time, 0)),
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
this.log.info(`Proving completed in ${totalTime}ms`, {
|
|
697
|
+
timings,
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!, timings);
|
|
668
701
|
} catch (err: any) {
|
|
669
702
|
throw this.#contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
|
|
670
703
|
}
|
|
@@ -674,10 +707,12 @@ export class PXEService implements PXE {
|
|
|
674
707
|
public profileTx(
|
|
675
708
|
txRequest: TxExecutionRequest,
|
|
676
709
|
profileMode: 'full' | 'execution-steps' | 'gates',
|
|
710
|
+
skipProofGeneration: boolean = true,
|
|
677
711
|
msgSender?: AztecAddress,
|
|
678
712
|
): Promise<TxProfileResult> {
|
|
679
713
|
// We disable concurrent profiles for consistency with simulateTx.
|
|
680
714
|
return this.#putInJobQueue(async () => {
|
|
715
|
+
const totalTimer = new Timer();
|
|
681
716
|
try {
|
|
682
717
|
const txInfo = {
|
|
683
718
|
origin: txRequest.origin,
|
|
@@ -692,16 +727,48 @@ export class PXEService implements PXE {
|
|
|
692
727
|
`Profiling transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
|
|
693
728
|
txInfo,
|
|
694
729
|
);
|
|
730
|
+
const syncTimer = new Timer();
|
|
695
731
|
await this.synchronizer.sync();
|
|
732
|
+
const syncTime = syncTimer.ms();
|
|
733
|
+
|
|
696
734
|
const privateExecutionResult = await this.#executePrivate(txRequest, msgSender);
|
|
697
735
|
|
|
698
|
-
const { executionSteps } = await this.#prove(
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
736
|
+
const { executionSteps, timings: { proving } = {} } = await this.#prove(
|
|
737
|
+
txRequest,
|
|
738
|
+
this.proofCreator,
|
|
739
|
+
privateExecutionResult,
|
|
740
|
+
{
|
|
741
|
+
simulate: skipProofGeneration,
|
|
742
|
+
skipFeeEnforcement: false,
|
|
743
|
+
profileMode,
|
|
744
|
+
},
|
|
745
|
+
);
|
|
703
746
|
|
|
704
|
-
|
|
747
|
+
const totalTime = totalTimer.ms();
|
|
748
|
+
|
|
749
|
+
const perFunction = executionSteps.map(({ functionName, timings: { witgen } }) => ({
|
|
750
|
+
functionName,
|
|
751
|
+
time: witgen,
|
|
752
|
+
}));
|
|
753
|
+
|
|
754
|
+
// Gate computation is time is not relevant for profiling, so we subtract it from the total time.
|
|
755
|
+
const gateCountComputationTime =
|
|
756
|
+
executionSteps.reduce((acc, { timings }) => acc + (timings.gateCount ?? 0), 0) ?? 0;
|
|
757
|
+
|
|
758
|
+
const timings: ProvingTimings = {
|
|
759
|
+
total: totalTime - gateCountComputationTime,
|
|
760
|
+
sync: syncTime,
|
|
761
|
+
proving,
|
|
762
|
+
perFunction,
|
|
763
|
+
unaccounted:
|
|
764
|
+
totalTime -
|
|
765
|
+
((syncTime ?? 0) +
|
|
766
|
+
(proving ?? 0) +
|
|
767
|
+
perFunction.reduce((acc, { time }) => acc + time, 0) +
|
|
768
|
+
gateCountComputationTime),
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
return new TxProfileResult(executionSteps, timings);
|
|
705
772
|
} catch (err: any) {
|
|
706
773
|
throw this.#contextualizeError(
|
|
707
774
|
err,
|
|
@@ -727,6 +794,7 @@ export class PXEService implements PXE {
|
|
|
727
794
|
// delete the same read value, or reading values that another simulation is currently modifying).
|
|
728
795
|
return this.#putInJobQueue(async () => {
|
|
729
796
|
try {
|
|
797
|
+
const totalTimer = new Timer();
|
|
730
798
|
const txInfo = {
|
|
731
799
|
origin: txRequest.origin,
|
|
732
800
|
functionSelector: txRequest.functionSelector,
|
|
@@ -740,32 +808,67 @@ export class PXEService implements PXE {
|
|
|
740
808
|
`Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
|
|
741
809
|
txInfo,
|
|
742
810
|
);
|
|
743
|
-
const
|
|
811
|
+
const syncTimer = new Timer();
|
|
744
812
|
await this.synchronizer.sync();
|
|
813
|
+
const syncTime = syncTimer.ms();
|
|
814
|
+
|
|
745
815
|
const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
|
|
746
816
|
|
|
747
|
-
const { publicInputs } = await this.#prove(
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
817
|
+
const { publicInputs, executionSteps } = await this.#prove(
|
|
818
|
+
txRequest,
|
|
819
|
+
this.proofCreator,
|
|
820
|
+
privateExecutionResult,
|
|
821
|
+
{
|
|
822
|
+
simulate: true,
|
|
823
|
+
skipFeeEnforcement,
|
|
824
|
+
profileMode: 'none',
|
|
825
|
+
},
|
|
826
|
+
);
|
|
752
827
|
|
|
753
828
|
const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
|
|
754
829
|
const simulatedTx = privateSimulationResult.toSimulatedTx();
|
|
830
|
+
let publicSimulationTime: number | undefined;
|
|
755
831
|
let publicOutput: PublicSimulationOutput | undefined;
|
|
756
832
|
if (simulatePublic && publicInputs.forPublic) {
|
|
833
|
+
const publicSimulationTimer = new Timer();
|
|
757
834
|
publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
|
|
835
|
+
publicSimulationTime = publicSimulationTimer.ms();
|
|
758
836
|
}
|
|
759
837
|
|
|
838
|
+
let validationTime: number | undefined;
|
|
760
839
|
if (!skipTxValidation) {
|
|
840
|
+
const validationTimer = new Timer();
|
|
761
841
|
const validationResult = await this.node.isValidTx(simulatedTx, { isSimulation: true, skipFeeEnforcement });
|
|
842
|
+
validationTime = validationTimer.ms();
|
|
762
843
|
if (validationResult.result === 'invalid') {
|
|
763
844
|
throw new Error('The simulated transaction is unable to be added to state and is invalid.');
|
|
764
845
|
}
|
|
765
846
|
}
|
|
766
847
|
|
|
767
848
|
const txHash = await simulatedTx.getTxHash();
|
|
768
|
-
|
|
849
|
+
|
|
850
|
+
const totalTime = totalTimer.ms();
|
|
851
|
+
|
|
852
|
+
const perFunction = executionSteps.map(({ functionName, timings: { witgen } }) => ({
|
|
853
|
+
functionName,
|
|
854
|
+
time: witgen,
|
|
855
|
+
}));
|
|
856
|
+
|
|
857
|
+
const timings: SimulationTimings = {
|
|
858
|
+
total: totalTime,
|
|
859
|
+
sync: syncTime,
|
|
860
|
+
publicSimulation: publicSimulationTime,
|
|
861
|
+
validation: validationTime,
|
|
862
|
+
perFunction,
|
|
863
|
+
unaccounted:
|
|
864
|
+
totalTime -
|
|
865
|
+
(syncTime +
|
|
866
|
+
(publicSimulationTime ?? 0) +
|
|
867
|
+
(validationTime ?? 0) +
|
|
868
|
+
perFunction.reduce((acc, { time }) => acc + time, 0)),
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
this.log.info(`Simulation completed for ${txHash.toString()} in ${totalTime}ms`, {
|
|
769
872
|
txHash,
|
|
770
873
|
...txInfo,
|
|
771
874
|
...(publicOutput
|
|
@@ -775,9 +878,14 @@ export class PXEService implements PXE {
|
|
|
775
878
|
revertReason: publicOutput.revertReason,
|
|
776
879
|
}
|
|
777
880
|
: {}),
|
|
881
|
+
timings,
|
|
778
882
|
});
|
|
779
883
|
|
|
780
|
-
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
|
|
884
|
+
return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
|
|
885
|
+
privateSimulationResult,
|
|
886
|
+
publicOutput,
|
|
887
|
+
timings,
|
|
888
|
+
);
|
|
781
889
|
} catch (err: any) {
|
|
782
890
|
throw this.#contextualizeError(
|
|
783
891
|
err,
|
|
@@ -811,19 +919,34 @@ export class PXEService implements PXE {
|
|
|
811
919
|
authwits?: AuthWitness[],
|
|
812
920
|
_from?: AztecAddress,
|
|
813
921
|
scopes?: AztecAddress[],
|
|
814
|
-
): Promise<
|
|
922
|
+
): Promise<UtilitySimulationResult> {
|
|
815
923
|
// We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
|
|
816
924
|
// to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
|
|
817
925
|
// delete the same read value, or reading values that another simulation is currently modifying).
|
|
818
926
|
return this.#putInJobQueue(async () => {
|
|
819
927
|
try {
|
|
928
|
+
const totalTimer = new Timer();
|
|
929
|
+
const syncTimer = new Timer();
|
|
820
930
|
await this.synchronizer.sync();
|
|
931
|
+
const syncTime = syncTimer.ms();
|
|
821
932
|
// TODO - Should check if `from` has the permission to call the view function.
|
|
822
933
|
const functionCall = await this.#getFunctionCall(functionName, args, to);
|
|
934
|
+
const functionTimer = new Timer();
|
|
823
935
|
const executionResult = await this.#simulateUtility(functionCall, authwits ?? [], scopes);
|
|
936
|
+
const functionTime = functionTimer.ms();
|
|
824
937
|
|
|
825
|
-
|
|
826
|
-
|
|
938
|
+
const totalTime = totalTimer.ms();
|
|
939
|
+
|
|
940
|
+
const perFunction = [{ functionName, time: functionTime }];
|
|
941
|
+
|
|
942
|
+
const timings: SimulationTimings = {
|
|
943
|
+
total: totalTime,
|
|
944
|
+
sync: syncTime,
|
|
945
|
+
perFunction,
|
|
946
|
+
unaccounted: totalTime - (syncTime + perFunction.reduce((acc, { time }) => acc + time, 0)),
|
|
947
|
+
};
|
|
948
|
+
|
|
949
|
+
return { result: executionResult, timings };
|
|
827
950
|
} catch (err: any) {
|
|
828
951
|
const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
|
|
829
952
|
throw this.#contextualizeError(
|
|
@@ -836,25 +959,31 @@ export class PXEService implements PXE {
|
|
|
836
959
|
}
|
|
837
960
|
|
|
838
961
|
public async getNodeInfo(): Promise<NodeInfo> {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
962
|
+
// This assumes we're connected to a single node, so we cache the info to avoid repeated calls.
|
|
963
|
+
// Load balancers and a myriad other configurations can break this assumption, so review this!
|
|
964
|
+
// Temporary mesure to avoid hammering full nodes with requests on testnet.
|
|
965
|
+
if (!this.#nodeInfo) {
|
|
966
|
+
const [nodeVersion, rollupVersion, chainId, enr, contractAddresses, protocolContractAddresses] =
|
|
967
|
+
await Promise.all([
|
|
968
|
+
this.node.getNodeVersion(),
|
|
969
|
+
this.node.getVersion(),
|
|
970
|
+
this.node.getChainId(),
|
|
971
|
+
this.node.getEncodedEnr(),
|
|
972
|
+
this.node.getL1ContractAddresses(),
|
|
973
|
+
this.node.getProtocolContractAddresses(),
|
|
974
|
+
]);
|
|
975
|
+
|
|
976
|
+
this.#nodeInfo = {
|
|
977
|
+
nodeVersion,
|
|
978
|
+
l1ChainId: chainId,
|
|
979
|
+
rollupVersion,
|
|
980
|
+
enr,
|
|
981
|
+
l1ContractAddresses: contractAddresses,
|
|
982
|
+
protocolContractAddresses: protocolContractAddresses,
|
|
983
|
+
};
|
|
984
|
+
}
|
|
856
985
|
|
|
857
|
-
return nodeInfo;
|
|
986
|
+
return this.#nodeInfo;
|
|
858
987
|
}
|
|
859
988
|
|
|
860
989
|
public getPXEInfo(): Promise<PXEInfo> {
|
|
@@ -908,19 +1037,19 @@ export class PXEService implements PXE {
|
|
|
908
1037
|
.map(log => {
|
|
909
1038
|
// +1 for the event selector
|
|
910
1039
|
const expectedLength = eventMetadataDef.fieldNames.length + 1;
|
|
911
|
-
|
|
1040
|
+
if (log.log.emittedLength !== expectedLength) {
|
|
1041
|
+
throw new Error(
|
|
1042
|
+
`Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length. Expected ${expectedLength}. Got ${log.log.emittedLength}.`,
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
const logFields = log.log.getEmittedFields();
|
|
912
1047
|
// We are assuming here that event logs are the last 4 bytes of the event. This is not enshrined but is a function of aztec.nr raw log emission.
|
|
913
1048
|
if (!EventSelector.fromField(logFields[logFields.length - 1]).equals(eventMetadataDef.eventSelector)) {
|
|
914
1049
|
return undefined;
|
|
915
1050
|
}
|
|
916
|
-
// If any of the remaining fields, are non-zero, the payload does match expected:
|
|
917
|
-
if (log.log.log.slice(expectedLength + 1).find(f => !f.isZero())) {
|
|
918
|
-
throw new Error(
|
|
919
|
-
'Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length',
|
|
920
|
-
);
|
|
921
|
-
}
|
|
922
1051
|
|
|
923
|
-
return decodeFromAbi([eventMetadataDef.abiType], log.log.
|
|
1052
|
+
return decodeFromAbi([eventMetadataDef.abiType], log.log.fields) as T;
|
|
924
1053
|
})
|
|
925
1054
|
.filter(log => log !== undefined) as T[];
|
|
926
1055
|
|
|
@@ -199,20 +199,22 @@ export class NoteDataProvider implements DataProvider {
|
|
|
199
199
|
this.#notesByRecipientAndScope.get(formattedScopeString)!.getValuesAsync(filter.recipient.toString()),
|
|
200
200
|
)
|
|
201
201
|
: filter.txHash
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
202
|
+
? await toArray(
|
|
203
|
+
this.#notesByTxHashAndScope.get(formattedScopeString)!.getValuesAsync(filter.txHash.toString()),
|
|
204
|
+
)
|
|
205
|
+
: filter.contractAddress
|
|
206
|
+
? await toArray(
|
|
207
|
+
this.#notesByContractAndScope
|
|
208
|
+
.get(formattedScopeString)!
|
|
209
|
+
.getValuesAsync(filter.contractAddress.toString()),
|
|
210
|
+
)
|
|
211
|
+
: filter.storageSlot
|
|
212
|
+
? await toArray(
|
|
213
|
+
this.#notesByStorageSlotAndScope
|
|
214
|
+
.get(formattedScopeString)!
|
|
215
|
+
.getValuesAsync(filter.storageSlot.toString()),
|
|
216
|
+
)
|
|
217
|
+
: await toArray(this.#notesByRecipientAndScope.get(formattedScopeString)!.valuesAsync()),
|
|
216
218
|
);
|
|
217
219
|
}
|
|
218
220
|
|
|
@@ -226,12 +228,12 @@ export class NoteDataProvider implements DataProvider {
|
|
|
226
228
|
ids: filter.recipient
|
|
227
229
|
? await toArray(this.#nullifiedNotesByRecipient.getValuesAsync(filter.recipient.toString()))
|
|
228
230
|
: filter.txHash
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
? await toArray(this.#nullifiedNotesByTxHash.getValuesAsync(filter.txHash.toString()))
|
|
232
|
+
: filter.contractAddress
|
|
233
|
+
? await toArray(this.#nullifiedNotesByContract.getValuesAsync(filter.contractAddress.toString()))
|
|
234
|
+
: filter.storageSlot
|
|
235
|
+
? await toArray(this.#nullifiedNotesByStorageSlot.getValuesAsync(filter.storageSlot.toString()))
|
|
236
|
+
: await toArray(this.#nullifiedNotes.keysAsync()),
|
|
235
237
|
notes: this.#nullifiedNotes,
|
|
236
238
|
});
|
|
237
239
|
}
|
|
@@ -105,7 +105,7 @@ export class Synchronizer implements L2BlockStreamEventHandler {
|
|
|
105
105
|
|
|
106
106
|
try {
|
|
107
107
|
currentHeader = await this.syncDataProvider.getBlockHeader();
|
|
108
|
-
} catch
|
|
108
|
+
} catch {
|
|
109
109
|
this.log.debug('Header is not set, requesting from the node');
|
|
110
110
|
}
|
|
111
111
|
if (!currentHeader) {
|