@aztec/txe 0.0.1-commit.5914bae → 0.0.1-commit.59a0419c6
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/oracle/interfaces.d.ts +5 -2
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.d.ts +7 -5
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +17 -6
- package/dest/rpc_translator.d.ts +10 -2
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +98 -21
- package/dest/state_machine/archiver.d.ts +1 -1
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +2 -1
- package/dest/state_machine/dummy_p2p_client.d.ts +3 -2
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +5 -2
- package/dest/state_machine/global_variable_builder.d.ts +9 -4
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +9 -3
- package/dest/state_machine/index.d.ts +1 -1
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +2 -2
- package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +35 -2
- package/dest/txe_session.d.ts +48 -4
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +66 -13
- package/dest/util/encoding.d.ts +89 -18
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +4 -0
- package/dest/util/txe_public_contract_data_source.d.ts +1 -1
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +1 -3
- package/package.json +15 -15
- package/src/oracle/interfaces.ts +1 -1
- package/src/oracle/txe_oracle_top_level_context.ts +9 -5
- package/src/rpc_translator.ts +113 -33
- package/src/state_machine/archiver.ts +1 -0
- package/src/state_machine/dummy_p2p_client.ts +6 -2
- package/src/state_machine/global_variable_builder.ts +18 -3
- package/src/state_machine/index.ts +3 -1
- package/src/state_machine/mock_epoch_cache.ts +46 -3
- package/src/txe_session.ts +122 -11
- package/src/util/encoding.ts +5 -0
- package/src/util/txe_public_contract_data_source.ts +0 -2
|
@@ -1,15 +1,29 @@
|
|
|
1
|
+
import type { SimulationOverridesPlan } from '@aztec/ethereum/contracts';
|
|
1
2
|
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { times } from '@aztec/foundation/collection';
|
|
2
4
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
5
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
-
import { GasFees } from '@aztec/stdlib/gas';
|
|
6
|
+
import { FEE_ORACLE_LAG, GasFees } from '@aztec/stdlib/gas';
|
|
5
7
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
6
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type CheckpointGlobalVariables,
|
|
10
|
+
type FeeProvider,
|
|
11
|
+
type GlobalVariableBuilder,
|
|
12
|
+
GlobalVariables,
|
|
13
|
+
} from '@aztec/stdlib/tx';
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
/** Simple FeeProvider for TXE that returns zero fees. */
|
|
16
|
+
export class TXEFeeProvider implements FeeProvider {
|
|
9
17
|
public getCurrentMinFees(): Promise<GasFees> {
|
|
10
18
|
return Promise.resolve(new GasFees(0, 0));
|
|
11
19
|
}
|
|
12
20
|
|
|
21
|
+
public getPredictedMinFees(): Promise<GasFees[]> {
|
|
22
|
+
return Promise.resolve(times(FEE_ORACLE_LAG, () => new GasFees(0, 0)));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
|
|
13
27
|
public buildGlobalVariables(
|
|
14
28
|
_blockNumber: BlockNumber,
|
|
15
29
|
_coinbase: EthAddress,
|
|
@@ -23,6 +37,7 @@ export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
|
|
|
23
37
|
_coinbase: EthAddress,
|
|
24
38
|
_feeRecipient: AztecAddress,
|
|
25
39
|
_slotNumber: SlotNumber,
|
|
40
|
+
_simulationOverridesPlan?: SimulationOverridesPlan,
|
|
26
41
|
): Promise<CheckpointGlobalVariables> {
|
|
27
42
|
const vars = makeGlobalVariables();
|
|
28
43
|
return Promise.resolve({
|
|
@@ -13,7 +13,7 @@ import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
|
13
13
|
|
|
14
14
|
import { TXEArchiver } from './archiver.js';
|
|
15
15
|
import { DummyP2P } from './dummy_p2p_client.js';
|
|
16
|
-
import { TXEGlobalVariablesBuilder } from './global_variable_builder.js';
|
|
16
|
+
import { TXEFeeProvider, TXEGlobalVariablesBuilder } from './global_variable_builder.js';
|
|
17
17
|
import { MockEpochCache } from './mock_epoch_cache.js';
|
|
18
18
|
import { TXESynchronizer } from './synchronizer.js';
|
|
19
19
|
|
|
@@ -56,9 +56,11 @@ export class TXEStateMachine {
|
|
|
56
56
|
VERSION,
|
|
57
57
|
CHAIN_ID,
|
|
58
58
|
new TXEGlobalVariablesBuilder(),
|
|
59
|
+
new TXEFeeProvider(),
|
|
59
60
|
new MockEpochCache(),
|
|
60
61
|
getPackageVersion() ?? '',
|
|
61
62
|
new TestCircuitVerifier(),
|
|
63
|
+
new TestCircuitVerifier(),
|
|
62
64
|
undefined,
|
|
63
65
|
log,
|
|
64
66
|
);
|
|
@@ -8,7 +8,7 @@ import { EmptyL1RollupConstants, type L1RollupConstants } from '@aztec/stdlib/ep
|
|
|
8
8
|
* Since in TXE we don't validate transactions, mock suffices here.
|
|
9
9
|
*/
|
|
10
10
|
export class MockEpochCache implements EpochCacheInterface {
|
|
11
|
-
getCommittee(): Promise<EpochCommitteeInfo> {
|
|
11
|
+
getCommittee(_slot: SlotTag = 'now'): Promise<EpochCommitteeInfo> {
|
|
12
12
|
return Promise.resolve({
|
|
13
13
|
committee: undefined,
|
|
14
14
|
seed: 0n,
|
|
@@ -17,6 +17,22 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
getSlotNow(): SlotNumber {
|
|
21
|
+
return SlotNumber(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getTargetSlot(): SlotNumber {
|
|
25
|
+
return SlotNumber(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getEpochNow(): EpochNumber {
|
|
29
|
+
return EpochNumber.ZERO;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getTargetEpoch(): EpochNumber {
|
|
33
|
+
return EpochNumber.ZERO;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
|
|
21
37
|
return {
|
|
22
38
|
epoch: EpochNumber.ZERO,
|
|
@@ -26,15 +42,27 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
26
42
|
};
|
|
27
43
|
}
|
|
28
44
|
|
|
29
|
-
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
45
|
+
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
|
|
30
46
|
return {
|
|
31
47
|
epoch: EpochNumber.ZERO,
|
|
32
48
|
slot: SlotNumber(0),
|
|
33
49
|
ts: 0n,
|
|
34
|
-
|
|
50
|
+
nowSeconds: 0n,
|
|
35
51
|
};
|
|
36
52
|
}
|
|
37
53
|
|
|
54
|
+
getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
|
|
55
|
+
return this.getEpochAndSlotInNextL1Slot();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
isProposerPipeliningEnabled(): boolean {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
pipeliningOffset(): number {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
38
66
|
getProposerIndexEncoding(_epoch: EpochNumber, _slot: SlotNumber, _seed: bigint): `0x${string}` {
|
|
39
67
|
return '0x00';
|
|
40
68
|
}
|
|
@@ -50,6 +78,13 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
50
78
|
};
|
|
51
79
|
}
|
|
52
80
|
|
|
81
|
+
getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
82
|
+
return {
|
|
83
|
+
targetSlot: SlotNumber(0),
|
|
84
|
+
nextSlot: SlotNumber(0),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
53
88
|
getProposerAttesterAddressInSlot(_slot: SlotNumber): Promise<EthAddress | undefined> {
|
|
54
89
|
return Promise.resolve(undefined);
|
|
55
90
|
}
|
|
@@ -66,6 +101,14 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
66
101
|
return Promise.resolve([]);
|
|
67
102
|
}
|
|
68
103
|
|
|
104
|
+
isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean> {
|
|
105
|
+
return Promise.resolve(false);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
isEscapeHatchOpenAtSlot(_slot: SlotTag): Promise<boolean> {
|
|
109
|
+
return Promise.resolve(false);
|
|
110
|
+
}
|
|
111
|
+
|
|
69
112
|
getL1Constants(): L1RollupConstants {
|
|
70
113
|
return EmptyL1RollupConstants;
|
|
71
114
|
}
|
package/src/txe_session.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
CapsuleService,
|
|
10
10
|
CapsuleStore,
|
|
11
11
|
ContractStore,
|
|
12
|
-
ContractSyncService,
|
|
13
12
|
JobCoordinator,
|
|
14
13
|
NoteService,
|
|
15
14
|
NoteStore,
|
|
@@ -43,7 +42,7 @@ import { GasSettings } from '@aztec/stdlib/gas';
|
|
|
43
42
|
import { computeProtocolNullifier } from '@aztec/stdlib/hash';
|
|
44
43
|
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
45
44
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
46
|
-
import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
|
|
45
|
+
import { CallContext, GlobalVariables, OFFCHAIN_MESSAGE_IDENTIFIER, TxContext } from '@aztec/stdlib/tx';
|
|
47
46
|
|
|
48
47
|
import { z } from 'zod';
|
|
49
48
|
|
|
@@ -118,6 +117,65 @@ export interface TXESessionStateHandler {
|
|
|
118
117
|
// TODO(F-335): Exposing the job info is abstraction breakage - drop the following 2 functions.
|
|
119
118
|
cycleJob(): Promise<string>;
|
|
120
119
|
getCurrentJob(): string;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Runs an executor-style top-level call (private/public call, utility execution) with last-call tracking.
|
|
123
|
+
*/
|
|
124
|
+
withTopLevelCallTracking<T>(work: () => Promise<{ result: T; txHash?: Fr }>): Promise<T>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Captures a raw offchain effect payload for consumption from test environment. Called by the `emit_offchain_effect`
|
|
128
|
+
* oracle handler whenever a contract function emits an offchain message, at any call depth.
|
|
129
|
+
*/
|
|
130
|
+
recordOffchainEffect(data: Fr[]): void;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Returns the raw offchain effect payloads emitted by the last top-level call. Each payload follows the protocol
|
|
134
|
+
* convention documented on `OFFCHAIN_MESSAGE_IDENTIFIER`, i.e. `[identifier, recipient, ...ciphertext]`. Decoding into
|
|
135
|
+
* `OffchainMessage` structs happens on the Noir side of the test helper. Marks the buffer as queried so the
|
|
136
|
+
* unqueried-messages warning doesn't fire on the next reset.
|
|
137
|
+
*/
|
|
138
|
+
getLastCallOffchainEffects(): { effects: Fr[][] };
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Returns the context of the last top-level call: its tx hash (`Fr.ZERO` if the call was tx-less) and the anchor
|
|
142
|
+
* block timestamp captured at the start of the call. Does *not* mark the buffer as queried — context reads are
|
|
143
|
+
* metadata, not effect consumption.
|
|
144
|
+
*/
|
|
145
|
+
getLastCallContext(): { txHash: Fr; anchorBlockTimestamp: bigint };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Session state tracking the most recently completed top-level call: the offchain effect buffer it produced, and the
|
|
150
|
+
* call's context (tx hash + anchor block timestamp). The context is refreshed on every top-level call, independently
|
|
151
|
+
* of whether the call produced offchain effects.
|
|
152
|
+
*/
|
|
153
|
+
interface LastCallState {
|
|
154
|
+
/**
|
|
155
|
+
* Raw offchain effect payloads emitted by the currently-executing (or most recently completed) top-level call. Wiped
|
|
156
|
+
* at the start of every top-level entry point, appended to on every `emit_offchain_effect` oracle invocation.
|
|
157
|
+
*/
|
|
158
|
+
offchainEffects: Fr[][];
|
|
159
|
+
/**
|
|
160
|
+
* Tracks whether the test has queried `effects` since the last reset. If a new top-level call clobbers the buffer
|
|
161
|
+
* without it being queried first, any accumulated messages are lost and we emit a warning so tests don't silently
|
|
162
|
+
* drop delivery.
|
|
163
|
+
*/
|
|
164
|
+
queried: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Tx hash of the most recently completed top-level call, or `Fr.ZERO` if the call was tx-less (context setters,
|
|
167
|
+
* utility execution). Populated by call executor handlers after execution completes.
|
|
168
|
+
*/
|
|
169
|
+
txHash: Fr;
|
|
170
|
+
/**
|
|
171
|
+
* Anchor block timestamp of the most recently completed top-level call, captured from the anchor block header that
|
|
172
|
+
* was active when the call started. Populated by call executor handlers after execution completes.
|
|
173
|
+
*/
|
|
174
|
+
anchorBlockTimestamp: bigint;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function emptyLastCallState(): LastCallState {
|
|
178
|
+
return { offchainEffects: [], queried: false, txHash: Fr.ZERO, anchorBlockTimestamp: 0n };
|
|
121
179
|
}
|
|
122
180
|
|
|
123
181
|
/**
|
|
@@ -127,6 +185,7 @@ export interface TXESessionStateHandler {
|
|
|
127
185
|
export class TXESession implements TXESessionStateHandler {
|
|
128
186
|
private state: SessionState = { name: 'TOP_LEVEL' };
|
|
129
187
|
private authwits: Map<string, AuthWitness> = new Map();
|
|
188
|
+
private lastCallInfo: LastCallState = emptyLastCallState();
|
|
130
189
|
|
|
131
190
|
constructor(
|
|
132
191
|
private logger: Logger,
|
|
@@ -151,7 +210,6 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
151
210
|
private chainId: Fr,
|
|
152
211
|
private version: Fr,
|
|
153
212
|
private nextBlockTimestamp: bigint,
|
|
154
|
-
private contractSyncService: ContractSyncService,
|
|
155
213
|
) {}
|
|
156
214
|
|
|
157
215
|
static async init(contractStore: ContractStore) {
|
|
@@ -188,7 +246,6 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
188
246
|
const initialJobId = jobCoordinator.beginJob();
|
|
189
247
|
|
|
190
248
|
const logger = createLogger('txe:session');
|
|
191
|
-
const contractSyncService = new ContractSyncService(stateMachine.node, contractStore, noteStore, logger);
|
|
192
249
|
|
|
193
250
|
const topLevelOracleHandler = new TXEOracleTopLevelContext(
|
|
194
251
|
stateMachine,
|
|
@@ -206,7 +263,6 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
206
263
|
version,
|
|
207
264
|
chainId,
|
|
208
265
|
new Map(),
|
|
209
|
-
contractSyncService,
|
|
210
266
|
);
|
|
211
267
|
await topLevelOracleHandler.advanceBlocksBy(1);
|
|
212
268
|
|
|
@@ -229,7 +285,6 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
229
285
|
version,
|
|
230
286
|
chainId,
|
|
231
287
|
nextBlockTimestamp,
|
|
232
|
-
contractSyncService,
|
|
233
288
|
);
|
|
234
289
|
}
|
|
235
290
|
|
|
@@ -275,6 +330,50 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
275
330
|
return this.currentJobId;
|
|
276
331
|
}
|
|
277
332
|
|
|
333
|
+
private resetLastCall(): void {
|
|
334
|
+
const notQueriedMessageCount = this.lastCallInfo.queried
|
|
335
|
+
? 0
|
|
336
|
+
: this.lastCallInfo.offchainEffects.filter(payload => payload[0]?.equals(OFFCHAIN_MESSAGE_IDENTIFIER)).length;
|
|
337
|
+
if (notQueriedMessageCount > 0) {
|
|
338
|
+
this.logger.warn(
|
|
339
|
+
`Dropping ${notQueriedMessageCount} unqueried offchain message(s) from the previous top-level call. ` +
|
|
340
|
+
`To deliver them, call \`env.offchain_messages()\` and forward the result to the recipient contract's ` +
|
|
341
|
+
`\`offchain_receive\` utility before issuing another top-level call. To intentionally discard, assign ` +
|
|
342
|
+
`to \`let _ = env.offchain_messages()\` to silence this warning.`,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
this.lastCallInfo = emptyLastCallState();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
recordOffchainEffect(data: Fr[]): void {
|
|
349
|
+
this.lastCallInfo.offchainEffects.push(data);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
private setLastCallContext(txHash: Fr, anchorBlockTimestamp: bigint): void {
|
|
353
|
+
this.lastCallInfo.txHash = txHash;
|
|
354
|
+
this.lastCallInfo.anchorBlockTimestamp = anchorBlockTimestamp;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async withTopLevelCallTracking<T>(work: () => Promise<{ result: T; txHash?: Fr }>): Promise<T> {
|
|
358
|
+
this.resetLastCall();
|
|
359
|
+
// Capture the anchor *before* `work` runs: private/public executor calls mine a new block as a
|
|
360
|
+
// side effect, and that block's timestamp should not be attributed to this call's anchor.
|
|
361
|
+
const anchorBlockTimestamp = (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
|
|
362
|
+
const { result, txHash } = await work();
|
|
363
|
+
this.setLastCallContext(txHash ?? Fr.ZERO, anchorBlockTimestamp);
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
getLastCallOffchainEffects(): { effects: Fr[][] } {
|
|
368
|
+
this.lastCallInfo.queried = true;
|
|
369
|
+
return { effects: this.lastCallInfo.offchainEffects };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
getLastCallContext(): { txHash: Fr; anchorBlockTimestamp: bigint } {
|
|
373
|
+
const { txHash, anchorBlockTimestamp } = this.lastCallInfo;
|
|
374
|
+
return { txHash, anchorBlockTimestamp };
|
|
375
|
+
}
|
|
376
|
+
|
|
278
377
|
async enterTopLevelState() {
|
|
279
378
|
switch (this.state.name) {
|
|
280
379
|
case 'PRIVATE': {
|
|
@@ -316,7 +415,6 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
316
415
|
this.version,
|
|
317
416
|
this.chainId,
|
|
318
417
|
this.authwits,
|
|
319
|
-
this.contractSyncService,
|
|
320
418
|
);
|
|
321
419
|
|
|
322
420
|
this.state = { name: 'TOP_LEVEL' };
|
|
@@ -328,6 +426,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
328
426
|
anchorBlockNumber?: BlockNumber,
|
|
329
427
|
): Promise<PrivateContextInputs> {
|
|
330
428
|
this.exitTopLevelState();
|
|
429
|
+
this.resetLastCall();
|
|
331
430
|
|
|
332
431
|
// Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
|
|
333
432
|
// build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
|
|
@@ -389,17 +488,22 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
389
488
|
this.state = { name: 'PRIVATE', nextBlockGlobalVariables, noteCache, taggingIndexCache };
|
|
390
489
|
this.logger.debug(`Entered state ${this.state.name}`);
|
|
391
490
|
|
|
491
|
+
// Record the *resolved* anchor's timestamp — if the caller pinned the anchor to a past block
|
|
492
|
+
// via `anchorBlockNumber`, "latest" would be the wrong anchor for offchain-message semantics.
|
|
493
|
+
this.setLastCallContext(Fr.ZERO, anchorBlock!.globalVariables.timestamp);
|
|
494
|
+
|
|
392
495
|
return (this.oracleHandler as PrivateExecutionOracle).getPrivateContextInputs();
|
|
393
496
|
}
|
|
394
497
|
|
|
395
498
|
async enterPublicState(contractAddress?: AztecAddress) {
|
|
396
499
|
this.exitTopLevelState();
|
|
500
|
+
this.resetLastCall();
|
|
397
501
|
|
|
398
502
|
// The PublicContext will create a block with a single transaction in it, containing the effects of what was done in
|
|
399
503
|
// the test. The block therefore gets the *next* block number and timestamp.
|
|
400
|
-
const
|
|
504
|
+
const latestHeader = (await this.stateMachine.node.getBlockHeader('latest'))!;
|
|
401
505
|
const globalVariables = makeGlobalVariables(undefined, {
|
|
402
|
-
blockNumber: BlockNumber(
|
|
506
|
+
blockNumber: BlockNumber(latestHeader.globalVariables.blockNumber + 1),
|
|
403
507
|
timestamp: this.nextBlockTimestamp,
|
|
404
508
|
version: this.version,
|
|
405
509
|
chainId: this.chainId,
|
|
@@ -414,10 +518,14 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
414
518
|
|
|
415
519
|
this.state = { name: 'PUBLIC' };
|
|
416
520
|
this.logger.debug(`Entered state ${this.state.name}`);
|
|
521
|
+
|
|
522
|
+
// Public state is anchored at the latest block.
|
|
523
|
+
this.setLastCallContext(Fr.ZERO, latestHeader.globalVariables.timestamp);
|
|
417
524
|
}
|
|
418
525
|
|
|
419
526
|
async enterUtilityState(contractAddress: AztecAddress = DEFAULT_ADDRESS) {
|
|
420
527
|
this.exitTopLevelState();
|
|
528
|
+
this.resetLastCall();
|
|
421
529
|
|
|
422
530
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
423
531
|
|
|
@@ -448,7 +556,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
448
556
|
capsuleService: new CapsuleService(this.capsuleStore, await this.keyStore.getAccounts()),
|
|
449
557
|
privateEventStore: this.privateEventStore,
|
|
450
558
|
messageContextService: this.stateMachine.messageContextService,
|
|
451
|
-
contractSyncService: this.contractSyncService,
|
|
559
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
452
560
|
l2TipsStore: this.stateMachine.node,
|
|
453
561
|
jobId: this.currentJobId,
|
|
454
562
|
scopes: await this.keyStore.getAccounts(),
|
|
@@ -456,6 +564,9 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
456
564
|
|
|
457
565
|
this.state = { name: 'UTILITY' };
|
|
458
566
|
this.logger.debug(`Entered state ${this.state.name}`);
|
|
567
|
+
|
|
568
|
+
// Utility state anchors at whatever the anchor block store is pointing to (tracked as latest).
|
|
569
|
+
this.setLastCallContext(Fr.ZERO, anchorBlockHeader.globalVariables.timestamp);
|
|
459
570
|
}
|
|
460
571
|
|
|
461
572
|
private exitTopLevelState() {
|
|
@@ -542,7 +653,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
542
653
|
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
543
654
|
privateEventStore: this.privateEventStore,
|
|
544
655
|
messageContextService: this.stateMachine.messageContextService,
|
|
545
|
-
contractSyncService: this.contractSyncService,
|
|
656
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
546
657
|
l2TipsStore: this.stateMachine.node,
|
|
547
658
|
jobId: this.currentJobId,
|
|
548
659
|
scopes,
|
package/src/util/encoding.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import { hexToBuffer } from '@aztec/foundation/string';
|
|
4
4
|
import { type ContractArtifact, ContractArtifactSchema } from '@aztec/stdlib/abi';
|
|
5
5
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
|
+
import { BlockHash } from '@aztec/stdlib/block';
|
|
6
7
|
import { type ContractInstanceWithAddress, ContractInstanceWithAddressSchema } from '@aztec/stdlib/contract';
|
|
7
8
|
|
|
8
9
|
import { z } from 'zod';
|
|
@@ -25,6 +26,10 @@ export function addressFromSingle(obj: ForeignCallSingle) {
|
|
|
25
26
|
return new AztecAddress(fromSingle(obj));
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
export function blockHashFromSingle(obj: ForeignCallSingle) {
|
|
30
|
+
return new BlockHash(fromSingle(obj));
|
|
31
|
+
}
|
|
32
|
+
|
|
28
33
|
export function fromArray(obj: ForeignCallArray) {
|
|
29
34
|
return obj.map(str => Fr.fromBuffer(hexToBuffer(str)));
|
|
30
35
|
}
|
|
@@ -26,8 +26,6 @@ export class TXEPublicContractDataSource implements ContractDataSource {
|
|
|
26
26
|
packedBytecode: contractClass.packedBytecode,
|
|
27
27
|
privateFunctionsRoot: contractClass.privateFunctionsRoot,
|
|
28
28
|
version: contractClass.version,
|
|
29
|
-
privateFunctions: [],
|
|
30
|
-
utilityFunctions: [],
|
|
31
29
|
};
|
|
32
30
|
}
|
|
33
31
|
|