@aztec/pxe 0.0.1-commit.d1da697d6 → 0.0.1-commit.d20b825a7
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/bin/check_oracle_version.js +4 -4
- package/dest/block_synchronizer/block_synchronizer.d.ts +6 -2
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +13 -1
- package/dest/config/index.d.ts +1 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +7 -14
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +4 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +6 -4
- package/dest/contract_function_simulator/ephemeral_array_service.d.ts +28 -0
- package/dest/contract_function_simulator/ephemeral_array_service.d.ts.map +1 -0
- package/dest/contract_function_simulator/ephemeral_array_service.js +78 -0
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +13 -2
- 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 +10 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +13 -2
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +98 -3
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +10 -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 +21 -15
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +28 -13
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +99 -27
- 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 +11 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +1 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.js +3 -0
- package/dest/contract_sync/contract_sync_service.d.ts +1 -1
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
- package/dest/contract_sync/contract_sync_service.js +35 -23
- package/dest/entrypoints/server/index.d.ts +2 -2
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +1 -1
- package/dest/events/event_service.d.ts +1 -1
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +10 -1
- package/dest/events/private_event_filter_validator.d.ts +3 -2
- package/dest/events/private_event_filter_validator.d.ts.map +1 -1
- package/dest/events/private_event_filter_validator.js +15 -0
- package/dest/logs/log_service.d.ts +6 -6
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +8 -20
- package/dest/oracle_version.d.ts +4 -3
- package/dest/oracle_version.d.ts.map +1 -1
- package/dest/oracle_version.js +20 -10
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +4 -7
- package/dest/private_kernel/private_kernel_oracle.d.ts +5 -5
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +12 -15
- package/dest/pxe.d.ts +16 -4
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +49 -20
- package/dest/storage/anchor_block_store/anchor_block_store.js +1 -1
- package/dest/storage/capsule_store/capsule_store.d.ts +1 -1
- package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
- package/dest/storage/capsule_store/capsule_store.js +8 -5
- package/dest/storage/contract_store/contract_store.d.ts +1 -1
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +4 -2
- package/dest/storage/private_event_store/private_event_store.d.ts +1 -1
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +3 -0
- package/dest/storage/private_event_store/stored_private_event.js +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +2 -2
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +2 -16
- package/package.json +16 -16
- package/src/bin/check_oracle_version.ts +4 -4
- package/src/block_synchronizer/block_synchronizer.ts +16 -2
- package/src/config/index.ts +2 -8
- package/src/contract_function_simulator/contract_function_simulator.ts +7 -4
- package/src/contract_function_simulator/ephemeral_array_service.ts +110 -0
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/oracle/interfaces.ts +20 -1
- package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +7 -1
- package/src/contract_function_simulator/oracle/oracle.ts +143 -3
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +31 -14
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +162 -54
- package/src/contract_function_simulator/pick_notes.ts +13 -1
- package/src/contract_function_simulator/proxied_contract_data_source.ts +8 -1
- package/src/contract_sync/contract_sync_service.ts +57 -51
- package/src/entrypoints/server/index.ts +1 -1
- package/src/events/event_service.ts +13 -1
- package/src/events/private_event_filter_validator.ts +21 -1
- package/src/logs/log_service.ts +14 -50
- package/src/oracle_version.ts +20 -10
- package/src/private_kernel/private_kernel_execution_prover.ts +4 -9
- package/src/private_kernel/private_kernel_oracle.ts +14 -14
- package/src/pxe.ts +86 -24
- package/src/storage/anchor_block_store/anchor_block_store.ts +1 -1
- package/src/storage/capsule_store/capsule_store.ts +15 -5
- package/src/storage/contract_store/contract_store.ts +8 -6
- package/src/storage/private_event_store/private_event_store.ts +4 -0
- package/src/storage/private_event_store/stored_private_event.ts +1 -1
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +5 -15
|
@@ -81,8 +81,11 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
81
81
|
private readonly taggingIndexCache: ExecutionTaggingIndexCache;
|
|
82
82
|
private readonly senderTaggingStore: SenderTaggingStore;
|
|
83
83
|
private totalPublicCalldataCount: number;
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
private readonly initialSideEffectCounter: number;
|
|
85
|
+
/** Sender for tags passed in at oracle construction time. Returned by `getSenderForTags` unless overridden. */
|
|
86
|
+
private readonly defaultSenderForTags: AztecAddress | undefined;
|
|
87
|
+
/** Per-call sender-for-tags override, set by `setSenderForTags`. Takes precedence over `defaultSenderForTags`. */
|
|
88
|
+
private currentSenderForTags: AztecAddress | undefined;
|
|
86
89
|
private readonly simulator?: CircuitSimulator;
|
|
87
90
|
|
|
88
91
|
constructor(args: PrivateExecutionOracleArgs) {
|
|
@@ -100,13 +103,18 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
100
103
|
this.taggingIndexCache = args.taggingIndexCache;
|
|
101
104
|
this.senderTaggingStore = args.senderTaggingStore;
|
|
102
105
|
this.totalPublicCalldataCount = args.totalPublicCalldataCount ?? 0;
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
106
|
+
this.initialSideEffectCounter = args.sideEffectCounter ?? 0;
|
|
107
|
+
this.defaultSenderForTags = args.senderForTags;
|
|
105
108
|
this.simulator = args.simulator;
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
public getPrivateContextInputs(): PrivateContextInputs {
|
|
109
|
-
return new PrivateContextInputs(
|
|
112
|
+
return new PrivateContextInputs(
|
|
113
|
+
this.callContext,
|
|
114
|
+
this.anchorBlockHeader,
|
|
115
|
+
this.txContext,
|
|
116
|
+
this.initialSideEffectCounter,
|
|
117
|
+
);
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
// We still need this function until we can get user-defined ordering of structs for fn arguments
|
|
@@ -173,11 +181,10 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
173
181
|
* for a tag in order to emit a log. Constrained tagging should not use this as there is no
|
|
174
182
|
* guarantee that the recipient knows about the sender, and hence about the shared secret.
|
|
175
183
|
*
|
|
176
|
-
*
|
|
177
|
-
* 'senderForTags' value (unless it is replaced).
|
|
184
|
+
* Returns `currentSenderForTags` if set (via `setSenderForTags`), otherwise `defaultSenderForTags`.
|
|
178
185
|
*/
|
|
179
186
|
public getSenderForTags(): Promise<AztecAddress | undefined> {
|
|
180
|
-
return Promise.resolve(this.
|
|
187
|
+
return Promise.resolve(this.currentSenderForTags ?? this.defaultSenderForTags);
|
|
181
188
|
}
|
|
182
189
|
|
|
183
190
|
/**
|
|
@@ -187,12 +194,14 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
187
194
|
* for a tag in order to emit a log. Constrained tagging should not use this as there is no
|
|
188
195
|
* guarantee that the recipient knows about the sender, and hence about the shared secret.
|
|
189
196
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* value (unless it is replaced by another call to this setter).
|
|
197
|
+
* Overrides `defaultSenderForTags` for the remainder of this call. Each oracle instance is
|
|
198
|
+
* independent, so this has no effect on any other call in the execution.
|
|
193
199
|
*/
|
|
194
200
|
public setSenderForTags(senderForTags: AztecAddress): Promise<void> {
|
|
195
|
-
this.
|
|
201
|
+
this.logger.debug(
|
|
202
|
+
`Sender for tags switched to ${senderForTags} by contract ${this.contractAddress} (default was ${this.defaultSenderForTags})`,
|
|
203
|
+
);
|
|
204
|
+
this.currentSenderForTags = senderForTags;
|
|
196
205
|
return Promise.resolve();
|
|
197
206
|
}
|
|
198
207
|
|
|
@@ -216,7 +225,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
216
225
|
this.logger.warn(`Computing a tag for invalid recipient ${recipient} - returning a random tag instead`, {
|
|
217
226
|
contractAddress: this.contractAddress,
|
|
218
227
|
});
|
|
219
|
-
return
|
|
228
|
+
return Tag.random();
|
|
220
229
|
}
|
|
221
230
|
|
|
222
231
|
const index = await this.#getIndexToUseForSecret(extendedSecret);
|
|
@@ -573,8 +582,9 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
573
582
|
sideEffectCounter,
|
|
574
583
|
log: this.logger,
|
|
575
584
|
scopes: this.scopes,
|
|
576
|
-
senderForTags: this.
|
|
585
|
+
senderForTags: this.defaultSenderForTags,
|
|
577
586
|
simulator: this.simulator!,
|
|
587
|
+
l2TipsStore: this.l2TipsStore,
|
|
578
588
|
});
|
|
579
589
|
|
|
580
590
|
const setupTime = simulatorSetupTimer.ms();
|
|
@@ -587,6 +597,9 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
587
597
|
functionSelector,
|
|
588
598
|
);
|
|
589
599
|
|
|
600
|
+
// Propagate the nested call's calldata count so the parent sees its increments on subsequent enqueues.
|
|
601
|
+
this.totalPublicCalldataCount = privateExecutionOracle.getTotalPublicCalldataCount();
|
|
602
|
+
|
|
590
603
|
if (isStaticCall) {
|
|
591
604
|
this.#checkValidStaticCall(childExecutionResult);
|
|
592
605
|
}
|
|
@@ -620,6 +633,10 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
620
633
|
return Promise.resolve();
|
|
621
634
|
}
|
|
622
635
|
|
|
636
|
+
public getTotalPublicCalldataCount(): number {
|
|
637
|
+
return this.totalPublicCalldataCount;
|
|
638
|
+
}
|
|
639
|
+
|
|
623
640
|
public notifyRevertiblePhaseStart(minRevertibleSideEffectCounter: number): Promise<void> {
|
|
624
641
|
return this.noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
625
642
|
}
|
|
@@ -9,7 +9,7 @@ import type { KeyStore } from '@aztec/key-store';
|
|
|
9
9
|
import { isProtocolContract } from '@aztec/protocol-contracts';
|
|
10
10
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
11
11
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
|
-
import { BlockHash } from '@aztec/stdlib/block';
|
|
12
|
+
import { BlockHash, type L2TipsProvider } from '@aztec/stdlib/block';
|
|
13
13
|
import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/stdlib/contract';
|
|
14
14
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
15
15
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
@@ -27,7 +27,7 @@ import { EventService } from '../../events/event_service.js';
|
|
|
27
27
|
import { LogService } from '../../logs/log_service.js';
|
|
28
28
|
import { MessageContextService } from '../../messages/message_context_service.js';
|
|
29
29
|
import { NoteService } from '../../notes/note_service.js';
|
|
30
|
-
import {
|
|
30
|
+
import { ORACLE_VERSION_MAJOR } from '../../oracle_version.js';
|
|
31
31
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
32
32
|
import type { CapsuleService } from '../../storage/capsule_store/capsule_service.js';
|
|
33
33
|
import type { ContractStore } from '../../storage/contract_store/contract_store.js';
|
|
@@ -35,6 +35,7 @@ import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
|
35
35
|
import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
|
|
36
36
|
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
37
37
|
import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_address_book_store.js';
|
|
38
|
+
import { EphemeralArrayService } from '../ephemeral_array_service.js';
|
|
38
39
|
import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
|
|
39
40
|
import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
|
|
40
41
|
import { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
|
|
@@ -62,6 +63,7 @@ export type UtilityExecutionOracleArgs = {
|
|
|
62
63
|
privateEventStore: PrivateEventStore;
|
|
63
64
|
messageContextService: MessageContextService;
|
|
64
65
|
contractSyncService: ContractSyncService;
|
|
66
|
+
l2TipsStore: L2TipsProvider;
|
|
65
67
|
jobId: string;
|
|
66
68
|
log?: ReturnType<typeof createLogger>;
|
|
67
69
|
scopes: AztecAddress[];
|
|
@@ -77,6 +79,10 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
77
79
|
private contractLogger: Logger | undefined;
|
|
78
80
|
private aztecnrLogger: Logger | undefined;
|
|
79
81
|
private offchainEffects: OffchainEffect[] = [];
|
|
82
|
+
private readonly ephemeralArrayService = new EphemeralArrayService();
|
|
83
|
+
|
|
84
|
+
// We store oracle version to be able to show a nice error message when an oracle handler is missing.
|
|
85
|
+
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
80
86
|
|
|
81
87
|
protected readonly contractAddress: AztecAddress;
|
|
82
88
|
protected readonly authWitnesses: AuthWitness[];
|
|
@@ -93,6 +99,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
93
99
|
protected readonly privateEventStore: PrivateEventStore;
|
|
94
100
|
protected readonly messageContextService: MessageContextService;
|
|
95
101
|
protected readonly contractSyncService: ContractSyncService;
|
|
102
|
+
protected readonly l2TipsStore: L2TipsProvider;
|
|
96
103
|
protected readonly jobId: string;
|
|
97
104
|
protected logger: ReturnType<typeof createLogger>;
|
|
98
105
|
protected readonly scopes: AztecAddress[];
|
|
@@ -113,12 +120,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
113
120
|
this.privateEventStore = args.privateEventStore;
|
|
114
121
|
this.messageContextService = args.messageContextService;
|
|
115
122
|
this.contractSyncService = args.contractSyncService;
|
|
123
|
+
this.l2TipsStore = args.l2TipsStore;
|
|
116
124
|
this.jobId = args.jobId;
|
|
117
125
|
this.logger = args.log ?? createLogger('simulator:client_view_context');
|
|
118
126
|
this.scopes = args.scopes;
|
|
119
127
|
}
|
|
120
128
|
|
|
121
|
-
public assertCompatibleOracleVersion(
|
|
129
|
+
public assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
122
130
|
// TODO(F-416): Remove this hack on v5 when protocol contracts are redeployed.
|
|
123
131
|
// Protocol contracts/canonical contracts shipped with committed bytecode that cannot be changed. Assert they use
|
|
124
132
|
// the expected pinned version or the current one. We want to allow for both the pinned and the current versions
|
|
@@ -126,27 +134,36 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
126
134
|
// pinned contracts (like e.g. next)
|
|
127
135
|
const LEGACY_ORACLE_VERSION = 12;
|
|
128
136
|
if (isProtocolContract(this.contractAddress)) {
|
|
129
|
-
if (
|
|
137
|
+
if (major !== LEGACY_ORACLE_VERSION && major !== ORACLE_VERSION_MAJOR) {
|
|
130
138
|
const hint =
|
|
131
|
-
|
|
139
|
+
major > ORACLE_VERSION_MAJOR
|
|
132
140
|
? '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
141
|
: '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.';
|
|
134
142
|
throw new Error(
|
|
135
|
-
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle version ${LEGACY_ORACLE_VERSION} or ${
|
|
143
|
+
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${LEGACY_ORACLE_VERSION} or ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
136
144
|
);
|
|
137
145
|
}
|
|
146
|
+
this.contractOracleVersion = { major, minor };
|
|
138
147
|
return;
|
|
139
148
|
}
|
|
140
149
|
|
|
141
|
-
if (
|
|
150
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
142
151
|
const hint =
|
|
143
|
-
|
|
152
|
+
major > ORACLE_VERSION_MAJOR
|
|
144
153
|
? '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
154
|
: '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
155
|
throw new Error(
|
|
147
|
-
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle version ${
|
|
156
|
+
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
148
157
|
);
|
|
149
158
|
}
|
|
159
|
+
|
|
160
|
+
// Major matches - store both major and minor for later diagnostics (e.g. when an oracle is not found)
|
|
161
|
+
this.contractOracleVersion = { major, minor };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
165
|
+
public nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
|
|
166
|
+
return this.contractOracleVersion;
|
|
150
167
|
}
|
|
151
168
|
|
|
152
169
|
public getRandomField(): Fr {
|
|
@@ -316,10 +333,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
316
333
|
}
|
|
317
334
|
|
|
318
335
|
/**
|
|
319
|
-
* Returns an auth witness for the given message hash
|
|
320
|
-
* for this transaction first, and falls back to the local database if not found.
|
|
336
|
+
* Returns an auth witness for the given message hash from the list of transient witnesses for this transaction.
|
|
321
337
|
* @param messageHash - Hash of the message to authenticate.
|
|
322
|
-
* @returns Authentication witness for the requested message hash.
|
|
338
|
+
* @returns Authentication witness for the requested message hash, or undefined if not found.
|
|
323
339
|
*/
|
|
324
340
|
public getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
|
|
325
341
|
return Promise.resolve(this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness);
|
|
@@ -493,31 +509,44 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
493
509
|
logContractMessage(logger, LogLevels[level], strippedMessage, fields);
|
|
494
510
|
}
|
|
495
511
|
|
|
512
|
+
// Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
|
|
496
513
|
public async getPendingTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr, scope: AztecAddress) {
|
|
497
|
-
const logService =
|
|
514
|
+
const logService = this.#createLogService();
|
|
515
|
+
const logs = await logService.fetchTaggedLogs(this.contractAddress, scope);
|
|
516
|
+
await this.capsuleService.appendToCapsuleArray(
|
|
517
|
+
this.contractAddress,
|
|
518
|
+
pendingTaggedLogArrayBaseSlot,
|
|
519
|
+
logs.map(log => log.toFields()),
|
|
520
|
+
this.jobId,
|
|
521
|
+
scope,
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/** Fetches pending tagged logs into a freshly allocated ephemeral array and returns its base slot. */
|
|
526
|
+
public async getPendingTaggedLogsV2(scope: AztecAddress): Promise<Fr> {
|
|
527
|
+
const logService = this.#createLogService();
|
|
528
|
+
const logs = await logService.fetchTaggedLogs(this.contractAddress, scope);
|
|
529
|
+
return this.ephemeralArrayService.newArray(logs.map(log => log.toFields()));
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
#createLogService(): LogService {
|
|
533
|
+
return new LogService(
|
|
498
534
|
this.aztecNode,
|
|
499
535
|
this.anchorBlockHeader,
|
|
536
|
+
this.l2TipsStore,
|
|
500
537
|
this.keyStore,
|
|
501
|
-
this.capsuleService,
|
|
502
538
|
this.recipientTaggingStore,
|
|
503
539
|
this.senderAddressBookStore,
|
|
504
540
|
this.addressStore,
|
|
505
541
|
this.jobId,
|
|
506
542
|
this.logger.getBindings(),
|
|
507
543
|
);
|
|
508
|
-
|
|
509
|
-
await logService.fetchTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, scope);
|
|
510
544
|
}
|
|
511
545
|
|
|
512
546
|
/**
|
|
513
|
-
*
|
|
514
|
-
* `enqueue_event_for_validation`, inserting them into the note database and event store respectively, making them
|
|
515
|
-
* queryable via `get_notes` and `getPrivateEvents`.
|
|
547
|
+
* Legacy: validates note/event requests stored in capsule arrays.
|
|
516
548
|
*
|
|
517
|
-
*
|
|
518
|
-
* @param contractAddress - The address of the contract that the logs are tagged for.
|
|
519
|
-
* @param noteValidationRequestsArrayBaseSlot - The base slot of capsule array containing note validation requests.
|
|
520
|
-
* @param eventValidationRequestsArrayBaseSlot - The base slot of capsule array containing event validation requests.
|
|
549
|
+
* Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
|
|
521
550
|
*/
|
|
522
551
|
public async validateAndStoreEnqueuedNotesAndEvents(
|
|
523
552
|
contractAddress: AztecAddress,
|
|
@@ -532,8 +561,6 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
532
561
|
throw new Error(`Got a note validation request from ${contractAddress}, expected ${this.contractAddress}`);
|
|
533
562
|
}
|
|
534
563
|
|
|
535
|
-
// We read all note and event validation requests and process them all concurrently. This makes the process much
|
|
536
|
-
// faster as we don't need to wait for the network round-trip.
|
|
537
564
|
const noteValidationRequests = (
|
|
538
565
|
await this.capsuleService.readCapsuleArray(
|
|
539
566
|
contractAddress,
|
|
@@ -552,6 +579,53 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
552
579
|
)
|
|
553
580
|
).map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
|
|
554
581
|
|
|
582
|
+
await this.#processValidationRequests(noteValidationRequests, eventValidationRequests, scope);
|
|
583
|
+
|
|
584
|
+
await this.capsuleService.setCapsuleArray(
|
|
585
|
+
contractAddress,
|
|
586
|
+
noteValidationRequestsArrayBaseSlot,
|
|
587
|
+
[],
|
|
588
|
+
this.jobId,
|
|
589
|
+
scope,
|
|
590
|
+
);
|
|
591
|
+
await this.capsuleService.setCapsuleArray(
|
|
592
|
+
contractAddress,
|
|
593
|
+
eventValidationRequestsArrayBaseSlot,
|
|
594
|
+
[],
|
|
595
|
+
this.jobId,
|
|
596
|
+
scope,
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
public async validateAndStoreEnqueuedNotesAndEventsV2(
|
|
601
|
+
noteValidationRequestsArrayBaseSlot: Fr,
|
|
602
|
+
eventValidationRequestsArrayBaseSlot: Fr,
|
|
603
|
+
maxNotePackedLen: number,
|
|
604
|
+
maxEventSerializedLen: number,
|
|
605
|
+
scope: AztecAddress,
|
|
606
|
+
) {
|
|
607
|
+
const noteValidationRequests = this.ephemeralArrayService
|
|
608
|
+
.readArrayAt(noteValidationRequestsArrayBaseSlot)
|
|
609
|
+
.map(fields => NoteValidationRequest.fromFields(fields, maxNotePackedLen));
|
|
610
|
+
|
|
611
|
+
const eventValidationRequests = this.ephemeralArrayService
|
|
612
|
+
.readArrayAt(eventValidationRequestsArrayBaseSlot)
|
|
613
|
+
.map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
|
|
614
|
+
|
|
615
|
+
await this.#processValidationRequests(noteValidationRequests, eventValidationRequests, scope);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Dispatches note and event validation requests to the service layer.
|
|
620
|
+
*
|
|
621
|
+
* This function is an auxiliary to support legacy (capsule backed) and new (ephemeral array backed) versions of the
|
|
622
|
+
* `validateAndStoreEnqueuedNotesAndEvents` oracle.
|
|
623
|
+
*/
|
|
624
|
+
async #processValidationRequests(
|
|
625
|
+
noteValidationRequests: NoteValidationRequest[],
|
|
626
|
+
eventValidationRequests: EventValidationRequest[],
|
|
627
|
+
scope: AztecAddress,
|
|
628
|
+
) {
|
|
555
629
|
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
556
630
|
const noteStorePromises = noteValidationRequests.map(request =>
|
|
557
631
|
noteService.validateAndStoreNote(
|
|
@@ -582,22 +656,6 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
582
656
|
);
|
|
583
657
|
|
|
584
658
|
await Promise.all([...noteStorePromises, ...eventStorePromises]);
|
|
585
|
-
|
|
586
|
-
// Requests are cleared once we're done.
|
|
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
|
-
);
|
|
601
659
|
}
|
|
602
660
|
|
|
603
661
|
public async getLogsByTag(
|
|
@@ -617,18 +675,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
617
675
|
await this.capsuleService.readCapsuleArray(contractAddress, logRetrievalRequestsArrayBaseSlot, this.jobId, scope)
|
|
618
676
|
).map(LogRetrievalRequest.fromFields);
|
|
619
677
|
|
|
620
|
-
const logService =
|
|
621
|
-
this.aztecNode,
|
|
622
|
-
this.anchorBlockHeader,
|
|
623
|
-
this.keyStore,
|
|
624
|
-
this.capsuleService,
|
|
625
|
-
this.recipientTaggingStore,
|
|
626
|
-
this.senderAddressBookStore,
|
|
627
|
-
this.addressStore,
|
|
628
|
-
this.jobId,
|
|
629
|
-
this.logger.getBindings(),
|
|
630
|
-
);
|
|
631
|
-
|
|
678
|
+
const logService = this.#createLogService();
|
|
632
679
|
const maybeLogRetrievalResponses = await logService.fetchLogsByTag(contractAddress, logRetrievalRequests);
|
|
633
680
|
|
|
634
681
|
// Requests are cleared once we're done.
|
|
@@ -650,6 +697,18 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
650
697
|
);
|
|
651
698
|
}
|
|
652
699
|
|
|
700
|
+
public async getLogsByTagV2(requestArrayBaseSlot: Fr): Promise<Fr> {
|
|
701
|
+
const logRetrievalRequests = this.ephemeralArrayService
|
|
702
|
+
.readArrayAt(requestArrayBaseSlot)
|
|
703
|
+
.map(LogRetrievalRequest.fromFields);
|
|
704
|
+
const logService = this.#createLogService();
|
|
705
|
+
|
|
706
|
+
const maybeLogRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests);
|
|
707
|
+
|
|
708
|
+
return this.ephemeralArrayService.newArray(maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption));
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
|
|
653
712
|
public async getMessageContextsByTxHash(
|
|
654
713
|
contractAddress: AztecAddress,
|
|
655
714
|
messageContextRequestsArrayBaseSlot: Fr,
|
|
@@ -661,7 +720,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
661
720
|
throw new Error(`Got a message context request from ${contractAddress}, expected ${this.contractAddress}`);
|
|
662
721
|
}
|
|
663
722
|
|
|
664
|
-
// TODO(@mverzilli): this is a prime example of where using
|
|
723
|
+
// TODO(@mverzilli): this is a prime example of where using an ephemeral array would make much more sense, we don't
|
|
665
724
|
// need scopes here, we just need a bit of shared memory to cross boundaries between Noir and TS.
|
|
666
725
|
// At the same time, we don't want to allow any global scope access other than where backwards compatibility
|
|
667
726
|
// forces us to. Hence we need the scope here to be artificial.
|
|
@@ -705,6 +764,27 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
705
764
|
}
|
|
706
765
|
}
|
|
707
766
|
|
|
767
|
+
/** Reads tx hash requests from an ephemeral array, resolves their contexts, and returns the response slot. */
|
|
768
|
+
public async getMessageContextsByTxHashV2(requestArrayBaseSlot: Fr): Promise<Fr> {
|
|
769
|
+
const requestFields = this.ephemeralArrayService.readArrayAt(requestArrayBaseSlot);
|
|
770
|
+
|
|
771
|
+
const txHashes = requestFields.map((fields, i) => {
|
|
772
|
+
if (fields.length !== 1) {
|
|
773
|
+
throw new Error(
|
|
774
|
+
`Malformed message context request at index ${i}: expected 1 field (tx hash), got ${fields.length}`,
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
return fields[0];
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
const maybeMessageContexts = await this.messageContextService.getMessageContextsByTxHash(
|
|
781
|
+
txHashes,
|
|
782
|
+
this.anchorBlockHeader.getBlockNumber(),
|
|
783
|
+
);
|
|
784
|
+
|
|
785
|
+
return this.ephemeralArrayService.newArray(maybeMessageContexts.map(MessageContext.toSerializedOption));
|
|
786
|
+
}
|
|
787
|
+
|
|
708
788
|
public setCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[], scope: AztecAddress): void {
|
|
709
789
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
710
790
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
@@ -781,6 +861,34 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
781
861
|
return deriveAppSiloedSharedSecret(addressSecret, ephPk, this.contractAddress);
|
|
782
862
|
}
|
|
783
863
|
|
|
864
|
+
public pushEphemeral(slot: Fr, elements: Fr[]): number {
|
|
865
|
+
return this.ephemeralArrayService.push(slot, elements);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
public popEphemeral(slot: Fr): Fr[] {
|
|
869
|
+
return this.ephemeralArrayService.pop(slot);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
public getEphemeral(slot: Fr, index: number): Fr[] {
|
|
873
|
+
return this.ephemeralArrayService.get(slot, index);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
public setEphemeral(slot: Fr, index: number, elements: Fr[]): void {
|
|
877
|
+
this.ephemeralArrayService.set(slot, index, elements);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
public getEphemeralLen(slot: Fr): number {
|
|
881
|
+
return this.ephemeralArrayService.len(slot);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
public removeEphemeral(slot: Fr, index: number): void {
|
|
885
|
+
this.ephemeralArrayService.remove(slot, index);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
public clearEphemeral(slot: Fr): void {
|
|
889
|
+
this.ephemeralArrayService.clear(slot);
|
|
890
|
+
}
|
|
891
|
+
|
|
784
892
|
public emitOffchainEffect(data: Fr[]): Promise<void> {
|
|
785
893
|
this.offchainEffects.push({ data, contractAddress: this.contractAddress });
|
|
786
894
|
return Promise.resolve();
|
|
@@ -85,6 +85,14 @@ interface ContainsNote {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const selectPropertyFromPackedNoteContent = (noteData: Fr[], selector: PropertySelector): Fr => {
|
|
88
|
+
if (selector.index >= noteData.length) {
|
|
89
|
+
throw new Error(`Property selector index ${selector.index} out of bounds for note with ${noteData.length} fields`);
|
|
90
|
+
}
|
|
91
|
+
if (selector.offset + selector.length > Fr.SIZE_IN_BYTES) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Property selector range (offset=${selector.offset}, length=${selector.length}) exceeds Fr buffer size of ${Fr.SIZE_IN_BYTES} bytes`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
88
96
|
const noteValueBuffer = noteData[selector.index].toBuffer();
|
|
89
97
|
// Noir's PropertySelector counts offset from the LSB (last byte of the big-endian buffer),
|
|
90
98
|
// so offset=0,length=Fr.SIZE_IN_BYTES reads the entire field, and offset=0,length=1 reads the last byte.
|
|
@@ -110,7 +118,11 @@ const selectNotes = <T extends ContainsNote>(noteDatas: T[], selects: Select[]):
|
|
|
110
118
|
[Comparator.GTE]: () => !noteValueFr.lt(value),
|
|
111
119
|
};
|
|
112
120
|
|
|
113
|
-
|
|
121
|
+
const fn = comparatorSelector[comparator];
|
|
122
|
+
if (!fn) {
|
|
123
|
+
throw new Error(`Invalid comparator value: ${comparator}`);
|
|
124
|
+
}
|
|
125
|
+
return fn();
|
|
114
126
|
}),
|
|
115
127
|
);
|
|
116
128
|
|
|
@@ -29,6 +29,7 @@ export class ProxiedContractStoreFactory {
|
|
|
29
29
|
}
|
|
30
30
|
instance.currentContractClassId = realInstance.currentContractClassId;
|
|
31
31
|
instance.originalContractClassId = realInstance.originalContractClassId;
|
|
32
|
+
instance.initializationHash = realInstance.initializationHash;
|
|
32
33
|
return instance;
|
|
33
34
|
} else {
|
|
34
35
|
return target.getContractInstance(address);
|
|
@@ -47,6 +48,9 @@ export class ProxiedContractStoreFactory {
|
|
|
47
48
|
return fn;
|
|
48
49
|
}
|
|
49
50
|
}
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Function with selector ${selector} not found in stub artifact for overridden contract at ${contractAddress}. The stub does not implement this function.`,
|
|
53
|
+
);
|
|
50
54
|
} else {
|
|
51
55
|
return target.getFunctionArtifact(contractAddress, selector);
|
|
52
56
|
}
|
|
@@ -64,6 +68,9 @@ export class ProxiedContractStoreFactory {
|
|
|
64
68
|
return fn;
|
|
65
69
|
}
|
|
66
70
|
}
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Function with selector ${selector} not found in stub artifact for overridden contract at ${contractAddress}. The stub does not implement this function.`,
|
|
73
|
+
);
|
|
67
74
|
} else {
|
|
68
75
|
return target.getFunctionArtifactWithDebugMetadata(contractAddress, selector);
|
|
69
76
|
}
|
|
@@ -78,6 +85,6 @@ export class ProxiedContractStoreFactory {
|
|
|
78
85
|
}
|
|
79
86
|
}
|
|
80
87
|
},
|
|
81
|
-
});
|
|
88
|
+
}) satisfies ContractStore;
|
|
82
89
|
}
|
|
83
90
|
}
|