@aztec/pxe 0.0.1-commit.e0f15ab9b → 0.0.1-commit.e304674f1
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 +1 -1
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +6 -0
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +3 -4
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +4 -3
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +2 -3
- 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 +2 -5
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +2 -3
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +2 -5
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +19 -19
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +18 -22
- package/dest/contract_function_simulator/oracle/oracle.d.ts +38 -19
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +60 -39
- package/dest/contract_function_simulator/oracle/private_execution.js +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +7 -8
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +16 -7
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +30 -29
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +115 -79
- package/dest/contract_function_simulator/pick_notes.d.ts +1 -1
- package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -1
- package/dest/contract_function_simulator/pick_notes.js +9 -2
- package/dest/contract_logging.d.ts +9 -4
- package/dest/contract_logging.d.ts.map +1 -1
- package/dest/contract_logging.js +21 -6
- package/dest/contract_sync/contract_sync_service.d.ts +3 -4
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
- package/dest/contract_sync/contract_sync_service.js +12 -22
- package/dest/contract_sync/helpers.d.ts +2 -3
- package/dest/contract_sync/helpers.d.ts.map +1 -1
- package/dest/contract_sync/helpers.js +7 -2
- package/dest/debug/pxe_debug_utils.d.ts +3 -3
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.d.ts +1 -2
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +0 -1
- package/dest/entrypoints/client/bundle/utils.d.ts +2 -2
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +2 -2
- package/dest/entrypoints/client/lazy/index.d.ts +1 -2
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +0 -1
- package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +2 -2
- package/dest/entrypoints/pxe_creation_options.d.ts +3 -1
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/pxe_creation_options.js +3 -1
- package/dest/entrypoints/server/index.d.ts +1 -2
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +0 -1
- package/dest/entrypoints/server/utils.d.ts +2 -2
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +2 -2
- package/dest/events/event_service.d.ts +3 -2
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +16 -4
- package/dest/logs/log_service.d.ts +6 -7
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +32 -30
- package/dest/messages/message_context_service.d.ts +3 -3
- package/dest/messages/message_context_service.d.ts.map +1 -1
- package/dest/messages/message_context_service.js +3 -3
- package/dest/notes/note_service.d.ts +4 -5
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +14 -5
- package/dest/notes_filter.d.ts +2 -3
- package/dest/notes_filter.d.ts.map +1 -1
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- package/dest/pxe.d.ts +4 -5
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +6 -4
- package/dest/storage/capsule_store/capsule_service.d.ts +21 -0
- package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -0
- package/dest/storage/capsule_store/capsule_service.js +50 -0
- package/dest/storage/capsule_store/capsule_store.d.ts +9 -9
- package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
- package/dest/storage/capsule_store/capsule_store.js +33 -28
- package/dest/storage/capsule_store/index.d.ts +2 -1
- package/dest/storage/capsule_store/index.d.ts.map +1 -1
- package/dest/storage/capsule_store/index.js +1 -0
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/note_store/note_store.d.ts +1 -1
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +2 -2
- package/package.json +16 -16
- package/src/block_synchronizer/block_synchronizer.ts +6 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +6 -6
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +0 -3
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +0 -3
- package/src/contract_function_simulator/oracle/interfaces.ts +26 -17
- package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +13 -50
- package/src/contract_function_simulator/oracle/oracle.ts +79 -33
- package/src/contract_function_simulator/oracle/private_execution.ts +1 -1
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +19 -10
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +204 -91
- package/src/contract_function_simulator/pick_notes.ts +9 -2
- package/src/contract_logging.ts +18 -5
- package/src/contract_sync/contract_sync_service.ts +32 -43
- package/src/contract_sync/helpers.ts +4 -4
- package/src/debug/pxe_debug_utils.ts +3 -3
- package/src/entrypoints/client/bundle/index.ts +0 -1
- package/src/entrypoints/client/bundle/utils.ts +2 -3
- package/src/entrypoints/client/lazy/index.ts +0 -1
- package/src/entrypoints/client/lazy/utils.ts +2 -3
- package/src/entrypoints/pxe_creation_options.ts +7 -0
- package/src/entrypoints/server/index.ts +0 -1
- package/src/entrypoints/server/utils.ts +2 -3
- package/src/events/event_service.ts +17 -4
- package/src/logs/log_service.ts +63 -48
- package/src/messages/message_context_service.ts +3 -4
- package/src/notes/note_service.ts +18 -8
- package/src/notes_filter.ts +1 -3
- package/src/oracle_version.ts +2 -2
- package/src/pxe.ts +11 -10
- package/src/storage/capsule_store/capsule_service.ts +90 -0
- package/src/storage/capsule_store/capsule_store.ts +34 -26
- package/src/storage/capsule_store/index.ts +1 -0
- package/src/storage/metadata.ts +1 -1
- package/src/storage/note_store/note_store.ts +2 -5
- package/dest/access_scopes.d.ts +0 -9
- package/dest/access_scopes.d.ts.map +0 -1
- package/dest/access_scopes.js +0 -6
- package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts +0 -16
- package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts.map +0 -1
- package/dest/contract_function_simulator/noir-structs/message_tx_context.js +0 -57
- package/src/access_scopes.ts +0 -9
- package/src/contract_function_simulator/noir-structs/message_tx_context.ts +0 -55
|
@@ -15,14 +15,13 @@ import { siloNullifier } from '@aztec/stdlib/hash';
|
|
|
15
15
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
16
16
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
17
17
|
import { type PublicKeys, computeAddressSecret } from '@aztec/stdlib/keys';
|
|
18
|
-
import {
|
|
18
|
+
import { MessageContext, deriveAppSiloedSharedSecret } from '@aztec/stdlib/logs';
|
|
19
19
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
20
20
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
21
21
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
22
22
|
import type { BlockHeader, Capsule, OffchainEffect } from '@aztec/stdlib/tx';
|
|
23
23
|
|
|
24
|
-
import
|
|
25
|
-
import { createContractLogger, logContractMessage } from '../../contract_logging.js';
|
|
24
|
+
import { createContractLogger, logContractMessage, stripAztecnrLogPrefix } from '../../contract_logging.js';
|
|
26
25
|
import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
|
|
27
26
|
import { EventService } from '../../events/event_service.js';
|
|
28
27
|
import { LogService } from '../../logs/log_service.js';
|
|
@@ -30,7 +29,7 @@ import { MessageContextService } from '../../messages/message_context_service.js
|
|
|
30
29
|
import { NoteService } from '../../notes/note_service.js';
|
|
31
30
|
import { ORACLE_VERSION } from '../../oracle_version.js';
|
|
32
31
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
33
|
-
import type {
|
|
32
|
+
import type { CapsuleService } from '../../storage/capsule_store/capsule_service.js';
|
|
34
33
|
import type { ContractStore } from '../../storage/contract_store/contract_store.js';
|
|
35
34
|
import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
36
35
|
import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
|
|
@@ -39,7 +38,6 @@ import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_
|
|
|
39
38
|
import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
|
|
40
39
|
import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
|
|
41
40
|
import { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
|
|
42
|
-
import { MessageTxContext } from '../noir-structs/message_tx_context.js';
|
|
43
41
|
import { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
|
|
44
42
|
import { UtilityContext } from '../noir-structs/utility_context.js';
|
|
45
43
|
import { pickNotes } from '../pick_notes.js';
|
|
@@ -60,13 +58,13 @@ export type UtilityExecutionOracleArgs = {
|
|
|
60
58
|
aztecNode: AztecNode;
|
|
61
59
|
recipientTaggingStore: RecipientTaggingStore;
|
|
62
60
|
senderAddressBookStore: SenderAddressBookStore;
|
|
63
|
-
|
|
61
|
+
capsuleService: CapsuleService;
|
|
64
62
|
privateEventStore: PrivateEventStore;
|
|
65
63
|
messageContextService: MessageContextService;
|
|
66
64
|
contractSyncService: ContractSyncService;
|
|
67
65
|
jobId: string;
|
|
68
66
|
log?: ReturnType<typeof createLogger>;
|
|
69
|
-
scopes:
|
|
67
|
+
scopes: AztecAddress[];
|
|
70
68
|
};
|
|
71
69
|
|
|
72
70
|
/**
|
|
@@ -77,6 +75,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
77
75
|
isUtility = true as const;
|
|
78
76
|
|
|
79
77
|
private contractLogger: Logger | undefined;
|
|
78
|
+
private aztecnrLogger: Logger | undefined;
|
|
80
79
|
private offchainEffects: OffchainEffect[] = [];
|
|
81
80
|
|
|
82
81
|
protected readonly contractAddress: AztecAddress;
|
|
@@ -90,13 +89,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
90
89
|
protected readonly aztecNode: AztecNode;
|
|
91
90
|
protected readonly recipientTaggingStore: RecipientTaggingStore;
|
|
92
91
|
protected readonly senderAddressBookStore: SenderAddressBookStore;
|
|
93
|
-
protected readonly
|
|
92
|
+
protected readonly capsuleService: CapsuleService;
|
|
94
93
|
protected readonly privateEventStore: PrivateEventStore;
|
|
95
94
|
protected readonly messageContextService: MessageContextService;
|
|
96
95
|
protected readonly contractSyncService: ContractSyncService;
|
|
97
96
|
protected readonly jobId: string;
|
|
98
97
|
protected logger: ReturnType<typeof createLogger>;
|
|
99
|
-
protected readonly scopes:
|
|
98
|
+
protected readonly scopes: AztecAddress[];
|
|
100
99
|
|
|
101
100
|
constructor(args: UtilityExecutionOracleArgs) {
|
|
102
101
|
this.contractAddress = args.contractAddress;
|
|
@@ -110,7 +109,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
110
109
|
this.aztecNode = args.aztecNode;
|
|
111
110
|
this.recipientTaggingStore = args.recipientTaggingStore;
|
|
112
111
|
this.senderAddressBookStore = args.senderAddressBookStore;
|
|
113
|
-
this.
|
|
112
|
+
this.capsuleService = args.capsuleService;
|
|
114
113
|
this.privateEventStore = args.privateEventStore;
|
|
115
114
|
this.messageContextService = args.messageContextService;
|
|
116
115
|
this.contractSyncService = args.contractSyncService;
|
|
@@ -128,15 +127,25 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
128
127
|
const LEGACY_ORACLE_VERSION = 12;
|
|
129
128
|
if (isProtocolContract(this.contractAddress)) {
|
|
130
129
|
if (version !== LEGACY_ORACLE_VERSION && version !== ORACLE_VERSION) {
|
|
130
|
+
const hint =
|
|
131
|
+
version > ORACLE_VERSION
|
|
132
|
+
? 'The contract was compiled with a newer version of Aztec.nr than your private environment supports. Upgrade your private environment to a compatible version.'
|
|
133
|
+
: 'The contract was compiled with an older version of Aztec.nr than your private environment supports. Recompile the contract with a compatible version of Aztec.nr.';
|
|
131
134
|
throw new Error(
|
|
132
|
-
`
|
|
135
|
+
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle version ${LEGACY_ORACLE_VERSION} or ${ORACLE_VERSION}, got ${version})`,
|
|
133
136
|
);
|
|
134
137
|
}
|
|
135
138
|
return;
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
if (version !== ORACLE_VERSION) {
|
|
139
|
-
|
|
142
|
+
const hint =
|
|
143
|
+
version > ORACLE_VERSION
|
|
144
|
+
? 'The contract was compiled with a newer version of Aztec.nr than your private environment supports. Upgrade your private environment to a compatible version.'
|
|
145
|
+
: 'The contract was compiled with an older version of Aztec.nr than your private environment supports. Recompile the contract with a compatible version of Aztec.nr.';
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle version ${ORACLE_VERSION}, got ${version})`,
|
|
148
|
+
);
|
|
140
149
|
}
|
|
141
150
|
}
|
|
142
151
|
|
|
@@ -156,33 +165,32 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
156
165
|
* @throws If scopes are defined and the account is not in the scopes.
|
|
157
166
|
*/
|
|
158
167
|
public async getKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (await this.keyStore.accountHasKey(this.scopes[i], pkMHash)) {
|
|
164
|
-
hasAccess = true;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
if (!hasAccess) {
|
|
168
|
-
throw new Error(`Key validation request denied: no scoped account has a key with hash ${pkMHash.toString()}.`);
|
|
168
|
+
let hasAccess = false;
|
|
169
|
+
for (let i = 0; i < this.scopes.length && !hasAccess; i++) {
|
|
170
|
+
if (await this.keyStore.accountHasKey(this.scopes[i], pkMHash)) {
|
|
171
|
+
hasAccess = true;
|
|
169
172
|
}
|
|
170
173
|
}
|
|
174
|
+
if (!hasAccess) {
|
|
175
|
+
throw new Error(`Key validation request denied: no scoped account has a key with hash ${pkMHash.toString()}.`);
|
|
176
|
+
}
|
|
171
177
|
return this.keyStore.getKeyValidationRequest(pkMHash, this.contractAddress);
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
/**
|
|
175
181
|
* Fetches the index and sibling path of a leaf at a given block from the note hash tree.
|
|
176
|
-
* @param
|
|
177
|
-
* witness.
|
|
182
|
+
* @param blockHash - The hash of a block that contains the note hash tree root in which to find the
|
|
183
|
+
* membership witness.
|
|
178
184
|
* @param noteHash - The note hash to find in the note hash tree.
|
|
179
185
|
* @returns The membership witness containing the leaf index and sibling path
|
|
180
186
|
*/
|
|
181
187
|
public getNoteHashMembershipWitness(
|
|
182
|
-
|
|
188
|
+
blockHash: BlockHash,
|
|
183
189
|
noteHash: Fr,
|
|
184
190
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
185
|
-
return this
|
|
191
|
+
return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
192
|
+
this.aztecNode.getNoteHashMembershipWitness(blockHash, noteHash),
|
|
193
|
+
);
|
|
186
194
|
}
|
|
187
195
|
|
|
188
196
|
/**
|
|
@@ -191,16 +199,21 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
191
199
|
* Block hashes are the leaves of the archive tree. Each time a new block is added to the chain,
|
|
192
200
|
* its block hash is appended as a new leaf to the archive tree.
|
|
193
201
|
*
|
|
194
|
-
* @param
|
|
202
|
+
* @param referenceBlockHash - The hash of a block that contains the archive tree root in which to find the membership
|
|
195
203
|
* witness.
|
|
196
204
|
* @param blockHash - The block hash to find in the archive tree.
|
|
197
205
|
* @returns The membership witness containing the leaf index and sibling path
|
|
198
206
|
*/
|
|
199
207
|
public getBlockHashMembershipWitness(
|
|
200
|
-
|
|
208
|
+
referenceBlockHash: BlockHash,
|
|
201
209
|
blockHash: BlockHash,
|
|
202
210
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
203
|
-
|
|
211
|
+
// Note that we validate that the reference block hash is at or before the anchor block - we don't test the block
|
|
212
|
+
// hash at all. If the block hash did not exist by the reference block hash, then the node will not return the
|
|
213
|
+
// membership witness as there is none.
|
|
214
|
+
return this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
|
|
215
|
+
this.aztecNode.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
|
|
216
|
+
);
|
|
204
217
|
}
|
|
205
218
|
|
|
206
219
|
/**
|
|
@@ -213,7 +226,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
213
226
|
blockHash: BlockHash,
|
|
214
227
|
nullifier: Fr,
|
|
215
228
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
216
|
-
return this
|
|
229
|
+
return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
230
|
+
this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier),
|
|
231
|
+
);
|
|
217
232
|
}
|
|
218
233
|
|
|
219
234
|
/**
|
|
@@ -229,7 +244,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
229
244
|
blockHash: BlockHash,
|
|
230
245
|
nullifier: Fr,
|
|
231
246
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
232
|
-
return this
|
|
247
|
+
return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
248
|
+
this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier),
|
|
249
|
+
);
|
|
233
250
|
}
|
|
234
251
|
|
|
235
252
|
/**
|
|
@@ -239,7 +256,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
239
256
|
* @returns - The witness
|
|
240
257
|
*/
|
|
241
258
|
public getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
242
|
-
return this
|
|
259
|
+
return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
260
|
+
this.aztecNode.getPublicDataWitness(blockHash, leafSlot),
|
|
261
|
+
);
|
|
243
262
|
}
|
|
244
263
|
|
|
245
264
|
/**
|
|
@@ -262,7 +281,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
262
281
|
* @param account - The account address.
|
|
263
282
|
* @returns The public keys and partial address, or `undefined` if the account is not registered.
|
|
264
283
|
*/
|
|
265
|
-
public async
|
|
284
|
+
public async getPublicKeysAndPartialAddress(
|
|
266
285
|
account: AztecAddress,
|
|
267
286
|
): Promise<{ publicKeys: PublicKeys; partialAddress: PartialAddress } | undefined> {
|
|
268
287
|
const completeAddress = await this.addressStore.getCompleteAddress(account);
|
|
@@ -368,7 +387,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
368
387
|
* @param innerNullifier - The inner nullifier.
|
|
369
388
|
* @returns A boolean indicating whether the nullifier exists in the tree or not.
|
|
370
389
|
*/
|
|
371
|
-
public async
|
|
390
|
+
public async doesNullifierExist(innerNullifier: Fr) {
|
|
372
391
|
const [nullifier, anchorBlockHash] = await Promise.all([
|
|
373
392
|
siloNullifier(this.contractAddress, innerNullifier!),
|
|
374
393
|
this.anchorBlockHeader.hash(),
|
|
@@ -380,7 +399,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
380
399
|
}
|
|
381
400
|
|
|
382
401
|
/**
|
|
383
|
-
*
|
|
402
|
+
* Returns the membership witness of an un-nullified L1 to L2 message.
|
|
384
403
|
* @param contractAddress - Address of a contract by which the message was emitted.
|
|
385
404
|
* @param messageHash - Hash of the message.
|
|
386
405
|
* @param secret - Secret used to compute a nullifier.
|
|
@@ -393,6 +412,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
393
412
|
contractAddress,
|
|
394
413
|
messageHash,
|
|
395
414
|
secret,
|
|
415
|
+
await this.anchorBlockHeader.hash(),
|
|
396
416
|
);
|
|
397
417
|
|
|
398
418
|
return new MessageLoadOracleInputs(messageIndex, siblingPath);
|
|
@@ -405,29 +425,31 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
405
425
|
* @param startStorageSlot - The starting storage slot.
|
|
406
426
|
* @param numberOfElements - Number of elements to read from the starting storage slot.
|
|
407
427
|
*/
|
|
408
|
-
public
|
|
428
|
+
public getFromPublicStorage(
|
|
409
429
|
blockHash: BlockHash,
|
|
410
430
|
contractAddress: AztecAddress,
|
|
411
431
|
startStorageSlot: Fr,
|
|
412
432
|
numberOfElements: number,
|
|
413
433
|
) {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
434
|
+
return this.#queryWithBlockHashNotAfterAnchor(blockHash, async () => {
|
|
435
|
+
const slots = Array(numberOfElements)
|
|
436
|
+
.fill(0)
|
|
437
|
+
.map((_, i) => new Fr(startStorageSlot.value + BigInt(i)));
|
|
417
438
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
439
|
+
const values = await Promise.all(
|
|
440
|
+
slots.map(storageSlot => this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot)),
|
|
441
|
+
);
|
|
421
442
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
443
|
+
this.logger.debug(
|
|
444
|
+
`Oracle storage read: slots=[${slots.map(slot => slot.toString()).join(', ')}] address=${contractAddress.toString()} values=[${values.join(', ')}]`,
|
|
445
|
+
);
|
|
425
446
|
|
|
426
|
-
|
|
447
|
+
return values;
|
|
448
|
+
});
|
|
427
449
|
}
|
|
428
450
|
|
|
429
451
|
/**
|
|
430
|
-
* Returns a per-contract logger whose output is prefixed with `
|
|
452
|
+
* Returns a per-contract logger whose output is prefixed with `contract:<name>(<addrAbbrev>)`.
|
|
431
453
|
*/
|
|
432
454
|
async #getContractLogger(): Promise<Logger> {
|
|
433
455
|
if (!this.contractLogger) {
|
|
@@ -436,26 +458,47 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
436
458
|
this.contractLogger = await createContractLogger(
|
|
437
459
|
this.contractAddress,
|
|
438
460
|
addr => this.contractStore.getDebugContractName(addr),
|
|
461
|
+
'user',
|
|
439
462
|
{ instanceId: this.jobId },
|
|
440
463
|
);
|
|
441
464
|
}
|
|
442
465
|
return this.contractLogger;
|
|
443
466
|
}
|
|
444
467
|
|
|
468
|
+
/**
|
|
469
|
+
* Returns a per-contract logger whose output is prefixed with `aztecnr:<name>(<addrAbbrev>)`.
|
|
470
|
+
*/
|
|
471
|
+
async #getAztecnrLogger(): Promise<Logger> {
|
|
472
|
+
if (!this.aztecnrLogger) {
|
|
473
|
+
// Purpose of instanceId is to distinguish logs from different instances of the same component. It makes sense
|
|
474
|
+
// to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
|
|
475
|
+
this.aztecnrLogger = await createContractLogger(
|
|
476
|
+
this.contractAddress,
|
|
477
|
+
addr => this.contractStore.getDebugContractName(addr),
|
|
478
|
+
'aztecnr',
|
|
479
|
+
{ instanceId: this.jobId },
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
return this.aztecnrLogger;
|
|
483
|
+
}
|
|
484
|
+
|
|
445
485
|
public async log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
446
486
|
if (!LogLevels[level]) {
|
|
447
487
|
throw new Error(`Invalid log level: ${level}`);
|
|
448
488
|
}
|
|
449
|
-
|
|
450
|
-
|
|
489
|
+
|
|
490
|
+
const { kind, message: strippedMessage } = stripAztecnrLogPrefix(message);
|
|
491
|
+
|
|
492
|
+
const logger = kind == 'aztecnr' ? await this.#getAztecnrLogger() : await this.#getContractLogger();
|
|
493
|
+
logContractMessage(logger, LogLevels[level], strippedMessage, fields);
|
|
451
494
|
}
|
|
452
495
|
|
|
453
|
-
public async
|
|
496
|
+
public async getPendingTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr, scope: AztecAddress) {
|
|
454
497
|
const logService = new LogService(
|
|
455
498
|
this.aztecNode,
|
|
456
499
|
this.anchorBlockHeader,
|
|
457
500
|
this.keyStore,
|
|
458
|
-
this.
|
|
501
|
+
this.capsuleService,
|
|
459
502
|
this.recipientTaggingStore,
|
|
460
503
|
this.senderAddressBookStore,
|
|
461
504
|
this.addressStore,
|
|
@@ -463,7 +506,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
463
506
|
this.logger.getBindings(),
|
|
464
507
|
);
|
|
465
508
|
|
|
466
|
-
await logService.fetchTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot,
|
|
509
|
+
await logService.fetchTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, scope);
|
|
467
510
|
}
|
|
468
511
|
|
|
469
512
|
/**
|
|
@@ -482,6 +525,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
482
525
|
eventValidationRequestsArrayBaseSlot: Fr,
|
|
483
526
|
maxNotePackedLen: number,
|
|
484
527
|
maxEventSerializedLen: number,
|
|
528
|
+
scope: AztecAddress,
|
|
485
529
|
) {
|
|
486
530
|
// TODO(#10727): allow other contracts to store notes
|
|
487
531
|
if (!this.contractAddress.equals(contractAddress)) {
|
|
@@ -491,11 +535,21 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
491
535
|
// We read all note and event validation requests and process them all concurrently. This makes the process much
|
|
492
536
|
// faster as we don't need to wait for the network round-trip.
|
|
493
537
|
const noteValidationRequests = (
|
|
494
|
-
await this.
|
|
538
|
+
await this.capsuleService.readCapsuleArray(
|
|
539
|
+
contractAddress,
|
|
540
|
+
noteValidationRequestsArrayBaseSlot,
|
|
541
|
+
this.jobId,
|
|
542
|
+
scope,
|
|
543
|
+
)
|
|
495
544
|
).map(fields => NoteValidationRequest.fromFields(fields, maxNotePackedLen));
|
|
496
545
|
|
|
497
546
|
const eventValidationRequests = (
|
|
498
|
-
await this.
|
|
547
|
+
await this.capsuleService.readCapsuleArray(
|
|
548
|
+
contractAddress,
|
|
549
|
+
eventValidationRequestsArrayBaseSlot,
|
|
550
|
+
this.jobId,
|
|
551
|
+
scope,
|
|
552
|
+
)
|
|
499
553
|
).map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
|
|
500
554
|
|
|
501
555
|
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
@@ -510,7 +564,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
510
564
|
request.noteHash,
|
|
511
565
|
request.nullifier,
|
|
512
566
|
request.txHash,
|
|
513
|
-
|
|
567
|
+
scope,
|
|
514
568
|
),
|
|
515
569
|
);
|
|
516
570
|
|
|
@@ -523,21 +577,34 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
523
577
|
request.serializedEvent,
|
|
524
578
|
request.eventCommitment,
|
|
525
579
|
request.txHash,
|
|
526
|
-
|
|
580
|
+
scope,
|
|
527
581
|
),
|
|
528
582
|
);
|
|
529
583
|
|
|
530
584
|
await Promise.all([...noteStorePromises, ...eventStorePromises]);
|
|
531
585
|
|
|
532
586
|
// Requests are cleared once we're done.
|
|
533
|
-
await this.
|
|
534
|
-
|
|
587
|
+
await this.capsuleService.setCapsuleArray(
|
|
588
|
+
contractAddress,
|
|
589
|
+
noteValidationRequestsArrayBaseSlot,
|
|
590
|
+
[],
|
|
591
|
+
this.jobId,
|
|
592
|
+
scope,
|
|
593
|
+
);
|
|
594
|
+
await this.capsuleService.setCapsuleArray(
|
|
595
|
+
contractAddress,
|
|
596
|
+
eventValidationRequestsArrayBaseSlot,
|
|
597
|
+
[],
|
|
598
|
+
this.jobId,
|
|
599
|
+
scope,
|
|
600
|
+
);
|
|
535
601
|
}
|
|
536
602
|
|
|
537
|
-
public async
|
|
603
|
+
public async getLogsByTag(
|
|
538
604
|
contractAddress: AztecAddress,
|
|
539
605
|
logRetrievalRequestsArrayBaseSlot: Fr,
|
|
540
606
|
logRetrievalResponsesArrayBaseSlot: Fr,
|
|
607
|
+
scope: AztecAddress,
|
|
541
608
|
) {
|
|
542
609
|
// TODO(#10727): allow other contracts to process partial notes
|
|
543
610
|
if (!this.contractAddress.equals(contractAddress)) {
|
|
@@ -547,14 +614,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
547
614
|
// We read all log retrieval requests and process them all concurrently. This makes the process much faster as we
|
|
548
615
|
// don't need to wait for the network round-trip.
|
|
549
616
|
const logRetrievalRequests = (
|
|
550
|
-
await this.
|
|
617
|
+
await this.capsuleService.readCapsuleArray(contractAddress, logRetrievalRequestsArrayBaseSlot, this.jobId, scope)
|
|
551
618
|
).map(LogRetrievalRequest.fromFields);
|
|
552
619
|
|
|
553
620
|
const logService = new LogService(
|
|
554
621
|
this.aztecNode,
|
|
555
622
|
this.anchorBlockHeader,
|
|
556
623
|
this.keyStore,
|
|
557
|
-
this.
|
|
624
|
+
this.capsuleService,
|
|
558
625
|
this.recipientTaggingStore,
|
|
559
626
|
this.senderAddressBookStore,
|
|
560
627
|
this.addressStore,
|
|
@@ -562,33 +629,47 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
562
629
|
this.logger.getBindings(),
|
|
563
630
|
);
|
|
564
631
|
|
|
565
|
-
const maybeLogRetrievalResponses = await logService.
|
|
632
|
+
const maybeLogRetrievalResponses = await logService.fetchLogsByTag(contractAddress, logRetrievalRequests);
|
|
566
633
|
|
|
567
634
|
// Requests are cleared once we're done.
|
|
568
|
-
await this.
|
|
635
|
+
await this.capsuleService.setCapsuleArray(
|
|
636
|
+
contractAddress,
|
|
637
|
+
logRetrievalRequestsArrayBaseSlot,
|
|
638
|
+
[],
|
|
639
|
+
this.jobId,
|
|
640
|
+
scope,
|
|
641
|
+
);
|
|
569
642
|
|
|
570
643
|
// The responses are stored as Option<LogRetrievalResponse> in a second CapsuleArray.
|
|
571
|
-
await this.
|
|
644
|
+
await this.capsuleService.setCapsuleArray(
|
|
572
645
|
contractAddress,
|
|
573
646
|
logRetrievalResponsesArrayBaseSlot,
|
|
574
647
|
maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption),
|
|
575
648
|
this.jobId,
|
|
649
|
+
scope,
|
|
576
650
|
);
|
|
577
651
|
}
|
|
578
652
|
|
|
579
|
-
public async
|
|
653
|
+
public async getMessageContextsByTxHash(
|
|
580
654
|
contractAddress: AztecAddress,
|
|
581
655
|
messageContextRequestsArrayBaseSlot: Fr,
|
|
582
656
|
messageContextResponsesArrayBaseSlot: Fr,
|
|
657
|
+
scope: AztecAddress,
|
|
583
658
|
) {
|
|
584
659
|
try {
|
|
585
660
|
if (!this.contractAddress.equals(contractAddress)) {
|
|
586
661
|
throw new Error(`Got a message context request from ${contractAddress}, expected ${this.contractAddress}`);
|
|
587
662
|
}
|
|
588
|
-
|
|
663
|
+
|
|
664
|
+
// TODO(@mverzilli): this is a prime example of where using a volatile array would make much more sense, we don't
|
|
665
|
+
// need scopes here, we just need a bit of shared memory to cross boundaries between Noir and TS.
|
|
666
|
+
// At the same time, we don't want to allow any global scope access other than where backwards compatibility
|
|
667
|
+
// forces us to. Hence we need the scope here to be artificial.
|
|
668
|
+
const requestCapsules = await this.capsuleService.readCapsuleArray(
|
|
589
669
|
contractAddress,
|
|
590
670
|
messageContextRequestsArrayBaseSlot,
|
|
591
671
|
this.jobId,
|
|
672
|
+
scope,
|
|
592
673
|
);
|
|
593
674
|
|
|
594
675
|
const txHashes = requestCapsules.map((fields, i) => {
|
|
@@ -600,66 +681,73 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
600
681
|
return fields[0];
|
|
601
682
|
});
|
|
602
683
|
|
|
603
|
-
const maybeMessageContexts = await this.messageContextService.
|
|
684
|
+
const maybeMessageContexts = await this.messageContextService.getMessageContextsByTxHash(
|
|
604
685
|
txHashes,
|
|
605
686
|
this.anchorBlockHeader.getBlockNumber(),
|
|
606
687
|
);
|
|
607
688
|
|
|
608
689
|
// Leave response in response capsule array.
|
|
609
|
-
await this.
|
|
690
|
+
await this.capsuleService.setCapsuleArray(
|
|
610
691
|
contractAddress,
|
|
611
692
|
messageContextResponsesArrayBaseSlot,
|
|
612
|
-
maybeMessageContexts.map(
|
|
693
|
+
maybeMessageContexts.map(MessageContext.toSerializedOption),
|
|
613
694
|
this.jobId,
|
|
695
|
+
scope,
|
|
614
696
|
);
|
|
615
697
|
} finally {
|
|
616
|
-
await this.
|
|
698
|
+
await this.capsuleService.setCapsuleArray(
|
|
699
|
+
contractAddress,
|
|
700
|
+
messageContextRequestsArrayBaseSlot,
|
|
701
|
+
[],
|
|
702
|
+
this.jobId,
|
|
703
|
+
scope,
|
|
704
|
+
);
|
|
617
705
|
}
|
|
618
706
|
}
|
|
619
707
|
|
|
620
|
-
public
|
|
708
|
+
public setCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[], scope: AztecAddress): void {
|
|
621
709
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
622
710
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
623
711
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
624
712
|
}
|
|
625
|
-
this.
|
|
626
|
-
return Promise.resolve();
|
|
713
|
+
this.capsuleService.setCapsule(contractAddress, slot, capsule, this.jobId, scope);
|
|
627
714
|
}
|
|
628
715
|
|
|
629
|
-
public
|
|
716
|
+
public getCapsule(contractAddress: AztecAddress, slot: Fr, scope: AztecAddress): Promise<Fr[] | null> {
|
|
630
717
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
631
718
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
632
719
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
633
720
|
}
|
|
634
|
-
return (
|
|
635
|
-
// TODO(#12425): On the following line, the pertinent capsule gets overshadowed by the transient one. Tackle this.
|
|
636
|
-
this.capsules.find(c => c.contractAddress.equals(contractAddress) && c.storageSlot.equals(slot))?.data ??
|
|
637
|
-
(await this.capsuleStore.loadCapsule(this.contractAddress, slot, this.jobId))
|
|
638
|
-
);
|
|
721
|
+
return this.capsuleService.getCapsule(contractAddress, slot, this.jobId, scope, this.capsules);
|
|
639
722
|
}
|
|
640
723
|
|
|
641
|
-
public deleteCapsule(contractAddress: AztecAddress, slot: Fr):
|
|
724
|
+
public deleteCapsule(contractAddress: AztecAddress, slot: Fr, scope: AztecAddress): void {
|
|
642
725
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
643
726
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
644
727
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
645
728
|
}
|
|
646
|
-
this.
|
|
647
|
-
return Promise.resolve();
|
|
729
|
+
this.capsuleService.deleteCapsule(contractAddress, slot, this.jobId, scope);
|
|
648
730
|
}
|
|
649
731
|
|
|
650
|
-
public copyCapsule(
|
|
732
|
+
public copyCapsule(
|
|
733
|
+
contractAddress: AztecAddress,
|
|
734
|
+
srcSlot: Fr,
|
|
735
|
+
dstSlot: Fr,
|
|
736
|
+
numEntries: number,
|
|
737
|
+
scope: AztecAddress,
|
|
738
|
+
): Promise<void> {
|
|
651
739
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
652
740
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
653
741
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
654
742
|
}
|
|
655
|
-
return this.
|
|
743
|
+
return this.capsuleService.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries, this.jobId, scope);
|
|
656
744
|
}
|
|
657
745
|
|
|
658
746
|
/**
|
|
659
747
|
* Clears cached sync state for a contract for a set of scopes, forcing re-sync on the next query so that newly
|
|
660
748
|
* stored notes or events are discovered.
|
|
661
749
|
*/
|
|
662
|
-
public
|
|
750
|
+
public setContractSyncCacheInvalid(contractAddress: AztecAddress, scopes: AztecAddress[]): void {
|
|
663
751
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
664
752
|
throw new Error(`Contract ${this.contractAddress} cannot invalidate sync cache of ${contractAddress}`);
|
|
665
753
|
}
|
|
@@ -667,25 +755,30 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
667
755
|
}
|
|
668
756
|
|
|
669
757
|
// TODO(#11849): consider replacing this oracle with a pure Noir implementation of aes decryption.
|
|
670
|
-
public
|
|
758
|
+
public decryptAes128(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise<Buffer> {
|
|
671
759
|
const aes128 = new Aes128();
|
|
672
760
|
return aes128.decryptBufferCBC(ciphertext, iv, symKey);
|
|
673
761
|
}
|
|
674
762
|
|
|
675
763
|
/**
|
|
676
|
-
* Retrieves the shared secret for a given address and ephemeral public key.
|
|
764
|
+
* Retrieves the app-siloed shared secret for a given address and ephemeral public key.
|
|
677
765
|
* @param address - The address to get the secret for.
|
|
678
766
|
* @param ephPk - The ephemeral public key to get the secret for.
|
|
679
|
-
* @
|
|
767
|
+
* @param contractAddress - The contract address for app-siloing (validated against execution context).
|
|
768
|
+
* @returns The app-siloed shared secret as a Field.
|
|
680
769
|
*/
|
|
681
|
-
public async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<
|
|
682
|
-
|
|
770
|
+
public async getSharedSecret(address: AztecAddress, ephPk: Point, contractAddress: AztecAddress): Promise<Fr> {
|
|
771
|
+
if (!contractAddress.equals(this.contractAddress)) {
|
|
772
|
+
throw new Error(
|
|
773
|
+
`getSharedSecret called with contract address ${contractAddress}, expected ${this.contractAddress}`,
|
|
774
|
+
);
|
|
775
|
+
}
|
|
683
776
|
const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
|
|
684
777
|
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
685
778
|
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
686
779
|
);
|
|
687
780
|
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
688
|
-
return
|
|
781
|
+
return deriveAppSiloedSharedSecret(addressSecret, ephPk, this.contractAddress);
|
|
689
782
|
}
|
|
690
783
|
|
|
691
784
|
public emitOffchainEffect(data: Fr[]): Promise<void> {
|
|
@@ -697,4 +790,24 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
697
790
|
public getOffchainEffects(): OffchainEffect[] {
|
|
698
791
|
return this.offchainEffects;
|
|
699
792
|
}
|
|
793
|
+
|
|
794
|
+
/** Runs a query concurrently with a validation that the block hash is not ahead of the anchor block. */
|
|
795
|
+
async #queryWithBlockHashNotAfterAnchor<T>(blockHash: BlockHash, query: () => Promise<T>): Promise<T> {
|
|
796
|
+
const [response] = await Promise.all([
|
|
797
|
+
query(),
|
|
798
|
+
(async () => {
|
|
799
|
+
const header = await this.aztecNode.getBlockHeader(blockHash);
|
|
800
|
+
if (!header) {
|
|
801
|
+
throw new Error(`Could not find block header for block hash ${blockHash}`);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
if (header.getBlockNumber() > this.anchorBlockHeader.getBlockNumber()) {
|
|
805
|
+
throw new Error(
|
|
806
|
+
`Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${await this.anchorBlockHeader.hash()}).`,
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
})(),
|
|
810
|
+
]);
|
|
811
|
+
return response;
|
|
812
|
+
}
|
|
700
813
|
}
|