@aztec/simulator 0.42.0 → 0.44.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 +5 -2
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +25 -8
- package/dest/acvm/oracle/typed_oracle.d.ts +7 -4
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +14 -5
- package/dest/avm/avm_execution_environment.d.ts +2 -0
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +9 -4
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +3 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +2 -4
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +2 -3
- package/dest/avm/fixtures/index.d.ts +10 -3
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +9 -11
- package/dest/avm/journal/journal.d.ts +57 -66
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +97 -131
- 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 +4 -0
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +10 -1
- package/dest/avm/opcodes/accrued_substate.d.ts +2 -2
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +39 -24
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +12 -9
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +11 -8
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +7 -5
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +20 -24
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +4 -2
- package/dest/avm/opcodes/ec_add.d.ts +19 -0
- package/dest/avm/opcodes/ec_add.d.ts.map +1 -0
- package/dest/avm/opcodes/ec_add.js +78 -0
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +19 -29
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +10 -2
- package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction_impl.js +4 -2
- package/dest/avm/opcodes/memory.d.ts +1 -1
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +14 -12
- package/dest/avm/opcodes/multi_scalar_mul.d.ts +16 -0
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -0
- package/dest/avm/opcodes/multi_scalar_mul.js +95 -0
- package/dest/avm/opcodes/storage.d.ts +1 -1
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +11 -8
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +5 -1
- package/dest/avm/serialization/instruction_serialization.d.ts +3 -1
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +4 -2
- 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 +17 -5
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +32 -18
- 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 +4 -3
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +17 -9
- package/dest/client/view_data_oracle.d.ts +2 -0
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +7 -1
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +3 -2
- package/dest/public/abstract_phase_manager.d.ts +11 -11
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +84 -59
- package/dest/public/app_logic_phase_manager.d.ts +3 -3
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
- package/dest/public/app_logic_phase_manager.js +4 -3
- package/dest/public/db_interfaces.d.ts +1 -0
- package/dest/public/db_interfaces.d.ts.map +1 -1
- package/dest/public/execution.d.ts +28 -40
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -51
- package/dest/public/executor.d.ts +9 -4
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +38 -27
- package/dest/public/hints_builder.d.ts +1 -1
- package/dest/public/index.d.ts +6 -6
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +7 -7
- package/dest/public/phase_manager_factory.d.ts +3 -3
- package/dest/public/phase_manager_factory.d.ts.map +1 -1
- package/dest/public/phase_manager_factory.js +5 -5
- package/dest/public/public_db_sources.d.ts +3 -1
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +54 -8
- 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 +143 -125
- package/dest/public/setup_phase_manager.d.ts +3 -3
- package/dest/public/setup_phase_manager.d.ts.map +1 -1
- package/dest/public/setup_phase_manager.js +3 -3
- package/dest/public/side_effect_trace.d.ts +86 -0
- package/dest/public/side_effect_trace.d.ts.map +1 -0
- package/dest/public/side_effect_trace.js +222 -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/tail_phase_manager.d.ts +3 -3
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +3 -3
- package/dest/public/teardown_phase_manager.d.ts +3 -3
- package/dest/public/teardown_phase_manager.d.ts.map +1 -1
- package/dest/public/teardown_phase_manager.js +4 -3
- package/dest/public/transitional_adaptors.d.ts +2 -6
- package/dest/public/transitional_adaptors.d.ts.map +1 -1
- package/dest/public/transitional_adaptors.js +1 -43
- package/package.json +18 -9
- package/src/acvm/oracle/oracle.ts +46 -9
- package/src/acvm/oracle/typed_oracle.ts +37 -7
- package/src/avm/avm_execution_environment.ts +10 -3
- package/src/avm/avm_gas.ts +2 -0
- package/src/avm/avm_memory_types.ts +1 -3
- package/src/avm/avm_simulator.ts +2 -3
- package/src/avm/fixtures/index.ts +19 -14
- package/src/avm/journal/journal.ts +127 -231
- package/src/avm/journal/nullifiers.ts +30 -13
- package/src/avm/journal/public_storage.ts +10 -0
- package/src/avm/opcodes/accrued_substate.ts +60 -23
- package/src/avm/opcodes/arithmetic.ts +17 -8
- package/src/avm/opcodes/bitwise.ts +13 -8
- package/src/avm/opcodes/comparators.ts +9 -4
- package/src/avm/opcodes/contract.ts +22 -26
- package/src/avm/opcodes/control_flow.ts +3 -1
- package/src/avm/opcodes/ec_add.ts +92 -0
- package/src/avm/opcodes/external_calls.ts +20 -36
- package/src/avm/opcodes/hashing.ts +11 -1
- package/src/avm/opcodes/instruction_impl.ts +4 -1
- package/src/avm/opcodes/memory.ts +18 -11
- package/src/avm/opcodes/multi_scalar_mul.ts +114 -0
- package/src/avm/opcodes/storage.ts +10 -10
- package/src/avm/serialization/bytecode_serialization.ts +4 -0
- package/src/avm/serialization/instruction_serialization.ts +2 -0
- package/src/avm/test_utils.ts +53 -0
- package/src/client/client_execution_context.ts +55 -21
- 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 +26 -10
- package/src/client/view_data_oracle.ts +8 -0
- package/src/mocks/fixtures.ts +2 -1
- package/src/public/abstract_phase_manager.ts +99 -70
- package/src/public/app_logic_phase_manager.ts +3 -2
- package/src/public/db_interfaces.ts +2 -0
- package/src/public/execution.ts +35 -94
- package/src/public/executor.ts +56 -40
- package/src/public/index.ts +6 -12
- package/src/public/phase_manager_factory.ts +6 -6
- package/src/public/public_db_sources.ts +62 -7
- package/src/public/public_processor.ts +15 -9
- package/src/public/setup_phase_manager.ts +2 -2
- package/src/public/side_effect_trace.ts +323 -0
- package/src/public/side_effect_trace_interface.ts +41 -0
- package/src/public/tail_phase_manager.ts +2 -2
- package/src/public/teardown_phase_manager.ts +3 -2
- package/src/public/transitional_adaptors.ts +2 -60
- 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 -151
- package/dest/avm/journal/trace_types.d.ts +0 -51
- package/dest/avm/journal/trace_types.d.ts.map +0 -1
- package/dest/avm/journal/trace_types.js +0 -6
- package/dest/public/utils.d.ts +0 -8
- package/dest/public/utils.d.ts.map +0 -1
- package/dest/public/utils.js +0 -38
- package/src/avm/journal/trace.ts +0 -184
- package/src/avm/journal/trace_types.ts +0 -88
- package/src/public/utils.ts +0 -39
|
@@ -1,137 +1,69 @@
|
|
|
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';
|
|
4
|
+
import { SerializableContractInstance } from '@aztec/types/contracts';
|
|
17
5
|
|
|
18
|
-
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 AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
9
|
+
import { type AvmContractCallResults } from '../avm_message_call_result.js';
|
|
19
10
|
import { type HostStorage } from './host_storage.js';
|
|
20
|
-
import {
|
|
11
|
+
import { NullifierManager } from './nullifiers.js';
|
|
21
12
|
import { PublicStorage } from './public_storage.js';
|
|
22
|
-
import { WorldStateAccessTrace } from './trace.js';
|
|
23
|
-
import {
|
|
24
|
-
type TracedL1toL2MessageCheck,
|
|
25
|
-
type TracedNoteHash,
|
|
26
|
-
type TracedNoteHashCheck,
|
|
27
|
-
type TracedNullifier,
|
|
28
|
-
type TracedNullifierCheck,
|
|
29
|
-
type TracedPublicStorageRead,
|
|
30
|
-
type TracedPublicStorageWrite,
|
|
31
|
-
type TracedUnencryptedL2Log,
|
|
32
|
-
} from './trace_types.js';
|
|
33
|
-
|
|
34
|
-
// TODO:(5818): do we need this type anymore?
|
|
35
|
-
/**
|
|
36
|
-
* Data held within the journal
|
|
37
|
-
*/
|
|
38
|
-
export type JournalData = {
|
|
39
|
-
storageWrites: TracedPublicStorageWrite[];
|
|
40
|
-
storageReads: TracedPublicStorageRead[];
|
|
41
|
-
|
|
42
|
-
noteHashChecks: TracedNoteHashCheck[];
|
|
43
|
-
newNoteHashes: TracedNoteHash[];
|
|
44
|
-
nullifierChecks: TracedNullifierCheck[];
|
|
45
|
-
newNullifiers: TracedNullifier[];
|
|
46
|
-
l1ToL2MessageChecks: TracedL1toL2MessageCheck[];
|
|
47
|
-
|
|
48
|
-
newL1Messages: L2ToL1Message[];
|
|
49
|
-
newLogs: UnencryptedL2Log[];
|
|
50
|
-
newLogsHashes: TracedUnencryptedL2Log[];
|
|
51
|
-
/** contract address -\> key -\> value */
|
|
52
|
-
currentStorageValue: Map<bigint, Map<bigint, Fr>>;
|
|
53
|
-
|
|
54
|
-
sideEffectCounter: number;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
58
|
-
type PartialPublicExecutionResult = {
|
|
59
|
-
noteHashReadRequests: ReadRequest[];
|
|
60
|
-
nullifierReadRequests: ReadRequest[];
|
|
61
|
-
nullifierNonExistentReadRequests: ReadRequest[];
|
|
62
|
-
l1ToL2MsgReadRequests: ReadRequest[];
|
|
63
|
-
newNoteHashes: NoteHash[];
|
|
64
|
-
newL2ToL1Messages: L2ToL1Message[];
|
|
65
|
-
startSideEffectCounter: number;
|
|
66
|
-
newNullifiers: Nullifier[];
|
|
67
|
-
contractStorageReads: ContractStorageRead[];
|
|
68
|
-
contractStorageUpdateRequests: ContractStorageUpdateRequest[];
|
|
69
|
-
unencryptedLogsHashes: LogHash[];
|
|
70
|
-
unencryptedLogs: UnencryptedL2Log[];
|
|
71
|
-
allUnencryptedLogs: UnencryptedL2Log[];
|
|
72
|
-
nestedExecutions: PublicExecutionResult[];
|
|
73
|
-
};
|
|
74
13
|
|
|
75
14
|
/**
|
|
76
15
|
* A class to manage persistable AVM state for contract calls.
|
|
77
16
|
* Maintains a cache of the current world state,
|
|
78
|
-
* a trace of all
|
|
17
|
+
* a trace of all side effects.
|
|
79
18
|
*
|
|
80
|
-
* The simulator should make any world state
|
|
19
|
+
* The simulator should make any world state / tree queries through this object.
|
|
81
20
|
*
|
|
82
21
|
* Manages merging of successful/reverted child state into current state.
|
|
83
22
|
*/
|
|
84
23
|
export class AvmPersistableStateManager {
|
|
85
24
|
private readonly log: DebugLogger = createDebugLogger('aztec:avm_simulator:state_manager');
|
|
86
|
-
/** Reference to node storage */
|
|
87
|
-
public readonly hostStorage: HostStorage;
|
|
88
|
-
|
|
89
|
-
// TODO(5818): make members private once this is not used in transitional_adaptors.ts.
|
|
90
|
-
/** World State */
|
|
91
|
-
/** Public storage, including cached writes */
|
|
92
|
-
public publicStorage: PublicStorage;
|
|
93
|
-
/** Nullifier set, including cached/recently-emitted nullifiers */
|
|
94
|
-
public nullifiers: Nullifiers;
|
|
95
25
|
|
|
96
|
-
|
|
97
|
-
|
|
26
|
+
constructor(
|
|
27
|
+
/** Reference to node storage */
|
|
28
|
+
private hostStorage: HostStorage,
|
|
29
|
+
/** Side effect trace */
|
|
30
|
+
private trace: PublicSideEffectTraceInterface,
|
|
31
|
+
/** Public storage, including cached writes */
|
|
32
|
+
public readonly publicStorage: PublicStorage,
|
|
33
|
+
/** Nullifier set, including cached/recently-emitted nullifiers */
|
|
34
|
+
private readonly nullifiers: NullifierManager,
|
|
35
|
+
) {}
|
|
98
36
|
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
newNoteHashes: [],
|
|
118
|
-
newL2ToL1Messages: [],
|
|
119
|
-
startSideEffectCounter: this.trace.accessCounter,
|
|
120
|
-
newNullifiers: [],
|
|
121
|
-
contractStorageReads: [],
|
|
122
|
-
contractStorageUpdateRequests: [],
|
|
123
|
-
unencryptedLogsHashes: [],
|
|
124
|
-
unencryptedLogs: [],
|
|
125
|
-
allUnencryptedLogs: [],
|
|
126
|
-
nestedExecutions: [],
|
|
127
|
-
};
|
|
37
|
+
/**
|
|
38
|
+
* Create a new state manager with some preloaded pending siloed nullifiers
|
|
39
|
+
*/
|
|
40
|
+
public static newWithPendingSiloedNullifiers(
|
|
41
|
+
hostStorage: HostStorage,
|
|
42
|
+
trace: PublicSideEffectTraceInterface,
|
|
43
|
+
pendingSiloedNullifiers: Fr[],
|
|
44
|
+
) {
|
|
45
|
+
const parentNullifiers = NullifierManager.newWithPendingSiloedNullifiers(
|
|
46
|
+
hostStorage.commitmentsDb,
|
|
47
|
+
pendingSiloedNullifiers,
|
|
48
|
+
);
|
|
49
|
+
return new AvmPersistableStateManager(
|
|
50
|
+
hostStorage,
|
|
51
|
+
trace,
|
|
52
|
+
/*publicStorage=*/ new PublicStorage(hostStorage.publicStateDb),
|
|
53
|
+
/*nullifiers=*/ parentNullifiers.fork(),
|
|
54
|
+
);
|
|
128
55
|
}
|
|
129
56
|
|
|
130
57
|
/**
|
|
131
58
|
* Create a new state manager forked from this one
|
|
132
59
|
*/
|
|
133
60
|
public fork() {
|
|
134
|
-
return new AvmPersistableStateManager(
|
|
61
|
+
return new AvmPersistableStateManager(
|
|
62
|
+
this.hostStorage,
|
|
63
|
+
this.trace.fork(),
|
|
64
|
+
this.publicStorage.fork(),
|
|
65
|
+
this.nullifiers.fork(),
|
|
66
|
+
);
|
|
135
67
|
}
|
|
136
68
|
|
|
137
69
|
/**
|
|
@@ -145,22 +77,6 @@ export class AvmPersistableStateManager {
|
|
|
145
77
|
this.log.debug(`Storage write (address=${storageAddress}, slot=${slot}): value=${value}`);
|
|
146
78
|
// Cache storage writes for later reference/reads
|
|
147
79
|
this.publicStorage.write(storageAddress, slot, value);
|
|
148
|
-
|
|
149
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
150
|
-
// The current info to the kernel clears any previous read or write request.
|
|
151
|
-
this.transitionalExecutionResult.contractStorageReads =
|
|
152
|
-
this.transitionalExecutionResult.contractStorageReads.filter(
|
|
153
|
-
read => !read.storageSlot.equals(slot) || !read.contractAddress!.equals(storageAddress),
|
|
154
|
-
);
|
|
155
|
-
this.transitionalExecutionResult.contractStorageUpdateRequests =
|
|
156
|
-
this.transitionalExecutionResult.contractStorageUpdateRequests.filter(
|
|
157
|
-
update => !update.storageSlot.equals(slot) || !update.contractAddress!.equals(storageAddress),
|
|
158
|
-
);
|
|
159
|
-
this.transitionalExecutionResult.contractStorageUpdateRequests.push(
|
|
160
|
-
new ContractStorageUpdateRequest(slot, value, this.trace.accessCounter, storageAddress),
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// Trace all storage writes (even reverted ones)
|
|
164
80
|
this.trace.tracePublicStorageWrite(storageAddress, slot, value);
|
|
165
81
|
}
|
|
166
82
|
|
|
@@ -176,25 +92,25 @@ export class AvmPersistableStateManager {
|
|
|
176
92
|
this.log.debug(
|
|
177
93
|
`Storage read (address=${storageAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`,
|
|
178
94
|
);
|
|
179
|
-
|
|
180
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
181
|
-
// The current info to the kernel kernel does not consider cached reads.
|
|
182
|
-
if (!cached) {
|
|
183
|
-
// The current info to the kernel removes any previous reads to the same slot.
|
|
184
|
-
this.transitionalExecutionResult.contractStorageReads =
|
|
185
|
-
this.transitionalExecutionResult.contractStorageReads.filter(
|
|
186
|
-
read => !read.storageSlot.equals(slot) || !read.contractAddress!.equals(storageAddress),
|
|
187
|
-
);
|
|
188
|
-
this.transitionalExecutionResult.contractStorageReads.push(
|
|
189
|
-
new ContractStorageRead(slot, value, this.trace.accessCounter, storageAddress),
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// We want to keep track of all performed reads (even reverted ones)
|
|
194
95
|
this.trace.tracePublicStorageRead(storageAddress, slot, value, exists, cached);
|
|
195
96
|
return Promise.resolve(value);
|
|
196
97
|
}
|
|
197
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Read from public storage, don't trace the read.
|
|
101
|
+
*
|
|
102
|
+
* @param storageAddress - the address of the contract whose storage is being read from
|
|
103
|
+
* @param slot - the slot in the contract's storage being read from
|
|
104
|
+
* @returns the latest value written to slot, or 0 if never written to before
|
|
105
|
+
*/
|
|
106
|
+
public async peekStorage(storageAddress: Fr, slot: Fr): Promise<Fr> {
|
|
107
|
+
const { value, exists, cached } = await this.publicStorage.read(storageAddress, slot);
|
|
108
|
+
this.log.debug(
|
|
109
|
+
`Storage peek (address=${storageAddress}, slot=${slot}): value=${value}, exists=${exists}, cached=${cached}`,
|
|
110
|
+
);
|
|
111
|
+
return Promise.resolve(value);
|
|
112
|
+
}
|
|
113
|
+
|
|
198
114
|
// TODO(4886): We currently don't silo note hashes.
|
|
199
115
|
/**
|
|
200
116
|
* Check if a note hash exists at the given leaf index, trace the check.
|
|
@@ -208,7 +124,7 @@ export class AvmPersistableStateManager {
|
|
|
208
124
|
const gotLeafIndex = await this.hostStorage.commitmentsDb.getCommitmentIndex(noteHash);
|
|
209
125
|
const exists = gotLeafIndex === leafIndex.toBigInt();
|
|
210
126
|
this.log.debug(`noteHashes(${storageAddress})@${noteHash} ?? leafIndex: ${leafIndex}, exists: ${exists}.`);
|
|
211
|
-
this.trace.traceNoteHashCheck(storageAddress, noteHash,
|
|
127
|
+
this.trace.traceNoteHashCheck(storageAddress, noteHash, leafIndex, exists);
|
|
212
128
|
return Promise.resolve(exists);
|
|
213
129
|
}
|
|
214
130
|
|
|
@@ -217,9 +133,6 @@ export class AvmPersistableStateManager {
|
|
|
217
133
|
* @param noteHash - the unsiloed note hash to write
|
|
218
134
|
*/
|
|
219
135
|
public writeNoteHash(storageAddress: Fr, noteHash: Fr) {
|
|
220
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
221
|
-
this.transitionalExecutionResult.newNoteHashes.push(new NoteHash(noteHash, this.trace.accessCounter));
|
|
222
|
-
|
|
223
136
|
this.log.debug(`noteHashes(${storageAddress}) += @${noteHash}.`);
|
|
224
137
|
this.trace.traceNewNoteHash(storageAddress, noteHash);
|
|
225
138
|
}
|
|
@@ -233,19 +146,9 @@ export class AvmPersistableStateManager {
|
|
|
233
146
|
public async checkNullifierExists(storageAddress: Fr, nullifier: Fr): Promise<boolean> {
|
|
234
147
|
const [exists, isPending, leafIndex] = await this.nullifiers.checkExists(storageAddress, nullifier);
|
|
235
148
|
this.log.debug(
|
|
236
|
-
`nullifiers(${storageAddress})@${nullifier} ?? leafIndex: ${leafIndex},
|
|
149
|
+
`nullifiers(${storageAddress})@${nullifier} ?? leafIndex: ${leafIndex}, exists: ${exists}, pending: ${isPending}.`,
|
|
237
150
|
);
|
|
238
|
-
|
|
239
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
240
|
-
if (exists) {
|
|
241
|
-
this.transitionalExecutionResult.nullifierReadRequests.push(new ReadRequest(nullifier, this.trace.accessCounter));
|
|
242
|
-
} else {
|
|
243
|
-
this.transitionalExecutionResult.nullifierNonExistentReadRequests.push(
|
|
244
|
-
new ReadRequest(nullifier, this.trace.accessCounter),
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
this.trace.traceNullifierCheck(storageAddress, nullifier, exists, isPending, leafIndex);
|
|
151
|
+
this.trace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending);
|
|
249
152
|
return Promise.resolve(exists);
|
|
250
153
|
}
|
|
251
154
|
|
|
@@ -255,11 +158,6 @@ export class AvmPersistableStateManager {
|
|
|
255
158
|
* @param nullifier - the unsiloed nullifier to write
|
|
256
159
|
*/
|
|
257
160
|
public async writeNullifier(storageAddress: Fr, nullifier: Fr) {
|
|
258
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
259
|
-
this.transitionalExecutionResult.newNullifiers.push(
|
|
260
|
-
new Nullifier(nullifier, this.trace.accessCounter, /*noteHash=*/ Fr.ZERO),
|
|
261
|
-
);
|
|
262
|
-
|
|
263
161
|
this.log.debug(`nullifiers(${storageAddress}) += ${nullifier}.`);
|
|
264
162
|
// Cache pending nullifiers for later access
|
|
265
163
|
await this.nullifiers.append(storageAddress, nullifier);
|
|
@@ -273,13 +171,13 @@ export class AvmPersistableStateManager {
|
|
|
273
171
|
* @param msgLeafIndex - the message leaf index to use in the check
|
|
274
172
|
* @returns exists - whether the message exists in the L1 to L2 Messages tree
|
|
275
173
|
*/
|
|
276
|
-
public async checkL1ToL2MessageExists(msgHash: Fr, msgLeafIndex: Fr): Promise<boolean> {
|
|
174
|
+
public async checkL1ToL2MessageExists(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr): Promise<boolean> {
|
|
277
175
|
const valueAtIndex = await this.hostStorage.commitmentsDb.getL1ToL2LeafValue(msgLeafIndex.toBigInt());
|
|
278
176
|
const exists = valueAtIndex?.equals(msgHash) ?? false;
|
|
279
177
|
this.log.debug(
|
|
280
178
|
`l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`,
|
|
281
179
|
);
|
|
282
|
-
this.trace.traceL1ToL2MessageCheck(msgHash, msgLeafIndex, exists);
|
|
180
|
+
this.trace.traceL1ToL2MessageCheck(contractAddress, msgHash, msgLeafIndex, exists);
|
|
283
181
|
return Promise.resolve(exists);
|
|
284
182
|
}
|
|
285
183
|
|
|
@@ -288,88 +186,86 @@ export class AvmPersistableStateManager {
|
|
|
288
186
|
* @param recipient - L1 contract address to send the message to.
|
|
289
187
|
* @param content - Message content.
|
|
290
188
|
*/
|
|
291
|
-
public
|
|
189
|
+
public writeL2ToL1Message(recipient: Fr, content: Fr) {
|
|
292
190
|
this.log.debug(`L1Messages(${recipient}) += ${content}.`);
|
|
293
|
-
|
|
294
|
-
const message = new L2ToL1Message(recipientAddress, content, 0);
|
|
295
|
-
this.newL1Messages.push(message);
|
|
296
|
-
|
|
297
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
298
|
-
this.transitionalExecutionResult.newL2ToL1Messages.push(message);
|
|
191
|
+
this.trace.traceNewL2ToL1Message(recipient, content);
|
|
299
192
|
}
|
|
300
193
|
|
|
301
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Write an unencrypted log
|
|
196
|
+
* @param contractAddress - address of the contract that emitted the log
|
|
197
|
+
* @param event - log event selector
|
|
198
|
+
* @param log - log contents
|
|
199
|
+
*/
|
|
200
|
+
public writeUnencryptedLog(contractAddress: Fr, event: Fr, log: Fr[]) {
|
|
302
201
|
this.log.debug(`UnencryptedL2Log(${contractAddress}) += event ${event} with ${log.length} fields.`);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
EventSelector.fromField(event),
|
|
306
|
-
Buffer.concat(log.map(f => f.toBuffer())),
|
|
307
|
-
);
|
|
308
|
-
const logHash = Fr.fromBuffer(ulog.hash());
|
|
202
|
+
this.trace.traceUnencryptedLog(contractAddress, event, log);
|
|
203
|
+
}
|
|
309
204
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Get a contract instance.
|
|
207
|
+
* @param contractAddress - address of the contract instance to retrieve.
|
|
208
|
+
* @returns the contract instance with an "exists" flag
|
|
209
|
+
*/
|
|
210
|
+
public async getContractInstance(contractAddress: Fr): Promise<TracedContractInstance> {
|
|
211
|
+
let exists = true;
|
|
212
|
+
const aztecAddress = AztecAddress.fromField(contractAddress);
|
|
213
|
+
let instance = await this.hostStorage.contractsDb.getContractInstance(aztecAddress);
|
|
214
|
+
if (instance === undefined) {
|
|
215
|
+
instance = SerializableContractInstance.empty().withAddress(aztecAddress);
|
|
216
|
+
exists = false;
|
|
217
|
+
}
|
|
218
|
+
this.log.debug(
|
|
219
|
+
`Get Contract instance (address=${contractAddress}): exists=${exists}, instance=${JSON.stringify(instance)}`,
|
|
317
220
|
);
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
this.newLogs.push(ulog);
|
|
322
|
-
this.trace.traceNewLog(logHash);
|
|
221
|
+
const tracedInstance = { ...instance, exists };
|
|
222
|
+
this.trace.traceGetContractInstance(tracedInstance);
|
|
223
|
+
return Promise.resolve(tracedInstance);
|
|
323
224
|
}
|
|
324
225
|
|
|
325
226
|
/**
|
|
326
|
-
* Accept nested world state modifications
|
|
227
|
+
* Accept nested world state modifications
|
|
327
228
|
*/
|
|
328
|
-
public acceptNestedCallState(
|
|
329
|
-
|
|
330
|
-
this.
|
|
331
|
-
|
|
332
|
-
// Merge World State Access Trace
|
|
333
|
-
this.trace.acceptAndMerge(nestedJournal.trace);
|
|
334
|
-
|
|
335
|
-
// Accrued Substate
|
|
336
|
-
this.newL1Messages.push(...nestedJournal.newL1Messages);
|
|
337
|
-
this.newLogs.push(...nestedJournal.newLogs);
|
|
338
|
-
|
|
339
|
-
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
340
|
-
this.transitionalExecutionResult.allUnencryptedLogs.push(
|
|
341
|
-
...nestedJournal.transitionalExecutionResult.allUnencryptedLogs,
|
|
342
|
-
);
|
|
229
|
+
public acceptNestedCallState(nestedState: AvmPersistableStateManager) {
|
|
230
|
+
this.publicStorage.acceptAndMerge(nestedState.publicStorage);
|
|
231
|
+
this.nullifiers.acceptAndMerge(nestedState.nullifiers);
|
|
343
232
|
}
|
|
344
233
|
|
|
345
234
|
/**
|
|
346
|
-
*
|
|
235
|
+
* Get a contract's bytecode from the contracts DB
|
|
347
236
|
*/
|
|
348
|
-
public
|
|
349
|
-
|
|
350
|
-
this.trace.acceptAndMerge(nestedJournal.trace);
|
|
237
|
+
public async getBytecode(contractAddress: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
|
|
238
|
+
return await this.hostStorage.contractsDb.getBytecode(contractAddress, selector);
|
|
351
239
|
}
|
|
352
240
|
|
|
353
|
-
// TODO:(5818): do we need this type anymore?
|
|
354
241
|
/**
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
* @returns a JournalData object
|
|
242
|
+
* Accept the nested call's state and trace the nested call
|
|
358
243
|
*/
|
|
359
|
-
public
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
244
|
+
public async processNestedCall(
|
|
245
|
+
nestedState: AvmPersistableStateManager,
|
|
246
|
+
success: boolean,
|
|
247
|
+
nestedEnvironment: AvmExecutionEnvironment,
|
|
248
|
+
startGasLeft: Gas,
|
|
249
|
+
endGasLeft: Gas,
|
|
250
|
+
bytecode: Buffer,
|
|
251
|
+
avmCallResults: AvmContractCallResults,
|
|
252
|
+
) {
|
|
253
|
+
if (success) {
|
|
254
|
+
this.acceptNestedCallState(nestedState);
|
|
255
|
+
}
|
|
256
|
+
const functionName =
|
|
257
|
+
(await nestedState.hostStorage.contractsDb.getDebugFunctionName(
|
|
258
|
+
nestedEnvironment.address,
|
|
259
|
+
nestedEnvironment.temporaryFunctionSelector,
|
|
260
|
+
)) ?? `${nestedEnvironment.address}:${nestedEnvironment.temporaryFunctionSelector}`;
|
|
261
|
+
this.trace.traceNestedCall(
|
|
262
|
+
nestedState.trace,
|
|
263
|
+
nestedEnvironment,
|
|
264
|
+
startGasLeft,
|
|
265
|
+
endGasLeft,
|
|
266
|
+
bytecode,
|
|
267
|
+
avmCallResults,
|
|
268
|
+
functionName,
|
|
269
|
+
);
|
|
374
270
|
}
|
|
375
271
|
}
|
|
@@ -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
|
*
|
|
@@ -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
|
}
|