@aztec/simulator 0.43.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/acvm/oracle/oracle.d.ts +3 -1
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +12 -6
- package/dest/acvm/oracle/typed_oracle.d.ts +6 -4
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +8 -2
- package/dest/avm/avm_context.d.ts +1 -1
- package/dest/avm/avm_context.d.ts.map +1 -1
- package/dest/avm/avm_context.js +3 -3
- package/dest/avm/{avm_message_call_result.d.ts → avm_contract_call_result.d.ts} +2 -2
- package/dest/avm/avm_contract_call_result.d.ts.map +1 -0
- package/dest/avm/avm_contract_call_result.js +18 -0
- package/dest/avm/avm_execution_environment.d.ts +8 -10
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +15 -19
- package/dest/avm/avm_gas.js +2 -2
- package/dest/avm/avm_simulator.d.ts +4 -4
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +7 -8
- package/dest/avm/bytecode_utils.d.ts +5 -0
- package/dest/avm/bytecode_utils.d.ts.map +1 -0
- package/dest/avm/bytecode_utils.js +29 -0
- package/dest/avm/errors.js +2 -2
- package/dest/avm/fixtures/index.d.ts +10 -6
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +10 -17
- package/dest/avm/journal/journal.d.ts +56 -65
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +80 -117
- package/dest/avm/journal/nullifiers.d.ts +21 -8
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +26 -8
- package/dest/avm/journal/public_storage.d.ts +5 -1
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +11 -2
- package/dest/avm/opcodes/accrued_substate.d.ts +1 -2
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +8 -17
- package/dest/avm/opcodes/environment_getters.d.ts +13 -8
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +20 -13
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +11 -27
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +5 -5
- package/dest/avm/serialization/instruction_serialization.d.ts +9 -9
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +10 -10
- package/dest/avm/test_utils.d.ts +14 -0
- package/dest/avm/test_utils.d.ts.map +1 -0
- package/dest/avm/test_utils.js +36 -0
- package/dest/client/client_execution_context.d.ts +6 -4
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +8 -6
- package/dest/client/execution_note_cache.d.ts.map +1 -1
- package/dest/client/execution_note_cache.js +1 -1
- package/dest/client/execution_result.d.ts +2 -1
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +1 -1
- package/dest/client/index.d.ts +2 -0
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +3 -1
- package/dest/client/simulator.d.ts +3 -3
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +1 -1
- package/dest/client/view_data_oracle.d.ts +5 -1
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +12 -4
- package/dest/mocks/fixtures.d.ts +3 -3
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +6 -5
- package/dest/public/abstract_phase_manager.d.ts +1 -0
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +17 -14
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
- package/dest/public/app_logic_phase_manager.js +2 -1
- package/dest/public/execution.d.ts +33 -30
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +2 -2
- package/dest/public/executor.d.ts +12 -7
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +42 -33
- package/dest/public/hints_builder.d.ts +1 -1
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -1
- package/dest/public/public_kernel.d.ts +1 -1
- package/dest/public/public_kernel.d.ts.map +1 -1
- package/dest/public/public_kernel.js +2 -2
- package/dest/public/public_processor.d.ts +5 -2
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +142 -123
- package/dest/public/side_effect_trace.d.ts +87 -0
- package/dest/public/side_effect_trace.d.ts.map +1 -0
- package/dest/public/side_effect_trace.js +236 -0
- package/dest/public/side_effect_trace_interface.d.ts +36 -0
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -0
- package/dest/public/side_effect_trace_interface.js +2 -0
- package/dest/public/teardown_phase_manager.d.ts.map +1 -1
- package/dest/public/teardown_phase_manager.js +2 -1
- package/dest/rollup/rollup.d.ts +1 -1
- package/dest/rollup/rollup.d.ts.map +1 -1
- package/dest/rollup/rollup.js +2 -2
- package/package.json +18 -9
- package/src/acvm/oracle/oracle.ts +23 -5
- package/src/acvm/oracle/typed_oracle.ts +23 -4
- package/src/avm/avm_context.ts +2 -2
- package/src/avm/{avm_message_call_result.ts → avm_contract_call_result.ts} +1 -1
- package/src/avm/avm_execution_environment.ts +16 -26
- package/src/avm/avm_gas.ts +1 -1
- package/src/avm/avm_simulator.ts +10 -13
- package/src/avm/bytecode_utils.ts +32 -0
- package/src/avm/errors.ts +1 -1
- package/src/avm/fixtures/index.ts +21 -23
- package/src/avm/journal/journal.ts +118 -224
- package/src/avm/journal/nullifiers.ts +30 -13
- package/src/avm/journal/public_storage.ts +12 -2
- package/src/avm/opcodes/accrued_substate.ts +12 -21
- package/src/avm/opcodes/environment_getters.ts +23 -14
- package/src/avm/opcodes/external_calls.ts +13 -36
- package/src/avm/serialization/bytecode_serialization.ts +4 -3
- package/src/avm/serialization/instruction_serialization.ts +3 -3
- package/src/avm/test_utils.ts +53 -0
- package/src/client/client_execution_context.ts +22 -7
- package/src/client/execution_note_cache.ts +0 -1
- package/src/client/execution_result.ts +2 -1
- package/src/client/index.ts +2 -0
- package/src/client/simulator.ts +8 -2
- package/src/client/view_data_oracle.ts +20 -3
- package/src/mocks/fixtures.ts +7 -6
- package/src/public/abstract_phase_manager.ts +32 -21
- package/src/public/app_logic_phase_manager.ts +1 -0
- package/src/public/execution.ts +45 -31
- package/src/public/executor.ts +71 -49
- package/src/public/index.ts +1 -1
- package/src/public/public_kernel.ts +2 -1
- package/src/public/public_processor.ts +11 -2
- package/src/public/side_effect_trace.ts +341 -0
- package/src/public/side_effect_trace_interface.ts +41 -0
- package/src/public/teardown_phase_manager.ts +1 -0
- package/src/rollup/rollup.ts +3 -1
- package/dest/avm/avm_message_call_result.d.ts.map +0 -1
- package/dest/avm/avm_message_call_result.js +0 -18
- package/dest/avm/journal/trace.d.ts +0 -33
- package/dest/avm/journal/trace.d.ts.map +0 -1
- package/dest/avm/journal/trace.js +0 -152
- package/dest/avm/journal/trace_types.d.ts +0 -55
- package/dest/avm/journal/trace_types.d.ts.map +0 -1
- package/dest/avm/journal/trace_types.js +0 -2
- package/dest/public/transitional_adaptors.d.ts +0 -21
- package/dest/public/transitional_adaptors.d.ts.map +0 -1
- package/dest/public/transitional_adaptors.js +0 -90
- package/src/avm/journal/trace.ts +0 -181
- package/src/avm/journal/trace_types.ts +0 -91
- package/src/public/transitional_adaptors.ts +0 -168
|
@@ -1,139 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
AztecAddress,
|
|
5
|
-
ContractStorageRead,
|
|
6
|
-
ContractStorageUpdateRequest,
|
|
7
|
-
EthAddress,
|
|
8
|
-
L2ToL1Message,
|
|
9
|
-
LogHash,
|
|
10
|
-
NoteHash,
|
|
11
|
-
Nullifier,
|
|
12
|
-
ReadRequest,
|
|
13
|
-
} from '@aztec/circuits.js';
|
|
14
|
-
import { EventSelector } from '@aztec/foundation/abi';
|
|
15
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import { AztecAddress, type FunctionSelector, type Gas } from '@aztec/circuits.js';
|
|
2
|
+
import { type Fr } from '@aztec/foundation/fields';
|
|
16
3
|
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
17
4
|
import { SerializableContractInstance } from '@aztec/types/contracts';
|
|
18
5
|
|
|
19
|
-
import { type
|
|
6
|
+
import { type TracedContractInstance } from '../../public/side_effect_trace.js';
|
|
7
|
+
import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js';
|
|
8
|
+
import { type AvmContractCallResult } from '../avm_contract_call_result.js';
|
|
9
|
+
import { type AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
20
10
|
import { type HostStorage } from './host_storage.js';
|
|
21
|
-
import {
|
|
11
|
+
import { NullifierManager } from './nullifiers.js';
|
|
22
12
|
import { PublicStorage } from './public_storage.js';
|
|
23
|
-
import { WorldStateAccessTrace } from './trace.js';
|
|
24
|
-
import {
|
|
25
|
-
type TracedContractInstance,
|
|
26
|
-
type TracedL1toL2MessageCheck,
|
|
27
|
-
type TracedNoteHash,
|
|
28
|
-
type TracedNoteHashCheck,
|
|
29
|
-
type TracedNullifier,
|
|
30
|
-
type TracedNullifierCheck,
|
|
31
|
-
type TracedPublicStorageRead,
|
|
32
|
-
type TracedPublicStorageWrite,
|
|
33
|
-
type TracedUnencryptedL2Log,
|
|
34
|
-
} from './trace_types.js';
|
|
35
|
-
|
|
36
|
-
// TODO:(5818): do we need this type anymore?
|
|
37
|
-
/**
|
|
38
|
-
* Data held within the journal
|
|
39
|
-
*/
|
|
40
|
-
export type JournalData = {
|
|
41
|
-
storageWrites: TracedPublicStorageWrite[];
|
|
42
|
-
storageReads: TracedPublicStorageRead[];
|
|
43
|
-
|
|
44
|
-
noteHashChecks: TracedNoteHashCheck[];
|
|
45
|
-
newNoteHashes: TracedNoteHash[];
|
|
46
|
-
nullifierChecks: TracedNullifierCheck[];
|
|
47
|
-
newNullifiers: TracedNullifier[];
|
|
48
|
-
l1ToL2MessageChecks: TracedL1toL2MessageCheck[];
|
|
49
|
-
|
|
50
|
-
newL1Messages: L2ToL1Message[];
|
|
51
|
-
newLogs: UnencryptedL2Log[];
|
|
52
|
-
newLogsHashes: TracedUnencryptedL2Log[];
|
|
53
|
-
/** contract address -\> key -\> value */
|
|
54
|
-
currentStorageValue: Map<bigint, Map<bigint, Fr>>;
|
|
55
|
-
|
|
56
|
-
sideEffectCounter: number;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
60
|
-
export type PartialPublicExecutionResult = {
|
|
61
|
-
noteHashReadRequests: ReadRequest[];
|
|
62
|
-
nullifierReadRequests: ReadRequest[];
|
|
63
|
-
nullifierNonExistentReadRequests: ReadRequest[];
|
|
64
|
-
l1ToL2MsgReadRequests: ReadRequest[];
|
|
65
|
-
newNoteHashes: NoteHash[];
|
|
66
|
-
newL2ToL1Messages: L2ToL1Message[];
|
|
67
|
-
startSideEffectCounter: number;
|
|
68
|
-
newNullifiers: Nullifier[];
|
|
69
|
-
contractStorageReads: ContractStorageRead[];
|
|
70
|
-
contractStorageUpdateRequests: ContractStorageUpdateRequest[];
|
|
71
|
-
unencryptedLogsHashes: LogHash[];
|
|
72
|
-
unencryptedLogs: UnencryptedL2Log[];
|
|
73
|
-
allUnencryptedLogs: UnencryptedL2Log[];
|
|
74
|
-
nestedExecutions: PublicExecutionResult[];
|
|
75
|
-
};
|
|
76
13
|
|
|
77
14
|
/**
|
|
78
15
|
* A class to manage persistable AVM state for contract calls.
|
|
79
16
|
* Maintains a cache of the current world state,
|
|
80
|
-
* a trace of all
|
|
17
|
+
* a trace of all side effects.
|
|
81
18
|
*
|
|
82
|
-
* The simulator should make any world state
|
|
19
|
+
* The simulator should make any world state / tree queries through this object.
|
|
83
20
|
*
|
|
84
21
|
* Manages merging of successful/reverted child state into current state.
|
|
85
22
|
*/
|
|
86
23
|
export class AvmPersistableStateManager {
|
|
87
24
|
private readonly log: DebugLogger = createDebugLogger('aztec:avm_simulator:state_manager');
|
|
88
|
-
/** Reference to node storage */
|
|
89
|
-
public readonly hostStorage: HostStorage;
|
|
90
|
-
|
|
91
|
-
// TODO(5818): make members private once this is not used in transitional_adaptors.ts.
|
|
92
|
-
/** World State */
|
|
93
|
-
/** Public storage, including cached writes */
|
|
94
|
-
public publicStorage: PublicStorage;
|
|
95
|
-
/** Nullifier set, including cached/recently-emitted nullifiers */
|
|
96
|
-
public nullifiers: Nullifiers;
|
|
97
25
|
|
|
98
|
-
|
|
99
|
-
|
|
26
|
+
constructor(
|
|
27
|
+
/** Reference to node storage */
|
|
28
|
+
private readonly hostStorage: HostStorage,
|
|
29
|
+
/** Side effect trace */
|
|
30
|
+
private readonly trace: PublicSideEffectTraceInterface,
|
|
31
|
+
/** Public storage, including cached writes */
|
|
32
|
+
// TODO(5818): make private once no longer accessed in executor
|
|
33
|
+
public readonly publicStorage: PublicStorage,
|
|
34
|
+
/** Nullifier set, including cached/recently-emitted nullifiers */
|
|
35
|
+
private readonly nullifiers: NullifierManager,
|
|
36
|
+
) {}
|
|
100
37
|
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
newNoteHashes: [],
|
|
120
|
-
newL2ToL1Messages: [],
|
|
121
|
-
startSideEffectCounter: this.trace.accessCounter,
|
|
122
|
-
newNullifiers: [],
|
|
123
|
-
contractStorageReads: [],
|
|
124
|
-
contractStorageUpdateRequests: [],
|
|
125
|
-
unencryptedLogsHashes: [],
|
|
126
|
-
unencryptedLogs: [],
|
|
127
|
-
allUnencryptedLogs: [],
|
|
128
|
-
nestedExecutions: [],
|
|
129
|
-
};
|
|
38
|
+
/**
|
|
39
|
+
* Create a new state manager with some preloaded pending siloed nullifiers
|
|
40
|
+
*/
|
|
41
|
+
public static newWithPendingSiloedNullifiers(
|
|
42
|
+
hostStorage: HostStorage,
|
|
43
|
+
trace: PublicSideEffectTraceInterface,
|
|
44
|
+
pendingSiloedNullifiers: Fr[],
|
|
45
|
+
) {
|
|
46
|
+
const parentNullifiers = NullifierManager.newWithPendingSiloedNullifiers(
|
|
47
|
+
hostStorage.commitmentsDb,
|
|
48
|
+
pendingSiloedNullifiers,
|
|
49
|
+
);
|
|
50
|
+
return new AvmPersistableStateManager(
|
|
51
|
+
hostStorage,
|
|
52
|
+
trace,
|
|
53
|
+
/*publicStorage=*/ new PublicStorage(hostStorage.publicStateDb),
|
|
54
|
+
/*nullifiers=*/ parentNullifiers.fork(),
|
|
55
|
+
);
|
|
130
56
|
}
|
|
131
57
|
|
|
132
58
|
/**
|
|
133
59
|
* Create a new state manager forked from this one
|
|
134
60
|
*/
|
|
135
61
|
public fork() {
|
|
136
|
-
return new AvmPersistableStateManager(
|
|
62
|
+
return new AvmPersistableStateManager(
|
|
63
|
+
this.hostStorage,
|
|
64
|
+
this.trace.fork(),
|
|
65
|
+
this.publicStorage.fork(),
|
|
66
|
+
this.nullifiers.fork(),
|
|
67
|
+
);
|
|
137
68
|
}
|
|
138
69
|
|
|
139
70
|
/**
|
|
@@ -147,13 +78,6 @@ export class AvmPersistableStateManager {
|
|
|
147
78
|
this.log.debug(`Storage write (address=${storageAddress}, slot=${slot}): value=${value}`);
|
|
148
79
|
// Cache storage writes for later reference/reads
|
|
149
80
|
this.publicStorage.write(storageAddress, slot, value);
|
|
150
|
-
|
|
151
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
152
|
-
this.transitionalExecutionResult.contractStorageUpdateRequests.push(
|
|
153
|
-
new ContractStorageUpdateRequest(slot, value, this.trace.accessCounter, storageAddress),
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
// Trace all storage writes (even reverted ones)
|
|
157
81
|
this.trace.tracePublicStorageWrite(storageAddress, slot, value);
|
|
158
82
|
}
|
|
159
83
|
|
|
@@ -169,14 +93,22 @@ export class AvmPersistableStateManager {
|
|
|
169
93
|
this.log.debug(
|
|
170
94
|
`Storage read (address=${storageAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`,
|
|
171
95
|
);
|
|
96
|
+
this.trace.tracePublicStorageRead(storageAddress, slot, value, exists, cached);
|
|
97
|
+
return Promise.resolve(value);
|
|
98
|
+
}
|
|
172
99
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Read from public storage, don't trace the read.
|
|
102
|
+
*
|
|
103
|
+
* @param storageAddress - the address of the contract whose storage is being read from
|
|
104
|
+
* @param slot - the slot in the contract's storage being read from
|
|
105
|
+
* @returns the latest value written to slot, or 0 if never written to before
|
|
106
|
+
*/
|
|
107
|
+
public async peekStorage(storageAddress: Fr, slot: Fr): Promise<Fr> {
|
|
108
|
+
const { value, exists, cached } = await this.publicStorage.read(storageAddress, slot);
|
|
109
|
+
this.log.debug(
|
|
110
|
+
`Storage peek (address=${storageAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`,
|
|
176
111
|
);
|
|
177
|
-
|
|
178
|
-
// We want to keep track of all performed reads (even reverted ones)
|
|
179
|
-
this.trace.tracePublicStorageRead(storageAddress, slot, value, exists, cached);
|
|
180
112
|
return Promise.resolve(value);
|
|
181
113
|
}
|
|
182
114
|
|
|
@@ -193,11 +125,7 @@ export class AvmPersistableStateManager {
|
|
|
193
125
|
const gotLeafIndex = await this.hostStorage.commitmentsDb.getCommitmentIndex(noteHash);
|
|
194
126
|
const exists = gotLeafIndex === leafIndex.toBigInt();
|
|
195
127
|
this.log.debug(`noteHashes(${storageAddress})@${noteHash} ?? leafIndex: ${leafIndex}, exists: ${exists}.`);
|
|
196
|
-
|
|
197
|
-
// TODO: include exists here also - This can for sure come from the trace???
|
|
198
|
-
this.transitionalExecutionResult.noteHashReadRequests.push(new ReadRequest(noteHash, this.trace.accessCounter));
|
|
199
|
-
|
|
200
|
-
this.trace.traceNoteHashCheck(storageAddress, noteHash, exists, leafIndex);
|
|
128
|
+
this.trace.traceNoteHashCheck(storageAddress, noteHash, leafIndex, exists);
|
|
201
129
|
return Promise.resolve(exists);
|
|
202
130
|
}
|
|
203
131
|
|
|
@@ -206,9 +134,6 @@ export class AvmPersistableStateManager {
|
|
|
206
134
|
* @param noteHash - the unsiloed note hash to write
|
|
207
135
|
*/
|
|
208
136
|
public writeNoteHash(storageAddress: Fr, noteHash: Fr) {
|
|
209
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
210
|
-
this.transitionalExecutionResult.newNoteHashes.push(new NoteHash(noteHash, this.trace.accessCounter));
|
|
211
|
-
|
|
212
137
|
this.log.debug(`noteHashes(${storageAddress}) += @${noteHash}.`);
|
|
213
138
|
this.trace.traceNewNoteHash(storageAddress, noteHash);
|
|
214
139
|
}
|
|
@@ -222,19 +147,9 @@ export class AvmPersistableStateManager {
|
|
|
222
147
|
public async checkNullifierExists(storageAddress: Fr, nullifier: Fr): Promise<boolean> {
|
|
223
148
|
const [exists, isPending, leafIndex] = await this.nullifiers.checkExists(storageAddress, nullifier);
|
|
224
149
|
this.log.debug(
|
|
225
|
-
`nullifiers(${storageAddress})@${nullifier} ?? leafIndex: ${leafIndex},
|
|
150
|
+
`nullifiers(${storageAddress})@${nullifier} ?? leafIndex: ${leafIndex}, exists: ${exists}, pending: ${isPending}.`,
|
|
226
151
|
);
|
|
227
|
-
|
|
228
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
229
|
-
if (exists) {
|
|
230
|
-
this.transitionalExecutionResult.nullifierReadRequests.push(new ReadRequest(nullifier, this.trace.accessCounter));
|
|
231
|
-
} else {
|
|
232
|
-
this.transitionalExecutionResult.nullifierNonExistentReadRequests.push(
|
|
233
|
-
new ReadRequest(nullifier, this.trace.accessCounter),
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
this.trace.traceNullifierCheck(storageAddress, nullifier, exists, isPending, leafIndex);
|
|
152
|
+
this.trace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending);
|
|
238
153
|
return Promise.resolve(exists);
|
|
239
154
|
}
|
|
240
155
|
|
|
@@ -244,11 +159,6 @@ export class AvmPersistableStateManager {
|
|
|
244
159
|
* @param nullifier - the unsiloed nullifier to write
|
|
245
160
|
*/
|
|
246
161
|
public async writeNullifier(storageAddress: Fr, nullifier: Fr) {
|
|
247
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
248
|
-
this.transitionalExecutionResult.newNullifiers.push(
|
|
249
|
-
new Nullifier(nullifier, this.trace.accessCounter, /*noteHash=*/ Fr.ZERO),
|
|
250
|
-
);
|
|
251
|
-
|
|
252
162
|
this.log.debug(`nullifiers(${storageAddress}) += ${nullifier}.`);
|
|
253
163
|
// Cache pending nullifiers for later access
|
|
254
164
|
await this.nullifiers.append(storageAddress, nullifier);
|
|
@@ -262,16 +172,13 @@ export class AvmPersistableStateManager {
|
|
|
262
172
|
* @param msgLeafIndex - the message leaf index to use in the check
|
|
263
173
|
* @returns exists - whether the message exists in the L1 to L2 Messages tree
|
|
264
174
|
*/
|
|
265
|
-
public async checkL1ToL2MessageExists(msgHash: Fr, msgLeafIndex: Fr): Promise<boolean> {
|
|
175
|
+
public async checkL1ToL2MessageExists(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr): Promise<boolean> {
|
|
266
176
|
const valueAtIndex = await this.hostStorage.commitmentsDb.getL1ToL2LeafValue(msgLeafIndex.toBigInt());
|
|
267
177
|
const exists = valueAtIndex?.equals(msgHash) ?? false;
|
|
268
178
|
this.log.debug(
|
|
269
179
|
`l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`,
|
|
270
180
|
);
|
|
271
|
-
|
|
272
|
-
this.transitionalExecutionResult.l1ToL2MsgReadRequests.push(new ReadRequest(msgHash, this.trace.accessCounter));
|
|
273
|
-
|
|
274
|
-
this.trace.traceL1ToL2MessageCheck(msgHash, msgLeafIndex, exists);
|
|
181
|
+
this.trace.traceL1ToL2MessageCheck(contractAddress, msgHash, msgLeafIndex, exists);
|
|
275
182
|
return Promise.resolve(exists);
|
|
276
183
|
}
|
|
277
184
|
|
|
@@ -280,40 +187,27 @@ export class AvmPersistableStateManager {
|
|
|
280
187
|
* @param recipient - L1 contract address to send the message to.
|
|
281
188
|
* @param content - Message content.
|
|
282
189
|
*/
|
|
283
|
-
public
|
|
190
|
+
public writeL2ToL1Message(recipient: Fr, content: Fr) {
|
|
284
191
|
this.log.debug(`L1Messages(${recipient}) += ${content}.`);
|
|
285
|
-
|
|
286
|
-
const message = new L2ToL1Message(recipientAddress, content, 0);
|
|
287
|
-
this.newL1Messages.push(message);
|
|
288
|
-
|
|
289
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
290
|
-
this.transitionalExecutionResult.newL2ToL1Messages.push(message);
|
|
192
|
+
this.trace.traceNewL2ToL1Message(recipient, content);
|
|
291
193
|
}
|
|
292
194
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
303
|
-
this.transitionalExecutionResult.unencryptedLogs.push(ulog);
|
|
304
|
-
this.transitionalExecutionResult.allUnencryptedLogs.push(ulog);
|
|
305
|
-
// this duplicates exactly what happens in the trace just for the purpose of transitional integration with the kernel
|
|
306
|
-
this.transitionalExecutionResult.unencryptedLogsHashes.push(
|
|
307
|
-
// TODO(6578): explain magic number 4 here
|
|
308
|
-
new LogHash(logHash, this.trace.accessCounter, new Fr(ulog.length + 4)),
|
|
309
|
-
);
|
|
310
|
-
// TODO(6206): likely need to track this here and not just in the transitional logic.
|
|
311
|
-
|
|
312
|
-
// TODO(6205): why are logs pushed here but logs hashes are traced?
|
|
313
|
-
this.newLogs.push(ulog);
|
|
314
|
-
this.trace.traceNewLog(logHash);
|
|
195
|
+
/**
|
|
196
|
+
* Write an unencrypted log
|
|
197
|
+
* @param contractAddress - address of the contract that emitted the log
|
|
198
|
+
* @param event - log event selector
|
|
199
|
+
* @param log - log contents
|
|
200
|
+
*/
|
|
201
|
+
public writeUnencryptedLog(contractAddress: Fr, log: Fr[]) {
|
|
202
|
+
this.log.debug(`UnencryptedL2Log(${contractAddress}) += event with ${log.length} fields.`);
|
|
203
|
+
this.trace.traceUnencryptedLog(contractAddress, log);
|
|
315
204
|
}
|
|
316
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Get a contract instance.
|
|
208
|
+
* @param contractAddress - address of the contract instance to retrieve.
|
|
209
|
+
* @returns the contract instance with an "exists" flag
|
|
210
|
+
*/
|
|
317
211
|
public async getContractInstance(contractAddress: Fr): Promise<TracedContractInstance> {
|
|
318
212
|
let exists = true;
|
|
319
213
|
const aztecAddress = AztecAddress.fromField(contractAddress);
|
|
@@ -322,59 +216,59 @@ export class AvmPersistableStateManager {
|
|
|
322
216
|
instance = SerializableContractInstance.empty().withAddress(aztecAddress);
|
|
323
217
|
exists = false;
|
|
324
218
|
}
|
|
219
|
+
this.log.debug(
|
|
220
|
+
`Get Contract instance (address=${contractAddress}): exists=${exists}, instance=${JSON.stringify(instance)}`,
|
|
221
|
+
);
|
|
325
222
|
const tracedInstance = { ...instance, exists };
|
|
326
223
|
this.trace.traceGetContractInstance(tracedInstance);
|
|
327
224
|
return Promise.resolve(tracedInstance);
|
|
328
225
|
}
|
|
329
226
|
|
|
330
227
|
/**
|
|
331
|
-
* Accept nested world state modifications
|
|
228
|
+
* Accept nested world state modifications
|
|
332
229
|
*/
|
|
333
|
-
public acceptNestedCallState(
|
|
334
|
-
|
|
335
|
-
this.
|
|
336
|
-
|
|
337
|
-
// Merge World State Access Trace
|
|
338
|
-
this.trace.acceptAndMerge(nestedJournal.trace);
|
|
339
|
-
|
|
340
|
-
// Accrued Substate
|
|
341
|
-
this.newL1Messages.push(...nestedJournal.newL1Messages);
|
|
342
|
-
this.newLogs.push(...nestedJournal.newLogs);
|
|
343
|
-
|
|
344
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
345
|
-
this.transitionalExecutionResult.allUnencryptedLogs.push(
|
|
346
|
-
...nestedJournal.transitionalExecutionResult.allUnencryptedLogs,
|
|
347
|
-
);
|
|
230
|
+
public acceptNestedCallState(nestedState: AvmPersistableStateManager) {
|
|
231
|
+
this.publicStorage.acceptAndMerge(nestedState.publicStorage);
|
|
232
|
+
this.nullifiers.acceptAndMerge(nestedState.nullifiers);
|
|
348
233
|
}
|
|
349
234
|
|
|
350
235
|
/**
|
|
351
|
-
*
|
|
236
|
+
* Get a contract's bytecode from the contracts DB
|
|
352
237
|
*/
|
|
353
|
-
public
|
|
354
|
-
|
|
355
|
-
this.trace.acceptAndMerge(nestedJournal.trace);
|
|
238
|
+
public async getBytecode(contractAddress: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
|
|
239
|
+
return await this.hostStorage.contractsDb.getBytecode(contractAddress, selector);
|
|
356
240
|
}
|
|
357
241
|
|
|
358
|
-
// TODO:(5818): do we need this type anymore?
|
|
359
242
|
/**
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
* @returns a JournalData object
|
|
243
|
+
* Accept the nested call's state and trace the nested call
|
|
363
244
|
*/
|
|
364
|
-
public
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
245
|
+
public async processNestedCall(
|
|
246
|
+
nestedState: AvmPersistableStateManager,
|
|
247
|
+
nestedEnvironment: AvmExecutionEnvironment,
|
|
248
|
+
startGasLeft: Gas,
|
|
249
|
+
endGasLeft: Gas,
|
|
250
|
+
bytecode: Buffer,
|
|
251
|
+
avmCallResults: AvmContractCallResult,
|
|
252
|
+
) {
|
|
253
|
+
if (!avmCallResults.reverted) {
|
|
254
|
+
this.acceptNestedCallState(nestedState);
|
|
255
|
+
}
|
|
256
|
+
const functionName =
|
|
257
|
+
(await nestedState.hostStorage.contractsDb.getDebugFunctionName(
|
|
258
|
+
nestedEnvironment.address,
|
|
259
|
+
nestedEnvironment.functionSelector,
|
|
260
|
+
)) ?? `${nestedEnvironment.address}:${nestedEnvironment.functionSelector}`;
|
|
261
|
+
|
|
262
|
+
this.log.verbose(`[AVM] Calling nested function ${functionName}`);
|
|
263
|
+
|
|
264
|
+
this.trace.traceNestedCall(
|
|
265
|
+
nestedState.trace,
|
|
266
|
+
nestedEnvironment,
|
|
267
|
+
startGasLeft,
|
|
268
|
+
endGasLeft,
|
|
269
|
+
bytecode,
|
|
270
|
+
avmCallResults,
|
|
271
|
+
functionName,
|
|
272
|
+
);
|
|
379
273
|
}
|
|
380
274
|
}
|
|
@@ -9,17 +9,29 @@ import type { CommitmentsDB } from '../../index.js';
|
|
|
9
9
|
* Maintains a nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
10
10
|
* When a contract call completes, its cached nullifier set can be merged into its parent's.
|
|
11
11
|
*/
|
|
12
|
-
export class
|
|
13
|
-
/** Cached nullifiers. */
|
|
14
|
-
public cache: NullifierCache;
|
|
15
|
-
|
|
12
|
+
export class NullifierManager {
|
|
16
13
|
constructor(
|
|
17
14
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
18
15
|
private readonly hostNullifiers: CommitmentsDB,
|
|
19
|
-
/**
|
|
20
|
-
private readonly
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
/** Cached nullifiers. */
|
|
17
|
+
private readonly cache: NullifierCache = new NullifierCache(),
|
|
18
|
+
/** Parent nullifier manager to fall back on */
|
|
19
|
+
private readonly parent?: NullifierManager,
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Create a new nullifiers manager with some preloaded pending siloed nullifiers
|
|
24
|
+
*/
|
|
25
|
+
public static newWithPendingSiloedNullifiers(hostNullifiers: CommitmentsDB, pendingSiloedNullifiers: Fr[]) {
|
|
26
|
+
const cache = new NullifierCache(pendingSiloedNullifiers);
|
|
27
|
+
return new NullifierManager(hostNullifiers, cache);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a new nullifiers manager forked from this one
|
|
32
|
+
*/
|
|
33
|
+
public fork() {
|
|
34
|
+
return new NullifierManager(this.hostNullifiers, new NullifierCache(), this);
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
/**
|
|
@@ -92,7 +104,7 @@ export class Nullifiers {
|
|
|
92
104
|
*
|
|
93
105
|
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
94
106
|
*/
|
|
95
|
-
public acceptAndMerge(incomingNullifiers:
|
|
107
|
+
public acceptAndMerge(incomingNullifiers: NullifierManager) {
|
|
96
108
|
this.cache.acceptAndMerge(incomingNullifiers.cache);
|
|
97
109
|
}
|
|
98
110
|
}
|
|
@@ -111,6 +123,15 @@ export class NullifierCache {
|
|
|
111
123
|
private cachePerContract: Map<bigint, Set<bigint>> = new Map();
|
|
112
124
|
private siloedNullifiers: Set<bigint> = new Set();
|
|
113
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @parem siloedNullifierFrs: optional list of pending siloed nullifiers to initialize this cache with
|
|
128
|
+
*/
|
|
129
|
+
constructor(siloedNullifierFrs?: Fr[]) {
|
|
130
|
+
if (siloedNullifierFrs !== undefined) {
|
|
131
|
+
siloedNullifierFrs.forEach(nullifier => this.siloedNullifiers.add(nullifier.toBigInt()));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
114
135
|
/**
|
|
115
136
|
* Check whether a nullifier exists in the cache.
|
|
116
137
|
*
|
|
@@ -147,10 +168,6 @@ export class NullifierCache {
|
|
|
147
168
|
nullifiersForContract.add(nullifier.toBigInt());
|
|
148
169
|
}
|
|
149
170
|
|
|
150
|
-
public appendSiloed(siloedNullifier: Fr) {
|
|
151
|
-
this.siloedNullifiers.add(siloedNullifier.toBigInt());
|
|
152
|
-
}
|
|
153
|
-
|
|
154
171
|
/**
|
|
155
172
|
* Merge another cache's nullifiers into this instance's.
|
|
156
173
|
*
|
|
@@ -16,7 +16,7 @@ type PublicStorageReadResult = {
|
|
|
16
16
|
*/
|
|
17
17
|
export class PublicStorage {
|
|
18
18
|
/** Cached storage writes. */
|
|
19
|
-
private cache: PublicStorageCache;
|
|
19
|
+
private readonly cache: PublicStorageCache;
|
|
20
20
|
|
|
21
21
|
constructor(
|
|
22
22
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
@@ -27,6 +27,13 @@ export class PublicStorage {
|
|
|
27
27
|
this.cache = new PublicStorageCache();
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Create a new public storage manager forked from this one
|
|
32
|
+
*/
|
|
33
|
+
public fork() {
|
|
34
|
+
return new PublicStorage(this.hostPublicStorage, this);
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
/**
|
|
31
38
|
* Get the pending storage.
|
|
32
39
|
*/
|
|
@@ -71,6 +78,9 @@ export class PublicStorage {
|
|
|
71
78
|
// Finally try the host's Aztec state (a trip to the database)
|
|
72
79
|
if (!value) {
|
|
73
80
|
value = await this.hostPublicStorage.storageRead(storageAddress, slot);
|
|
81
|
+
// TODO(dbanks12): if value retrieved from host storage, we can cache it here
|
|
82
|
+
// any future reads to the same slot can read from cache instead of more expensive
|
|
83
|
+
// DB access
|
|
74
84
|
} else {
|
|
75
85
|
cached = true;
|
|
76
86
|
}
|
|
@@ -124,7 +134,7 @@ class PublicStorageCache {
|
|
|
124
134
|
* mapping storage slot to latest staged write value.
|
|
125
135
|
*/
|
|
126
136
|
public cachePerContract: Map<bigint, Map<bigint, Fr>> = new Map();
|
|
127
|
-
// FIXME: storage ^ should be private, but its value is used in
|
|
137
|
+
// FIXME: storage ^ should be private, but its value is used in commitToDB
|
|
128
138
|
|
|
129
139
|
/**
|
|
130
140
|
* Read a staged value from storage, if it has been previously written to.
|
|
@@ -201,7 +201,11 @@ export class L1ToL2MessageExists extends Instruction {
|
|
|
201
201
|
|
|
202
202
|
const msgHash = memory.get(msgHashOffset).toFr();
|
|
203
203
|
const msgLeafIndex = memory.get(msgLeafIndexOffset).toFr();
|
|
204
|
-
const exists = await context.persistableState.checkL1ToL2MessageExists(
|
|
204
|
+
const exists = await context.persistableState.checkL1ToL2MessageExists(
|
|
205
|
+
context.environment.address,
|
|
206
|
+
msgHash,
|
|
207
|
+
msgLeafIndex,
|
|
208
|
+
);
|
|
205
209
|
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
206
210
|
|
|
207
211
|
memory.assert(memoryOperations);
|
|
@@ -213,20 +217,9 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
213
217
|
static type: string = 'EMITUNENCRYPTEDLOG';
|
|
214
218
|
static readonly opcode: Opcode = Opcode.EMITUNENCRYPTEDLOG;
|
|
215
219
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
216
|
-
static readonly wireFormat = [
|
|
217
|
-
OperandType.UINT8,
|
|
218
|
-
OperandType.UINT8,
|
|
219
|
-
OperandType.UINT32,
|
|
220
|
-
OperandType.UINT32,
|
|
221
|
-
OperandType.UINT32,
|
|
222
|
-
];
|
|
220
|
+
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32];
|
|
223
221
|
|
|
224
|
-
constructor(
|
|
225
|
-
private indirect: number,
|
|
226
|
-
private eventSelectorOffset: number,
|
|
227
|
-
private logOffset: number,
|
|
228
|
-
private logSizeOffset: number,
|
|
229
|
-
) {
|
|
222
|
+
constructor(private indirect: number, private logOffset: number, private logSizeOffset: number) {
|
|
230
223
|
super();
|
|
231
224
|
}
|
|
232
225
|
|
|
@@ -237,22 +230,20 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
237
230
|
|
|
238
231
|
const memory = context.machineState.memory.track(this.type);
|
|
239
232
|
|
|
240
|
-
const [
|
|
241
|
-
[this.
|
|
233
|
+
const [logOffset, logSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
234
|
+
[this.logOffset, this.logSizeOffset],
|
|
242
235
|
memory,
|
|
243
236
|
);
|
|
244
|
-
memory.checkTag(TypeTag.FIELD, eventSelectorOffset);
|
|
245
237
|
memory.checkTag(TypeTag.UINT32, logSizeOffset);
|
|
246
238
|
const logSize = memory.get(logSizeOffset).toNumber();
|
|
247
239
|
memory.checkTagsRange(TypeTag.FIELD, logOffset, logSize);
|
|
248
240
|
|
|
249
241
|
const contractAddress = context.environment.address;
|
|
250
|
-
const event = memory.get(eventSelectorOffset).toFr();
|
|
251
242
|
|
|
252
|
-
const memoryOperations = { reads:
|
|
243
|
+
const memoryOperations = { reads: 1 + logSize, indirect: this.indirect };
|
|
253
244
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
254
245
|
const log = memory.getSlice(logOffset, logSize).map(f => f.toFr());
|
|
255
|
-
context.persistableState.
|
|
246
|
+
context.persistableState.writeUnencryptedLog(contractAddress, log);
|
|
256
247
|
|
|
257
248
|
memory.assert(memoryOperations);
|
|
258
249
|
context.machineState.incrementPc();
|
|
@@ -285,7 +276,7 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
285
276
|
|
|
286
277
|
const recipient = memory.get(recipientOffset).toFr();
|
|
287
278
|
const content = memory.get(contentOffset).toFr();
|
|
288
|
-
context.persistableState.
|
|
279
|
+
context.persistableState.writeL2ToL1Message(recipient, content);
|
|
289
280
|
|
|
290
281
|
memory.assert(memoryOperations);
|
|
291
282
|
context.machineState.incrementPc();
|