@aztec/txe 0.0.1-commit.2b2662070 → 0.0.1-commit.2c0ee1788

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.
@@ -2,7 +2,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { type Logger } from '@aztec/foundation/log';
4
4
  import { KeyStore } from '@aztec/key-store';
5
- import { AddressStore, CapsuleStore, ContractStore, ContractSyncService, JobCoordinator, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
5
+ import { AddressStore, CapsuleStore, ContractStore, JobCoordinator, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
6
6
  import { type IPrivateExecutionOracle, type IUtilityExecutionOracle } from '@aztec/pxe/simulator';
7
7
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
8
8
  import { PrivateContextInputs } from '@aztec/stdlib/kernel';
@@ -26,6 +26,36 @@ export interface TXESessionStateHandler {
26
26
  enterUtilityState(contractAddress?: AztecAddress): Promise<void>;
27
27
  cycleJob(): Promise<string>;
28
28
  getCurrentJob(): string;
29
+ /**
30
+ * Runs an executor-style top-level call (private/public call, utility execution) with last-call tracking.
31
+ */
32
+ withTopLevelCallTracking<T>(work: () => Promise<{
33
+ result: T;
34
+ txHash?: Fr;
35
+ }>): Promise<T>;
36
+ /**
37
+ * Captures a raw offchain effect payload for consumption from test environment. Called by the `emit_offchain_effect`
38
+ * oracle handler whenever a contract function emits an offchain message, at any call depth.
39
+ */
40
+ recordOffchainEffect(data: Fr[]): void;
41
+ /**
42
+ * Returns the raw offchain effect payloads emitted by the last top-level call. Each payload follows the protocol
43
+ * convention documented on `OFFCHAIN_MESSAGE_IDENTIFIER`, i.e. `[identifier, recipient, ...ciphertext]`. Decoding into
44
+ * `OffchainMessage` structs happens on the Noir side of the test helper. Marks the buffer as queried so the
45
+ * unqueried-messages warning doesn't fire on the next reset.
46
+ */
47
+ getLastCallOffchainEffects(): {
48
+ effects: Fr[][];
49
+ };
50
+ /**
51
+ * Returns the context of the last top-level call: its tx hash (`Fr.ZERO` if the call was tx-less) and the anchor
52
+ * block timestamp captured at the start of the call. Does *not* mark the buffer as queried — context reads are
53
+ * metadata, not effect consumption.
54
+ */
55
+ getLastCallContext(): {
56
+ txHash: Fr;
57
+ anchorBlockTimestamp: bigint;
58
+ };
29
59
  }
30
60
  /**
31
61
  * A `TXESession` corresponds to a Noir `#[test]` function, and handles all of its oracle calls, stores test-specific
@@ -50,10 +80,10 @@ export declare class TXESession implements TXESessionStateHandler {
50
80
  private chainId;
51
81
  private version;
52
82
  private nextBlockTimestamp;
53
- private contractSyncService;
54
83
  private state;
55
84
  private authwits;
56
- constructor(logger: Logger, stateMachine: TXEStateMachine, oracleHandler: IUtilityExecutionOracle | IPrivateExecutionOracle | IAvmExecutionOracle | ITxeExecutionOracle, contractStore: ContractStore, noteStore: NoteStore, keyStore: KeyStore, addressStore: AddressStore, accountStore: TXEAccountStore, senderTaggingStore: SenderTaggingStore, recipientTaggingStore: RecipientTaggingStore, senderAddressBookStore: SenderAddressBookStore, capsuleStore: CapsuleStore, privateEventStore: PrivateEventStore, jobCoordinator: JobCoordinator, currentJobId: string, chainId: Fr, version: Fr, nextBlockTimestamp: bigint, contractSyncService: ContractSyncService);
85
+ private lastCallInfo;
86
+ constructor(logger: Logger, stateMachine: TXEStateMachine, oracleHandler: IUtilityExecutionOracle | IPrivateExecutionOracle | IAvmExecutionOracle | ITxeExecutionOracle, contractStore: ContractStore, noteStore: NoteStore, keyStore: KeyStore, addressStore: AddressStore, accountStore: TXEAccountStore, senderTaggingStore: SenderTaggingStore, recipientTaggingStore: RecipientTaggingStore, senderAddressBookStore: SenderAddressBookStore, capsuleStore: CapsuleStore, privateEventStore: PrivateEventStore, jobCoordinator: JobCoordinator, currentJobId: string, chainId: Fr, version: Fr, nextBlockTimestamp: bigint);
57
87
  static init(contractStore: ContractStore): Promise<TXESession>;
58
88
  /**
59
89
  * Processes an oracle function invoked by the Noir test associated to this session.
@@ -65,6 +95,20 @@ export declare class TXESession implements TXESessionStateHandler {
65
95
  getCurrentJob(): string;
66
96
  /** Commits the current job and begins a new one. Returns the new job ID. */
67
97
  cycleJob(): Promise<string>;
98
+ private resetLastCall;
99
+ recordOffchainEffect(data: Fr[]): void;
100
+ private setLastCallContext;
101
+ withTopLevelCallTracking<T>(work: () => Promise<{
102
+ result: T;
103
+ txHash?: Fr;
104
+ }>): Promise<T>;
105
+ getLastCallOffchainEffects(): {
106
+ effects: Fr[][];
107
+ };
108
+ getLastCallContext(): {
109
+ txHash: Fr;
110
+ anchorBlockTimestamp: bigint;
111
+ };
68
112
  enterTopLevelState(): Promise<void>;
69
113
  enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: BlockNumber): Promise<PrivateContextInputs>;
70
114
  enterPublicState(contractAddress?: AztecAddress): Promise<void>;
@@ -76,4 +120,4 @@ export declare class TXESession implements TXESessionStateHandler {
76
120
  private utilityExecutorForContractSync;
77
121
  }
78
122
  export {};
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX3Nlc3Npb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eGVfc2Vzc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxFQUNMLFlBQVksRUFHWixZQUFZLEVBQ1osYUFBYSxFQUNiLG1CQUFtQixFQUNuQixjQUFjLEVBRWQsU0FBUyxFQUNULGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsc0JBQXNCLEVBQ3RCLGtCQUFrQixFQUNuQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFJTCxLQUFLLHVCQUF1QixFQUM1QixLQUFLLHVCQUF1QixFQUk3QixNQUFNLHNCQUFzQixDQUFDO0FBVzlCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUczRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQU81RCxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3ZGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDN0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBeUM5RCxLQUFLLFdBQVcsQ0FBQyxDQUFDLElBQUk7S0FDbkIsQ0FBQyxJQUFJLE1BQU0s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
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX3Nlc3Npb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eGVfc2Vzc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxFQUNMLFlBQVksRUFHWixZQUFZLEVBQ1osYUFBYSxFQUNiLGNBQWMsRUFFZCxTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLHFCQUFxQixFQUNyQixzQkFBc0IsRUFDdEIsa0JBQWtCLEVBQ25CLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUlMLEtBQUssdUJBQXVCLEVBQzVCLEtBQUssdUJBQXVCLEVBSTdCLE1BQU0sc0JBQXNCLENBQUM7QUFXOUIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRzNELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBTzVELE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHdkYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUF5QzlELEtBQUssV0FBVyxDQUFDLENBQUMsSUFBSTtLQUNuQixDQUFDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FB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
@@ -1 +1 @@
1
- {"version":3,"file":"txe_session.d.ts","sourceRoot":"","sources":["../src/txe_session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"txe_session.d.ts","sourceRoot":"","sources":["../src/txe_session.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import { KeyStore } from '@aztec/key-store';
5
5
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
6
- import { AddressStore, AnchorBlockStore, CapsuleService, CapsuleStore, ContractSyncService, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
6
+ import { AddressStore, AnchorBlockStore, CapsuleService, CapsuleStore, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
7
7
  import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle } from '@aztec/pxe/simulator';
8
8
  import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness } from '@aztec/simulator/client';
9
9
  import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
@@ -11,7 +11,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
11
11
  import { GasSettings } from '@aztec/stdlib/gas';
12
12
  import { computeProtocolNullifier } from '@aztec/stdlib/hash';
13
13
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
14
- import { CallContext, TxContext } from '@aztec/stdlib/tx';
14
+ import { CallContext, OFFCHAIN_MESSAGE_IDENTIFIER, TxContext } from '@aztec/stdlib/tx';
15
15
  import { z } from 'zod';
16
16
  import { DEFAULT_ADDRESS } from './constants.js';
17
17
  import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
@@ -22,6 +22,14 @@ import { TXEStateMachine } from './state_machine/index.js';
22
22
  import { TXEAccountStore } from './util/txe_account_store.js';
23
23
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
24
24
  import { makeTxEffect } from './utils/tx_effect_creation.js';
25
+ function emptyLastCallState() {
26
+ return {
27
+ offchainEffects: [],
28
+ queried: false,
29
+ txHash: Fr.ZERO,
30
+ anchorBlockTimestamp: 0n
31
+ };
32
+ }
25
33
  /**
26
34
  * A `TXESession` corresponds to a Noir `#[test]` function, and handles all of its oracle calls, stores test-specific
27
35
  * state, etc., independent of all other tests running in parallel.
@@ -44,10 +52,10 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
44
52
  chainId;
45
53
  version;
46
54
  nextBlockTimestamp;
47
- contractSyncService;
48
55
  state;
49
56
  authwits;
50
- constructor(logger, stateMachine, oracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobCoordinator, currentJobId, chainId, version, nextBlockTimestamp, contractSyncService){
57
+ lastCallInfo;
58
+ constructor(logger, stateMachine, oracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobCoordinator, currentJobId, chainId, version, nextBlockTimestamp){
51
59
  this.logger = logger;
52
60
  this.stateMachine = stateMachine;
53
61
  this.oracleHandler = oracleHandler;
@@ -66,11 +74,11 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
66
74
  this.chainId = chainId;
67
75
  this.version = version;
68
76
  this.nextBlockTimestamp = nextBlockTimestamp;
69
- this.contractSyncService = contractSyncService;
70
77
  this.state = {
71
78
  name: 'TOP_LEVEL'
72
79
  };
73
80
  this.authwits = new Map();
81
+ this.lastCallInfo = emptyLastCallState();
74
82
  }
75
83
  static async init(contractStore) {
76
84
  const store = await openTmpStore('txe-session');
@@ -100,10 +108,9 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
100
108
  const chainId = new Fr(await stateMachine.node.getChainId());
101
109
  const initialJobId = jobCoordinator.beginJob();
102
110
  const logger = createLogger('txe:session');
103
- const contractSyncService = new ContractSyncService(stateMachine.node, contractStore, noteStore, logger);
104
- const topLevelOracleHandler = new TXEOracleTopLevelContext(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, new Map(), contractSyncService);
111
+ const topLevelOracleHandler = new TXEOracleTopLevelContext(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, new Map());
105
112
  await topLevelOracleHandler.advanceBlocksBy(1);
106
- return new TXESession(logger, stateMachine, topLevelOracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobCoordinator, initialJobId, version, chainId, nextBlockTimestamp, contractSyncService);
113
+ return new TXESession(logger, stateMachine, topLevelOracleHandler, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobCoordinator, initialJobId, version, chainId, nextBlockTimestamp);
107
114
  }
108
115
  /**
109
116
  * Processes an oracle function invoked by the Noir test associated to this session.
@@ -134,6 +141,42 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
134
141
  this.currentJobId = this.jobCoordinator.beginJob();
135
142
  return this.currentJobId;
136
143
  }
144
+ resetLastCall() {
145
+ const notQueriedMessageCount = this.lastCallInfo.queried ? 0 : this.lastCallInfo.offchainEffects.filter((payload)=>payload[0]?.equals(OFFCHAIN_MESSAGE_IDENTIFIER)).length;
146
+ if (notQueriedMessageCount > 0) {
147
+ this.logger.warn(`Dropping ${notQueriedMessageCount} unqueried offchain message(s) from the previous top-level call. ` + `To deliver them, call \`env.offchain_messages()\` and forward the result to the recipient contract's ` + `\`offchain_receive\` utility before issuing another top-level call. To intentionally discard, assign ` + `to \`let _ = env.offchain_messages()\` to silence this warning.`);
148
+ }
149
+ this.lastCallInfo = emptyLastCallState();
150
+ }
151
+ recordOffchainEffect(data) {
152
+ this.lastCallInfo.offchainEffects.push(data);
153
+ }
154
+ setLastCallContext(txHash, anchorBlockTimestamp) {
155
+ this.lastCallInfo.txHash = txHash;
156
+ this.lastCallInfo.anchorBlockTimestamp = anchorBlockTimestamp;
157
+ }
158
+ async withTopLevelCallTracking(work) {
159
+ this.resetLastCall();
160
+ // Capture the anchor *before* `work` runs: private/public executor calls mine a new block as a
161
+ // side effect, and that block's timestamp should not be attributed to this call's anchor.
162
+ const anchorBlockTimestamp = (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.timestamp;
163
+ const { result, txHash } = await work();
164
+ this.setLastCallContext(txHash ?? Fr.ZERO, anchorBlockTimestamp);
165
+ return result;
166
+ }
167
+ getLastCallOffchainEffects() {
168
+ this.lastCallInfo.queried = true;
169
+ return {
170
+ effects: this.lastCallInfo.offchainEffects
171
+ };
172
+ }
173
+ getLastCallContext() {
174
+ const { txHash, anchorBlockTimestamp } = this.lastCallInfo;
175
+ return {
176
+ txHash,
177
+ anchorBlockTimestamp
178
+ };
179
+ }
137
180
  async enterTopLevelState() {
138
181
  switch(this.state.name){
139
182
  case 'PRIVATE':
@@ -162,7 +205,7 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
162
205
  }
163
206
  // Commit all staged stores from the job that was just completed, then begin a new job
164
207
  await this.cycleJob();
165
- this.oracleHandler = new TXEOracleTopLevelContext(this.stateMachine, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.accountStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.nextBlockTimestamp, this.version, this.chainId, this.authwits, this.contractSyncService);
208
+ this.oracleHandler = new TXEOracleTopLevelContext(this.stateMachine, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.accountStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.nextBlockTimestamp, this.version, this.chainId, this.authwits);
166
209
  this.state = {
167
210
  name: 'TOP_LEVEL'
168
211
  };
@@ -170,6 +213,7 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
170
213
  }
171
214
  async enterPrivateState(contractAddress = DEFAULT_ADDRESS, anchorBlockNumber) {
172
215
  this.exitTopLevelState();
216
+ this.resetLastCall();
173
217
  // Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
174
218
  // build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
175
219
  // a single transaction with the effects of what was done in the test.
@@ -212,7 +256,8 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
212
256
  l2TipsStore: this.stateMachine.node,
213
257
  jobId: this.currentJobId,
214
258
  scopes: await this.keyStore.getAccounts(),
215
- messageContextService: this.stateMachine.messageContextService
259
+ messageContextService: this.stateMachine.messageContextService,
260
+ simulator: new WASMSimulator()
216
261
  });
217
262
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
218
263
  // data) in order to refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The
@@ -226,15 +271,19 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
226
271
  taggingIndexCache
227
272
  };
228
273
  this.logger.debug(`Entered state ${this.state.name}`);
274
+ // Record the *resolved* anchor's timestamp — if the caller pinned the anchor to a past block
275
+ // via `anchorBlockNumber`, "latest" would be the wrong anchor for offchain-message semantics.
276
+ this.setLastCallContext(Fr.ZERO, anchorBlock.globalVariables.timestamp);
229
277
  return this.oracleHandler.getPrivateContextInputs();
230
278
  }
231
279
  async enterPublicState(contractAddress) {
232
280
  this.exitTopLevelState();
281
+ this.resetLastCall();
233
282
  // The PublicContext will create a block with a single transaction in it, containing the effects of what was done in
234
283
  // the test. The block therefore gets the *next* block number and timestamp.
235
- const latestBlockNumber = (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.blockNumber;
284
+ const latestHeader = await this.stateMachine.node.getBlockHeader('latest');
236
285
  const globalVariables = makeGlobalVariables(undefined, {
237
- blockNumber: BlockNumber(latestBlockNumber + 1),
286
+ blockNumber: BlockNumber(latestHeader.globalVariables.blockNumber + 1),
238
287
  timestamp: this.nextBlockTimestamp,
239
288
  version: this.version,
240
289
  chainId: this.chainId
@@ -244,9 +293,12 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
244
293
  name: 'PUBLIC'
245
294
  };
246
295
  this.logger.debug(`Entered state ${this.state.name}`);
296
+ // Public state is anchored at the latest block.
297
+ this.setLastCallContext(Fr.ZERO, latestHeader.globalVariables.timestamp);
247
298
  }
248
299
  async enterUtilityState(contractAddress = DEFAULT_ADDRESS) {
249
300
  this.exitTopLevelState();
301
+ this.resetLastCall();
250
302
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
251
303
  // There is no automatic message discovery and contract-driven syncing process in inlined private or utility
252
304
  // contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
@@ -269,15 +321,18 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
269
321
  capsuleService: new CapsuleService(this.capsuleStore, await this.keyStore.getAccounts()),
270
322
  privateEventStore: this.privateEventStore,
271
323
  messageContextService: this.stateMachine.messageContextService,
272
- contractSyncService: this.contractSyncService,
324
+ contractSyncService: this.stateMachine.contractSyncService,
273
325
  l2TipsStore: this.stateMachine.node,
274
326
  jobId: this.currentJobId,
275
- scopes: await this.keyStore.getAccounts()
327
+ scopes: await this.keyStore.getAccounts(),
328
+ simulator: new WASMSimulator()
276
329
  });
277
330
  this.state = {
278
331
  name: 'UTILITY'
279
332
  };
280
333
  this.logger.debug(`Entered state ${this.state.name}`);
334
+ // Utility state anchors at whatever the anchor block store is pointing to (tracked as latest).
335
+ this.setLastCallContext(Fr.ZERO, anchorBlockHeader.globalVariables.timestamp);
281
336
  }
282
337
  exitTopLevelState() {
283
338
  if (this.state.name != 'TOP_LEVEL') {
@@ -336,6 +391,7 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
336
391
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
337
392
  }
338
393
  try {
394
+ const simulator = new WASMSimulator();
339
395
  const oracle = new UtilityExecutionOracle({
340
396
  contractAddress: call.to,
341
397
  authWitnesses: [],
@@ -351,12 +407,13 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
351
407
  capsuleService: new CapsuleService(this.capsuleStore, scopes),
352
408
  privateEventStore: this.privateEventStore,
353
409
  messageContextService: this.stateMachine.messageContextService,
354
- contractSyncService: this.contractSyncService,
410
+ contractSyncService: this.stateMachine.contractSyncService,
355
411
  l2TipsStore: this.stateMachine.node,
356
412
  jobId: this.currentJobId,
357
- scopes
413
+ scopes,
414
+ simulator
358
415
  });
359
- await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
416
+ await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
360
417
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
361
418
  throw new ExecutionError(err.message, {
362
419
  contractAddress: call.to,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "0.0.1-commit.2b2662070",
3
+ "version": "0.0.1-commit.2c0ee1788",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "bin": "./dest/bin/index.js",
@@ -61,20 +61,20 @@
61
61
  ]
62
62
  },
63
63
  "dependencies": {
64
- "@aztec/accounts": "0.0.1-commit.2b2662070",
65
- "@aztec/archiver": "0.0.1-commit.2b2662070",
66
- "@aztec/aztec-node": "0.0.1-commit.2b2662070",
67
- "@aztec/aztec.js": "0.0.1-commit.2b2662070",
68
- "@aztec/bb-prover": "0.0.1-commit.2b2662070",
69
- "@aztec/constants": "0.0.1-commit.2b2662070",
70
- "@aztec/foundation": "0.0.1-commit.2b2662070",
71
- "@aztec/key-store": "0.0.1-commit.2b2662070",
72
- "@aztec/kv-store": "0.0.1-commit.2b2662070",
73
- "@aztec/protocol-contracts": "0.0.1-commit.2b2662070",
74
- "@aztec/pxe": "0.0.1-commit.2b2662070",
75
- "@aztec/simulator": "0.0.1-commit.2b2662070",
76
- "@aztec/stdlib": "0.0.1-commit.2b2662070",
77
- "@aztec/world-state": "0.0.1-commit.2b2662070",
64
+ "@aztec/accounts": "0.0.1-commit.2c0ee1788",
65
+ "@aztec/archiver": "0.0.1-commit.2c0ee1788",
66
+ "@aztec/aztec-node": "0.0.1-commit.2c0ee1788",
67
+ "@aztec/aztec.js": "0.0.1-commit.2c0ee1788",
68
+ "@aztec/bb-prover": "0.0.1-commit.2c0ee1788",
69
+ "@aztec/constants": "0.0.1-commit.2c0ee1788",
70
+ "@aztec/foundation": "0.0.1-commit.2c0ee1788",
71
+ "@aztec/key-store": "0.0.1-commit.2c0ee1788",
72
+ "@aztec/kv-store": "0.0.1-commit.2c0ee1788",
73
+ "@aztec/protocol-contracts": "0.0.1-commit.2c0ee1788",
74
+ "@aztec/pxe": "0.0.1-commit.2c0ee1788",
75
+ "@aztec/simulator": "0.0.1-commit.2c0ee1788",
76
+ "@aztec/stdlib": "0.0.1-commit.2c0ee1788",
77
+ "@aztec/world-state": "0.0.1-commit.2c0ee1788",
78
78
  "zod": "^3.23.8"
79
79
  },
80
80
  "devDependencies": {
@@ -68,7 +68,7 @@ export interface ITxeExecutionOracle {
68
68
  argsHash: Fr,
69
69
  isStaticCall: boolean,
70
70
  jobId: string,
71
- ): Promise<Fr[]>;
71
+ ): Promise<{ returnValues: Fr[]; offchainEffects: Fr[][] }>;
72
72
  executeUtilityFunction(
73
73
  targetContractAddress: AztecAddress,
74
74
  functionSelector: FunctionSelector,
@@ -15,7 +15,6 @@ import {
15
15
  CapsuleService,
16
16
  CapsuleStore,
17
17
  type ContractStore,
18
- type ContractSyncService,
19
18
  NoteStore,
20
19
  ORACLE_VERSION_MAJOR,
21
20
  PrivateEventStore,
@@ -116,7 +115,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
116
115
  private version: Fr,
117
116
  private chainId: Fr,
118
117
  private authwits: Map<string, AuthWitness>,
119
- private readonly contractSyncService: ContractSyncService,
120
118
  ) {
121
119
  this.logger = createLogger('txe:top_level_context');
122
120
  this.logger.debug('Entering Top Level Context');
@@ -514,11 +512,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
514
512
  }
515
513
  }
516
514
 
515
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
516
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
517
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
518
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
519
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
520
+
517
521
  if (isStaticCall) {
518
522
  await checkpoint!.revert();
519
523
 
520
524
  await forkedWorldTrees.close();
521
- return executionResult.returnValues ?? [];
525
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
522
526
  }
523
527
 
524
528
  const txEffect = TxEffect.empty();
@@ -540,7 +544,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
540
544
 
541
545
  await forkedWorldTrees.close();
542
546
 
543
- return executionResult.returnValues ?? [];
547
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
544
548
  }
545
549
 
546
550
  async publicCallNewFlow(
@@ -749,6 +753,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
749
753
 
750
754
  try {
751
755
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
756
+ const simulator = new WASMSimulator();
752
757
  const oracle = new UtilityExecutionOracle({
753
758
  contractAddress: call.to,
754
759
  authWitnesses: [],
@@ -764,12 +769,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
764
769
  capsuleService: new CapsuleService(this.capsuleStore, scopes),
765
770
  privateEventStore: this.privateEventStore,
766
771
  messageContextService: this.stateMachine.messageContextService,
767
- contractSyncService: this.contractSyncService,
772
+ contractSyncService: this.stateMachine.contractSyncService,
768
773
  l2TipsStore: this.stateMachine.node,
769
774
  jobId,
770
775
  scopes,
776
+ simulator,
771
777
  });
772
- const acirExecutionResult = await new WASMSimulator()
778
+ const acirExecutionResult = await simulator
773
779
  .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
774
780
  .catch((err: Error) => {
775
781
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
@@ -1,6 +1,6 @@
1
1
  import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
2
2
  import { Fr, Point } from '@aztec/aztec.js/fields';
3
- import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
3
+ import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, PRIVATE_LOG_CIPHERTEXT_LEN } from '@aztec/constants';
4
4
  import { BlockNumber } from '@aztec/foundation/branded-types';
5
5
  import {
6
6
  type IMiscOracle,
@@ -298,6 +298,46 @@ export class RPCTranslator {
298
298
  ]);
299
299
  }
300
300
 
301
+ // eslint-disable-next-line camelcase
302
+ aztec_txe_getLastCallOffchainEffects() {
303
+ // This oracle returns all offchain effect payloads (messages, authwit requests, etc.) emitted by the last top-level call,
304
+ // MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY is arbitrarily set at 64 because we need a bound. Nothing inherent about it.
305
+ const MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY = 64;
306
+ // Must match MAX_OFFCHAIN_EFFECT_LEN in txe_oracles.nr.
307
+ const MAX_OFFCHAIN_EFFECT_LEN = 2 + PRIVATE_LOG_CIPHERTEXT_LEN;
308
+
309
+ const { effects } = this.stateHandler.getLastCallOffchainEffects();
310
+
311
+ if (effects.length > MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY) {
312
+ throw new Error(`${effects.length} offchain effects exceed max ${MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY}`);
313
+ }
314
+ if (effects.some(e => e.length > MAX_OFFCHAIN_EFFECT_LEN)) {
315
+ throw new Error(`Some offchain effect has length larger than max ${MAX_OFFCHAIN_EFFECT_LEN}`);
316
+ }
317
+
318
+ const rawArrayStorage = effects
319
+ .map(e => e.concat(Array(MAX_OFFCHAIN_EFFECT_LEN - e.length).fill(new Fr(0))))
320
+ .concat(
321
+ Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(Array(MAX_OFFCHAIN_EFFECT_LEN).fill(new Fr(0))),
322
+ )
323
+ .flat();
324
+
325
+ const effectLengths = effects
326
+ .map(e => new Fr(e.length))
327
+ .concat(Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(new Fr(0)));
328
+
329
+ const count = new Fr(effects.length);
330
+
331
+ return toForeignCallResult([toArray(rawArrayStorage), toArray(effectLengths), toSingle(count)]);
332
+ }
333
+
334
+ // eslint-disable-next-line camelcase
335
+ aztec_txe_getLastCallContext() {
336
+ const { txHash, anchorBlockTimestamp } = this.stateHandler.getLastCallContext();
337
+ const isSome = txHash.isZero() ? 0 : 1;
338
+ return toForeignCallResult([toSingle(isSome), toSingle(txHash), toSingle(new Fr(anchorBlockTimestamp))]);
339
+ }
340
+
301
341
  // eslint-disable-next-line camelcase
302
342
  async aztec_txe_getPrivateEvents(
303
343
  foreignSelector: ForeignCallSingle,
@@ -1071,8 +1111,13 @@ export class RPCTranslator {
1071
1111
  }
1072
1112
 
1073
1113
  // eslint-disable-next-line camelcase
1074
- aztec_utl_emitOffchainEffect(_foreignData: ForeignCallArray) {
1075
- throw new Error('Offchain effects are not yet supported in the TestEnvironment');
1114
+ aztec_utl_emitOffchainEffect(foreignData: ForeignCallArray) {
1115
+ // Record the raw payload against the currently-executing top-level call. The Noir side
1116
+ // (via `env.offchain_messages()`) is responsible for decoding the protocol-reserved prefix
1117
+ // (`OFFCHAIN_MESSAGE_IDENTIFIER`, recipient) and turning each payload into an `OffchainMessage` struct suitable
1118
+ // for `offchain_receive`.
1119
+ this.stateHandler.recordOffchainEffect(fromArray(foreignData));
1120
+ return Promise.resolve(toForeignCallResult([]));
1076
1121
  }
1077
1122
 
1078
1123
  // AVM opcodes
@@ -1281,18 +1326,38 @@ export class RPCTranslator {
1281
1326
  const argsHash = fromSingle(foreignArgsHash);
1282
1327
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1283
1328
 
1284
- const returnValues = await this.handlerAsTxe().privateCallNewFlow(
1285
- from,
1286
- targetContractAddress,
1287
- functionSelector,
1288
- args,
1289
- argsHash,
1290
- isStaticCall,
1291
- this.stateHandler.getCurrentJob(),
1292
- );
1329
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1330
+ const { returnValues, offchainEffects } = await this.handlerAsTxe().privateCallNewFlow(
1331
+ from,
1332
+ targetContractAddress,
1333
+ functionSelector,
1334
+ args,
1335
+ argsHash,
1336
+ isStaticCall,
1337
+ this.stateHandler.getCurrentJob(),
1338
+ );
1339
+
1340
+ // Private execution collects offchain effects inside PXE's PrivateExecutionOracle rather than
1341
+ // round-tripping them through `aztec_utl_emitOffchainEffect`, so the session buffer is empty
1342
+ // at this point. Drain the effects from the execution tree into the session buffer so the
1343
+ // next `env.offchain_messages()` call in the test sees them.
1344
+ for (const data of offchainEffects) {
1345
+ this.stateHandler.recordOffchainEffect(data);
1346
+ }
1347
+
1348
+ // TODO(F-335): Avoid doing the following call here.
1349
+ await this.stateHandler.cycleJob();
1350
+
1351
+ if (isStaticCall) {
1352
+ // Static calls revert their checkpoint and mine no block, so there is no tx hash to tag
1353
+ // offchain effects with. Querying `getLastTxEffects()` here would return an unrelated
1354
+ // predecessor tx.
1355
+ return { result: returnValues };
1356
+ }
1357
+ const { txHash } = await this.handlerAsTxe().getLastTxEffects();
1358
+ return { result: returnValues, txHash: txHash.hash };
1359
+ });
1293
1360
 
1294
- // TODO(F-335): Avoid doing the following call here.
1295
- await this.stateHandler.cycleJob();
1296
1361
  return toForeignCallResult([toArray(returnValues)]);
1297
1362
  }
1298
1363
 
@@ -1306,15 +1371,20 @@ export class RPCTranslator {
1306
1371
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
1307
1372
  const args = fromArray(foreignArgs);
1308
1373
 
1309
- const returnValues = await this.handlerAsTxe().executeUtilityFunction(
1310
- targetContractAddress,
1311
- functionSelector,
1312
- args,
1313
- this.stateHandler.getCurrentJob(),
1314
- );
1374
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1375
+ const returnValues = await this.handlerAsTxe().executeUtilityFunction(
1376
+ targetContractAddress,
1377
+ functionSelector,
1378
+ args,
1379
+ this.stateHandler.getCurrentJob(),
1380
+ );
1381
+
1382
+ // TODO(F-335): Avoid doing the following call here.
1383
+ await this.stateHandler.cycleJob();
1384
+
1385
+ return { result: returnValues };
1386
+ });
1315
1387
 
1316
- // TODO(F-335): Avoid doing the following call here.
1317
- await this.stateHandler.cycleJob();
1318
1388
  return toForeignCallResult([toArray(returnValues)]);
1319
1389
  }
1320
1390
 
@@ -1330,10 +1400,20 @@ export class RPCTranslator {
1330
1400
  const calldata = fromArray(foreignCalldata);
1331
1401
  const isStaticCall = fromSingle(foreignIsStaticCall).toBool();
1332
1402
 
1333
- const returnValues = await this.handlerAsTxe().publicCallNewFlow(from, address, calldata, isStaticCall);
1403
+ const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => {
1404
+ const returnValues = await this.handlerAsTxe().publicCallNewFlow(from, address, calldata, isStaticCall);
1405
+
1406
+ // TODO(F-335): Avoid doing the following call here.
1407
+ await this.stateHandler.cycleJob();
1408
+
1409
+ if (isStaticCall) {
1410
+ // See equivalent branch in `aztec_txe_privateCallNewFlow`.
1411
+ return { result: returnValues };
1412
+ }
1413
+ const { txHash } = await this.handlerAsTxe().getLastTxEffects();
1414
+ return { result: returnValues, txHash: txHash.hash };
1415
+ });
1334
1416
 
1335
- // TODO(F-335): Avoid doing the following call here.
1336
- await this.stateHandler.cycleJob();
1337
1417
  return toForeignCallResult([toArray(returnValues)]);
1338
1418
  }
1339
1419