@aztec/simulator 0.33.0 → 0.35.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/acvm.d.ts +4 -1
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +5 -5
- package/dest/acvm/deserialize.d.ts +3 -5
- package/dest/acvm/deserialize.d.ts.map +1 -1
- package/dest/acvm/deserialize.js +6 -9
- 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 +14 -6
- package/dest/acvm/oracle/typed_oracle.d.ts +2 -0
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +7 -1
- package/dest/avm/avm_execution_environment.d.ts +6 -3
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +12 -9
- package/dest/avm/avm_gas.js +2 -2
- package/dest/avm/avm_machine_state.d.ts +2 -0
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +24 -6
- package/dest/avm/avm_memory_types.js +6 -6
- package/dest/avm/avm_simulator.js +7 -7
- package/dest/avm/fixtures/index.d.ts +3 -0
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +11 -4
- package/dest/avm/journal/journal.d.ts +15 -13
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +16 -5
- package/dest/avm/journal/trace.d.ts +8 -19
- package/dest/avm/journal/trace.d.ts.map +1 -1
- package/dest/avm/journal/trace.js +48 -116
- package/dest/avm/journal/trace_types.d.ts +23 -4
- package/dest/avm/journal/trace_types.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.d.ts +2 -1
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +14 -6
- package/dest/avm/opcodes/context_getters.js +2 -2
- package/dest/avm/opcodes/external_calls.d.ts +2 -2
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +26 -10
- package/dest/avm/opcodes/hashing.d.ts +8 -8
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +35 -43
- package/dest/avm/serialization/instruction_serialization.d.ts +1 -1
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +2 -2
- package/dest/client/client_execution_context.d.ts +14 -4
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +28 -13
- package/dest/client/private_execution.d.ts +1 -1
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +10 -8
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +6 -5
- package/dest/client/unconstrained_execution.d.ts +1 -1
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +6 -5
- package/dest/client/view_data_oracle.d.ts +2 -2
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +2 -2
- package/dest/common/index.d.ts +1 -1
- package/dest/common/index.d.ts.map +1 -1
- package/dest/common/index.js +2 -2
- package/dest/common/packed_values_cache.d.ts +28 -0
- package/dest/common/packed_values_cache.d.ts.map +1 -0
- package/dest/common/packed_values_cache.js +50 -0
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/mocks/fixtures.d.ts +42 -0
- package/dest/mocks/fixtures.d.ts.map +1 -0
- package/dest/mocks/fixtures.js +84 -0
- package/dest/mocks/index.d.ts +2 -0
- package/dest/mocks/index.d.ts.map +1 -0
- package/dest/mocks/index.js +2 -0
- package/dest/public/abstract_phase_manager.d.ts +82 -0
- package/dest/public/abstract_phase_manager.d.ts.map +1 -0
- package/dest/public/abstract_phase_manager.js +320 -0
- package/dest/public/app_logic_phase_manager.d.ts +29 -0
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -0
- package/dest/public/app_logic_phase_manager.js +50 -0
- package/dest/public/execution.d.ts +3 -0
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -1
- package/dest/public/executor.d.ts +1 -15
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +80 -83
- package/dest/public/hints_builder.d.ts +23 -0
- package/dest/public/hints_builder.d.ts.map +1 -0
- package/dest/public/hints_builder.js +62 -0
- package/dest/public/index.d.ts +5 -0
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +6 -1
- package/dest/public/phase_manager_factory.d.ts +18 -0
- package/dest/public/phase_manager_factory.d.ts.map +1 -0
- package/dest/public/phase_manager_factory.js +56 -0
- package/dest/public/public_execution_context.d.ts +20 -10
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +35 -23
- package/dest/public/public_executor.d.ts +79 -0
- package/dest/public/public_executor.d.ts.map +1 -0
- package/dest/public/public_executor.js +198 -0
- package/dest/public/public_kernel.d.ts +37 -0
- package/dest/public/public_kernel.d.ts.map +1 -0
- package/dest/public/public_kernel.js +97 -0
- package/dest/public/public_kernel_circuit_simulator.d.ts +31 -0
- package/dest/public/public_kernel_circuit_simulator.d.ts.map +1 -0
- package/dest/public/public_kernel_circuit_simulator.js +2 -0
- package/dest/public/public_processor.d.ts +53 -0
- package/dest/public/public_processor.d.ts.map +1 -0
- package/dest/public/public_processor.js +144 -0
- package/dest/public/setup_phase_manager.d.ts +30 -0
- package/dest/public/setup_phase_manager.d.ts.map +1 -0
- package/dest/public/setup_phase_manager.js +46 -0
- package/dest/public/tail_phase_manager.d.ts +30 -0
- package/dest/public/tail_phase_manager.d.ts.map +1 -0
- package/dest/public/tail_phase_manager.js +60 -0
- package/dest/public/teardown_phase_manager.d.ts +30 -0
- package/dest/public/teardown_phase_manager.d.ts.map +1 -0
- package/dest/public/teardown_phase_manager.js +46 -0
- package/dest/public/transitional_adaptors.d.ts +33 -0
- package/dest/public/transitional_adaptors.d.ts.map +1 -0
- package/dest/public/transitional_adaptors.js +162 -0
- package/dest/public/utils.d.ts +8 -0
- package/dest/public/utils.d.ts.map +1 -0
- package/dest/public/utils.js +29 -0
- package/dest/simulator/acvm_native.d.ts +19 -3
- package/dest/simulator/acvm_native.d.ts.map +1 -1
- package/dest/simulator/acvm_native.js +75 -48
- package/dest/simulator/acvm_wasm.d.ts.map +1 -1
- package/dest/simulator/acvm_wasm.js +3 -4
- package/package.json +8 -5
- package/src/acvm/acvm.ts +8 -5
- package/src/acvm/deserialize.ts +5 -9
- package/src/acvm/oracle/oracle.ts +15 -5
- package/src/acvm/oracle/typed_oracle.ts +8 -0
- package/src/avm/avm_execution_environment.ts +17 -17
- package/src/avm/avm_gas.ts +1 -1
- package/src/avm/avm_machine_state.ts +26 -5
- package/src/avm/avm_memory_types.ts +5 -5
- package/src/avm/avm_simulator.ts +6 -6
- package/src/avm/fixtures/index.ts +14 -1
- package/src/avm/journal/journal.ts +37 -17
- package/src/avm/journal/trace.ts +59 -121
- package/src/avm/journal/trace_types.ts +39 -39
- package/src/avm/opcodes/accrued_substate.ts +17 -5
- package/src/avm/opcodes/context_getters.ts +1 -1
- package/src/avm/opcodes/external_calls.ts +32 -9
- package/src/avm/opcodes/hashing.ts +38 -54
- package/src/avm/serialization/instruction_serialization.ts +1 -1
- package/src/client/client_execution_context.ts +30 -11
- package/src/client/private_execution.ts +9 -8
- package/src/client/simulator.ts +7 -3
- package/src/client/unconstrained_execution.ts +5 -4
- package/src/client/view_data_oracle.ts +1 -1
- package/src/common/index.ts +1 -1
- package/src/common/packed_values_cache.ts +55 -0
- package/src/index.ts +1 -0
- package/src/mocks/fixtures.ts +169 -0
- package/src/mocks/index.ts +1 -0
- package/src/public/abstract_phase_manager.ts +571 -0
- package/src/public/app_logic_phase_manager.ts +76 -0
- package/src/public/execution.ts +4 -0
- package/src/public/executor.ts +93 -93
- package/src/public/hints_builder.ts +119 -0
- package/src/public/index.ts +5 -0
- package/src/public/phase_manager_factory.ts +126 -0
- package/src/public/public_execution_context.ts +43 -37
- package/src/public/public_executor.ts +267 -0
- package/src/public/public_kernel.ts +139 -0
- package/src/public/public_kernel_circuit_simulator.ts +36 -0
- package/src/public/public_processor.ts +212 -0
- package/src/public/setup_phase_manager.ts +66 -0
- package/src/public/tail_phase_manager.ts +120 -0
- package/src/public/teardown_phase_manager.ts +66 -0
- package/src/public/transitional_adaptors.ts +249 -0
- package/src/public/utils.ts +31 -0
- package/src/simulator/acvm_native.ts +94 -47
- package/src/simulator/acvm_wasm.ts +7 -3
- package/dest/avm/temporary_executor_migration.d.ts +0 -27
- package/dest/avm/temporary_executor_migration.d.ts.map +0 -1
- package/dest/avm/temporary_executor_migration.js +0 -94
- package/dest/common/packed_args_cache.d.ts +0 -28
- package/dest/common/packed_args_cache.d.ts.map +0 -1
- package/dest/common/packed_args_cache.js +0 -50
- package/src/avm/temporary_executor_migration.ts +0 -136
- package/src/common/packed_args_cache.ts +0 -55
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type NullifierMembershipWitness,
|
|
3
|
-
UnencryptedFunctionL2Logs,
|
|
4
|
-
type UnencryptedL2Log,
|
|
5
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { UnencryptedFunctionL2Logs, type UnencryptedL2Log } from '@aztec/circuit-types';
|
|
6
2
|
import {
|
|
7
3
|
CallContext,
|
|
8
4
|
FunctionData,
|
|
@@ -17,7 +13,7 @@ import { createDebugLogger } from '@aztec/foundation/log';
|
|
|
17
13
|
import { type ContractInstance } from '@aztec/types/contracts';
|
|
18
14
|
|
|
19
15
|
import { TypedOracle, toACVMWitness } from '../acvm/index.js';
|
|
20
|
-
import { type
|
|
16
|
+
import { type PackedValuesCache, type SideEffectCounter } from '../common/index.js';
|
|
21
17
|
import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db.js';
|
|
22
18
|
import { type PublicExecution, type PublicExecutionResult, checkValidStaticCall } from './execution.js';
|
|
23
19
|
import { executePublicFunction } from './executor.js';
|
|
@@ -36,13 +32,13 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
36
32
|
* Data for this execution.
|
|
37
33
|
*/
|
|
38
34
|
public readonly execution: PublicExecution,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
private readonly
|
|
35
|
+
public readonly header: Header,
|
|
36
|
+
public readonly globalVariables: GlobalVariables,
|
|
37
|
+
private readonly packedValuesCache: PackedValuesCache,
|
|
42
38
|
private readonly sideEffectCounter: SideEffectCounter,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
public readonly stateDb: PublicStateDB,
|
|
40
|
+
public readonly contractsDb: PublicContractsDB,
|
|
41
|
+
public readonly commitmentsDb: CommitmentsDB,
|
|
46
42
|
private log = createDebugLogger('aztec:simulator:public_execution_context'),
|
|
47
43
|
) {
|
|
48
44
|
super();
|
|
@@ -98,7 +94,23 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
98
94
|
* @param args - Arguments to pack
|
|
99
95
|
*/
|
|
100
96
|
public packArguments(args: Fr[]): Promise<Fr> {
|
|
101
|
-
return Promise.resolve(this.
|
|
97
|
+
return Promise.resolve(this.packedValuesCache.pack(args));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Pack the given returns.
|
|
102
|
+
* @param returns - Returns to pack
|
|
103
|
+
*/
|
|
104
|
+
public packReturns(returns: Fr[]): Promise<Fr> {
|
|
105
|
+
return Promise.resolve(this.packedValuesCache.pack(returns));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Unpack the given returns.
|
|
110
|
+
* @param returnsHash - Returns hash to unpack
|
|
111
|
+
*/
|
|
112
|
+
public unpackReturns(returnsHash: Fr): Promise<Fr[]> {
|
|
113
|
+
return Promise.resolve(this.packedValuesCache.unpack(returnsHash));
|
|
102
114
|
}
|
|
103
115
|
|
|
104
116
|
/**
|
|
@@ -120,7 +132,7 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
120
132
|
public emitUnencryptedLog(log: UnencryptedL2Log) {
|
|
121
133
|
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/885)
|
|
122
134
|
this.unencryptedLogs.push(log);
|
|
123
|
-
this.log(`Emitted unencrypted log: "${log.toHumanReadable()}"`);
|
|
135
|
+
this.log.verbose(`Emitted unencrypted log: "${log.toHumanReadable()}"`);
|
|
124
136
|
}
|
|
125
137
|
|
|
126
138
|
/**
|
|
@@ -144,7 +156,7 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
144
156
|
const storageSlot = new Fr(startStorageSlot.value + BigInt(i));
|
|
145
157
|
const sideEffectCounter = this.sideEffectCounter.count();
|
|
146
158
|
const value = await this.storageActions.read(storageSlot, sideEffectCounter);
|
|
147
|
-
this.log(`Oracle storage read: slot=${storageSlot.toString()} value=${value.toString()}`);
|
|
159
|
+
this.log.debug(`Oracle storage read: slot=${storageSlot.toString()} value=${value.toString()}`);
|
|
148
160
|
values.push(value);
|
|
149
161
|
}
|
|
150
162
|
return values;
|
|
@@ -163,7 +175,7 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
163
175
|
const sideEffectCounter = this.sideEffectCounter.count();
|
|
164
176
|
this.storageActions.write(storageSlot, newValue, sideEffectCounter);
|
|
165
177
|
await this.stateDb.storageWrite(this.execution.callContext.storageContractAddress, storageSlot, newValue);
|
|
166
|
-
this.log(`Oracle storage write: slot=${storageSlot.toString()} value=${newValue.toString()}`);
|
|
178
|
+
this.log.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${newValue.toString()}`);
|
|
167
179
|
newValues.push(newValue);
|
|
168
180
|
}
|
|
169
181
|
return newValues;
|
|
@@ -186,26 +198,25 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
186
198
|
) {
|
|
187
199
|
isStaticCall = isStaticCall || this.execution.callContext.isStaticCall;
|
|
188
200
|
|
|
189
|
-
const args = this.
|
|
190
|
-
this.log
|
|
201
|
+
const args = this.packedValuesCache.unpack(argsHash);
|
|
202
|
+
this.log.verbose(
|
|
203
|
+
`Public function call: addr=${targetContractAddress} selector=${functionSelector} args=${args.join(',')}`,
|
|
204
|
+
);
|
|
191
205
|
|
|
192
206
|
const portalAddress = (await this.contractsDb.getPortalContractAddress(targetContractAddress)) ?? EthAddress.ZERO;
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
if (!acir) {
|
|
196
|
-
throw new Error(`Bytecode not found for ${targetContractAddress}:${functionSelector}`);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const functionData = new FunctionData(functionSelector, false);
|
|
200
|
-
|
|
207
|
+
const functionData = new FunctionData(functionSelector, /*isPrivate=*/ false);
|
|
208
|
+
const { transactionFee, gasSettings, gasLeft } = this.execution.callContext;
|
|
201
209
|
const callContext = CallContext.from({
|
|
202
210
|
msgSender: isDelegateCall ? this.execution.callContext.msgSender : this.execution.contractAddress,
|
|
203
211
|
storageContractAddress: isDelegateCall ? this.execution.contractAddress : targetContractAddress,
|
|
204
212
|
portalContractAddress: portalAddress,
|
|
205
213
|
functionSelector,
|
|
214
|
+
gasLeft, // Propagate the same gas left as when we started since ACVM public functions don't have any metering
|
|
206
215
|
isDelegateCall,
|
|
207
216
|
isStaticCall,
|
|
208
217
|
sideEffectCounter,
|
|
218
|
+
gasSettings,
|
|
219
|
+
transactionFee,
|
|
209
220
|
});
|
|
210
221
|
|
|
211
222
|
const nestedExecution: PublicExecution = {
|
|
@@ -219,7 +230,7 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
219
230
|
nestedExecution,
|
|
220
231
|
this.header,
|
|
221
232
|
this.globalVariables,
|
|
222
|
-
this.
|
|
233
|
+
this.packedValuesCache,
|
|
223
234
|
this.sideEffectCounter,
|
|
224
235
|
this.stateDb,
|
|
225
236
|
this.contractsDb,
|
|
@@ -227,7 +238,7 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
227
238
|
this.log,
|
|
228
239
|
);
|
|
229
240
|
|
|
230
|
-
const childExecutionResult = await executePublicFunction(context,
|
|
241
|
+
const childExecutionResult = await executePublicFunction(context, /*nested=*/ true);
|
|
231
242
|
|
|
232
243
|
if (isStaticCall) {
|
|
233
244
|
checkValidStaticCall(
|
|
@@ -240,19 +251,14 @@ export class PublicExecutionContext extends TypedOracle {
|
|
|
240
251
|
}
|
|
241
252
|
|
|
242
253
|
this.nestedExecutions.push(childExecutionResult);
|
|
243
|
-
this.log(`Returning from nested call: ret=${childExecutionResult.returnValues.join(', ')}`);
|
|
254
|
+
this.log.debug(`Returning from nested call: ret=${childExecutionResult.returnValues.join(', ')}`);
|
|
244
255
|
|
|
245
256
|
return childExecutionResult.returnValues;
|
|
246
257
|
}
|
|
247
258
|
|
|
248
|
-
public async
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
): Promise<NullifierMembershipWitness | undefined> {
|
|
252
|
-
if (!this.header.globalVariables.blockNumber.equals(new Fr(blockNumber))) {
|
|
253
|
-
throw new Error(`Public execution oracle can only access nullifier membership witnesses for the current block`);
|
|
254
|
-
}
|
|
255
|
-
return await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier);
|
|
259
|
+
public async checkNullifierExists(nullifier: Fr): Promise<boolean> {
|
|
260
|
+
const witness = await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier);
|
|
261
|
+
return !!witness;
|
|
256
262
|
}
|
|
257
263
|
|
|
258
264
|
public async getContractInstance(address: AztecAddress): Promise<ContractInstance> {
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { MerkleTreeId, NullifierMembershipWitness, type Tx } from '@aztec/circuit-types';
|
|
2
|
+
import {
|
|
3
|
+
type AztecAddress,
|
|
4
|
+
ContractClassRegisteredEvent,
|
|
5
|
+
ContractInstanceDeployedEvent,
|
|
6
|
+
type EthAddress,
|
|
7
|
+
Fr,
|
|
8
|
+
type FunctionSelector,
|
|
9
|
+
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
10
|
+
type NULLIFIER_TREE_HEIGHT,
|
|
11
|
+
type NullifierLeafPreimage,
|
|
12
|
+
type PublicDataTreeLeafPreimage,
|
|
13
|
+
} from '@aztec/circuits.js';
|
|
14
|
+
import { computeL1ToL2MessageNullifier, computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
|
|
15
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
16
|
+
import { getCanonicalClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
|
|
17
|
+
import {
|
|
18
|
+
type CommitmentsDB,
|
|
19
|
+
MessageLoadOracleInputs,
|
|
20
|
+
type PublicContractsDB,
|
|
21
|
+
type PublicStateDB,
|
|
22
|
+
} from '@aztec/simulator';
|
|
23
|
+
import {
|
|
24
|
+
type ContractClassPublic,
|
|
25
|
+
type ContractDataSource,
|
|
26
|
+
type ContractInstanceWithAddress,
|
|
27
|
+
} from '@aztec/types/contracts';
|
|
28
|
+
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Implements the PublicContractsDB using a ContractDataSource.
|
|
32
|
+
* Progressively records contracts in transaction as they are processed in a block.
|
|
33
|
+
*/
|
|
34
|
+
export class ContractsDataSourcePublicDB implements PublicContractsDB {
|
|
35
|
+
private instanceCache = new Map<string, ContractInstanceWithAddress>();
|
|
36
|
+
private classCache = new Map<string, ContractClassPublic>();
|
|
37
|
+
|
|
38
|
+
private log = createDebugLogger('aztec:sequencer:contracts-data-source');
|
|
39
|
+
|
|
40
|
+
constructor(private db: ContractDataSource) {}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Add new contracts from a transaction
|
|
44
|
+
* @param tx - The transaction to add contracts from.
|
|
45
|
+
*/
|
|
46
|
+
public addNewContracts(tx: Tx): Promise<void> {
|
|
47
|
+
// Extract contract class and instance data from logs and add to cache for this block
|
|
48
|
+
const logs = tx.unencryptedLogs.unrollLogs();
|
|
49
|
+
ContractClassRegisteredEvent.fromLogs(logs, getCanonicalClassRegistererAddress()).forEach(e => {
|
|
50
|
+
this.log.debug(`Adding class ${e.contractClassId.toString()} to public execution contract cache`);
|
|
51
|
+
this.classCache.set(e.contractClassId.toString(), e.toContractClassPublic());
|
|
52
|
+
});
|
|
53
|
+
ContractInstanceDeployedEvent.fromLogs(logs).forEach(e => {
|
|
54
|
+
this.log.debug(
|
|
55
|
+
`Adding instance ${e.address.toString()} with class ${e.contractClassId.toString()} to public execution contract cache`,
|
|
56
|
+
);
|
|
57
|
+
this.instanceCache.set(e.address.toString(), e.toContractInstance());
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return Promise.resolve();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Removes new contracts added from transactions
|
|
65
|
+
* @param tx - The tx's contracts to be removed
|
|
66
|
+
*/
|
|
67
|
+
public removeNewContracts(tx: Tx): Promise<void> {
|
|
68
|
+
// TODO(@spalladino): Can this inadvertently delete a valid contract added by another tx?
|
|
69
|
+
// Let's say we have two txs adding the same contract on the same block. If the 2nd one reverts,
|
|
70
|
+
// wouldn't that accidentally remove the contract added on the first one?
|
|
71
|
+
const logs = tx.unencryptedLogs.unrollLogs();
|
|
72
|
+
ContractClassRegisteredEvent.fromLogs(logs, getCanonicalClassRegistererAddress()).forEach(e =>
|
|
73
|
+
this.classCache.delete(e.contractClassId.toString()),
|
|
74
|
+
);
|
|
75
|
+
ContractInstanceDeployedEvent.fromLogs(logs).forEach(e => this.instanceCache.delete(e.address.toString()));
|
|
76
|
+
return Promise.resolve();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public async getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
80
|
+
return this.instanceCache.get(address.toString()) ?? (await this.db.getContract(address));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public async getContractClass(contractClassId: Fr): Promise<ContractClassPublic | undefined> {
|
|
84
|
+
return this.classCache.get(contractClassId.toString()) ?? (await this.db.getContractClass(contractClassId));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
|
|
88
|
+
const instance = await this.getContractInstance(address);
|
|
89
|
+
if (!instance) {
|
|
90
|
+
throw new Error(`Contract ${address.toString()} not found`);
|
|
91
|
+
}
|
|
92
|
+
const contractClass = await this.getContractClass(instance.contractClassId);
|
|
93
|
+
if (!contractClass) {
|
|
94
|
+
throw new Error(`Contract class ${instance.contractClassId.toString()} for ${address.toString()} not found`);
|
|
95
|
+
}
|
|
96
|
+
return contractClass.publicFunctions.find(f => f.selector.equals(selector))?.bytecode;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getPortalContractAddress(address: AztecAddress): Promise<EthAddress | undefined> {
|
|
100
|
+
const contract = await this.getContractInstance(address);
|
|
101
|
+
return contract?.portalContractAddress;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Implements the PublicStateDB using a world-state database.
|
|
107
|
+
*/
|
|
108
|
+
export class WorldStatePublicDB implements PublicStateDB {
|
|
109
|
+
private committedWriteCache: Map<bigint, Fr> = new Map();
|
|
110
|
+
private checkpointedWriteCache: Map<bigint, Fr> = new Map();
|
|
111
|
+
private uncommittedWriteCache: Map<bigint, Fr> = new Map();
|
|
112
|
+
|
|
113
|
+
constructor(private db: MerkleTreeOperations) {}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Reads a value from public storage, returning zero if none.
|
|
117
|
+
* @param contract - Owner of the storage.
|
|
118
|
+
* @param slot - Slot to read in the contract storage.
|
|
119
|
+
* @returns The current value in the storage slot.
|
|
120
|
+
*/
|
|
121
|
+
public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
122
|
+
const leafSlot = computePublicDataTreeLeafSlot(contract, slot).value;
|
|
123
|
+
const uncommitted = this.uncommittedWriteCache.get(leafSlot);
|
|
124
|
+
if (uncommitted !== undefined) {
|
|
125
|
+
return uncommitted;
|
|
126
|
+
}
|
|
127
|
+
const checkpointed = this.checkpointedWriteCache.get(leafSlot);
|
|
128
|
+
if (checkpointed !== undefined) {
|
|
129
|
+
return checkpointed;
|
|
130
|
+
}
|
|
131
|
+
const committed = this.committedWriteCache.get(leafSlot);
|
|
132
|
+
if (committed !== undefined) {
|
|
133
|
+
return committed;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
137
|
+
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
138
|
+
return Fr.ZERO;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const preimage = (await this.db.getLeafPreimage(
|
|
142
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
143
|
+
lowLeafResult.index,
|
|
144
|
+
)) as PublicDataTreeLeafPreimage;
|
|
145
|
+
|
|
146
|
+
return preimage.value;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Records a write to public storage.
|
|
151
|
+
* @param contract - Owner of the storage.
|
|
152
|
+
* @param slot - Slot to read in the contract storage.
|
|
153
|
+
* @param newValue - The new value to store.
|
|
154
|
+
*/
|
|
155
|
+
public storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
|
|
156
|
+
const index = computePublicDataTreeLeafSlot(contract, slot).value;
|
|
157
|
+
this.uncommittedWriteCache.set(index, newValue);
|
|
158
|
+
return Promise.resolve();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Commit the pending changes to the DB.
|
|
163
|
+
* @returns Nothing.
|
|
164
|
+
*/
|
|
165
|
+
commit(): Promise<void> {
|
|
166
|
+
for (const [k, v] of this.checkpointedWriteCache) {
|
|
167
|
+
this.committedWriteCache.set(k, v);
|
|
168
|
+
}
|
|
169
|
+
// uncommitted writes take precedence over checkpointed writes
|
|
170
|
+
// since they are the most recent
|
|
171
|
+
for (const [k, v] of this.uncommittedWriteCache) {
|
|
172
|
+
this.committedWriteCache.set(k, v);
|
|
173
|
+
}
|
|
174
|
+
return this.rollbackToCommit();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Rollback the pending changes.
|
|
179
|
+
* @returns Nothing.
|
|
180
|
+
*/
|
|
181
|
+
async rollbackToCommit(): Promise<void> {
|
|
182
|
+
await this.rollbackToCheckpoint();
|
|
183
|
+
this.checkpointedWriteCache = new Map<bigint, Fr>();
|
|
184
|
+
return Promise.resolve();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
checkpoint(): Promise<void> {
|
|
188
|
+
for (const [k, v] of this.uncommittedWriteCache) {
|
|
189
|
+
this.checkpointedWriteCache.set(k, v);
|
|
190
|
+
}
|
|
191
|
+
return this.rollbackToCheckpoint();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
rollbackToCheckpoint(): Promise<void> {
|
|
195
|
+
this.uncommittedWriteCache = new Map<bigint, Fr>();
|
|
196
|
+
return Promise.resolve();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Implements WorldState db using a world state database.
|
|
202
|
+
*/
|
|
203
|
+
export class WorldStateDB implements CommitmentsDB {
|
|
204
|
+
constructor(private db: MerkleTreeOperations) {}
|
|
205
|
+
|
|
206
|
+
public async getNullifierMembershipWitnessAtLatestBlock(
|
|
207
|
+
nullifier: Fr,
|
|
208
|
+
): Promise<NullifierMembershipWitness | undefined> {
|
|
209
|
+
const index = await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
210
|
+
if (!index) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const leafPreimagePromise = this.db.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
|
|
215
|
+
const siblingPathPromise = this.db.getSiblingPath<typeof NULLIFIER_TREE_HEIGHT>(
|
|
216
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
217
|
+
BigInt(index),
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const [leafPreimage, siblingPath] = await Promise.all([leafPreimagePromise, siblingPathPromise]);
|
|
221
|
+
|
|
222
|
+
if (!leafPreimage) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return new NullifierMembershipWitness(BigInt(index), leafPreimage as NullifierLeafPreimage, siblingPath);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
public async getL1ToL2MembershipWitness(
|
|
230
|
+
contractAddress: AztecAddress,
|
|
231
|
+
messageHash: Fr,
|
|
232
|
+
secret: Fr,
|
|
233
|
+
): Promise<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> {
|
|
234
|
+
let nullifierIndex: bigint | undefined;
|
|
235
|
+
let messageIndex: bigint | undefined;
|
|
236
|
+
let startIndex = 0n;
|
|
237
|
+
|
|
238
|
+
// We iterate over messages until we find one whose nullifier is not in the nullifier tree --> we need to check
|
|
239
|
+
// for nullifiers because messages can have duplicates.
|
|
240
|
+
do {
|
|
241
|
+
messageIndex = (await this.db.findLeafIndexAfter(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, messageHash, startIndex))!;
|
|
242
|
+
if (messageIndex === undefined) {
|
|
243
|
+
throw new Error(`No non-nullified L1 to L2 message found for message hash ${messageHash.toString()}`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const messageNullifier = computeL1ToL2MessageNullifier(contractAddress, messageHash, secret, messageIndex);
|
|
247
|
+
nullifierIndex = await this.getNullifierIndex(messageNullifier);
|
|
248
|
+
|
|
249
|
+
startIndex = messageIndex + 1n;
|
|
250
|
+
} while (nullifierIndex !== undefined);
|
|
251
|
+
|
|
252
|
+
const siblingPath = await this.db.getSiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>(
|
|
253
|
+
MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
|
|
254
|
+
messageIndex,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
return new MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>(messageIndex, siblingPath);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public async getCommitmentIndex(commitment: Fr): Promise<bigint | undefined> {
|
|
261
|
+
return await this.db.findLeafIndex(MerkleTreeId.NOTE_HASH_TREE, commitment);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public async getNullifierIndex(nullifier: Fr): Promise<bigint | undefined> {
|
|
265
|
+
return await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { type CircuitSimulationStats } from '@aztec/circuit-types/stats';
|
|
2
|
+
import {
|
|
3
|
+
type KernelCircuitPublicInputs,
|
|
4
|
+
type PublicKernelCircuitPrivateInputs,
|
|
5
|
+
type PublicKernelCircuitPublicInputs,
|
|
6
|
+
type PublicKernelTailCircuitPrivateInputs,
|
|
7
|
+
} from '@aztec/circuits.js';
|
|
8
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
9
|
+
import { elapsed } from '@aztec/foundation/timer';
|
|
10
|
+
import {
|
|
11
|
+
PublicKernelAppLogicArtifact,
|
|
12
|
+
PublicKernelSetupArtifact,
|
|
13
|
+
PublicKernelTailArtifact,
|
|
14
|
+
PublicKernelTeardownArtifact,
|
|
15
|
+
convertPublicInnerRollupInputsToWitnessMap,
|
|
16
|
+
convertPublicInnerRollupOutputFromWitnessMap,
|
|
17
|
+
convertPublicSetupRollupInputsToWitnessMap,
|
|
18
|
+
convertPublicSetupRollupOutputFromWitnessMap,
|
|
19
|
+
convertPublicTailInputsToWitnessMap,
|
|
20
|
+
convertPublicTailOutputFromWitnessMap,
|
|
21
|
+
convertPublicTeardownRollupInputsToWitnessMap,
|
|
22
|
+
convertPublicTeardownRollupOutputFromWitnessMap,
|
|
23
|
+
} from '@aztec/noir-protocol-circuits-types';
|
|
24
|
+
import { type SimulationProvider, WASMSimulator } from '@aztec/simulator';
|
|
25
|
+
|
|
26
|
+
import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Implements the PublicKernelCircuitSimulator.
|
|
30
|
+
*/
|
|
31
|
+
export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimulator {
|
|
32
|
+
private log = createDebugLogger('aztec:public-kernel-simulator');
|
|
33
|
+
|
|
34
|
+
// Some circuits are so small it is faster to use WASM
|
|
35
|
+
private wasmSimulator: WASMSimulator = new WASMSimulator();
|
|
36
|
+
|
|
37
|
+
constructor(private simulator: SimulationProvider) {}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Simulates the public kernel setup circuit from its inputs.
|
|
41
|
+
* @param input - Inputs to the circuit.
|
|
42
|
+
* @returns The public inputs as outputs of the simulation.
|
|
43
|
+
*/
|
|
44
|
+
public async publicKernelCircuitSetup(
|
|
45
|
+
input: PublicKernelCircuitPrivateInputs,
|
|
46
|
+
): Promise<PublicKernelCircuitPublicInputs> {
|
|
47
|
+
if (!input.previousKernel.publicInputs.needsSetup) {
|
|
48
|
+
throw new Error(`Expected previous kernel inputs to need setup`);
|
|
49
|
+
}
|
|
50
|
+
const inputWitness = convertPublicSetupRollupInputsToWitnessMap(input);
|
|
51
|
+
const [duration, witness] = await elapsed(() =>
|
|
52
|
+
this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelSetupArtifact),
|
|
53
|
+
);
|
|
54
|
+
const result = convertPublicSetupRollupOutputFromWitnessMap(witness);
|
|
55
|
+
this.log.debug(`Simulated public kernel setup circuit`, {
|
|
56
|
+
eventName: 'circuit-simulation',
|
|
57
|
+
circuitName: 'public-kernel-setup',
|
|
58
|
+
duration,
|
|
59
|
+
inputSize: input.toBuffer().length,
|
|
60
|
+
outputSize: result.toBuffer().length,
|
|
61
|
+
} satisfies CircuitSimulationStats);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Simulates the public kernel app logic circuit from its inputs.
|
|
67
|
+
* @param input - Inputs to the circuit.
|
|
68
|
+
* @returns The public inputs as outputs of the simulation.
|
|
69
|
+
*/
|
|
70
|
+
public async publicKernelCircuitAppLogic(
|
|
71
|
+
input: PublicKernelCircuitPrivateInputs,
|
|
72
|
+
): Promise<PublicKernelCircuitPublicInputs> {
|
|
73
|
+
if (!input.previousKernel.publicInputs.needsAppLogic) {
|
|
74
|
+
throw new Error(`Expected previous kernel inputs to need app logic`);
|
|
75
|
+
}
|
|
76
|
+
const inputWitness = convertPublicInnerRollupInputsToWitnessMap(input);
|
|
77
|
+
const [duration, witness] = await elapsed(() =>
|
|
78
|
+
this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelAppLogicArtifact),
|
|
79
|
+
);
|
|
80
|
+
const result = convertPublicInnerRollupOutputFromWitnessMap(witness);
|
|
81
|
+
this.log.debug(`Simulated public kernel app logic circuit`, {
|
|
82
|
+
eventName: 'circuit-simulation',
|
|
83
|
+
circuitName: 'public-kernel-app-logic',
|
|
84
|
+
duration,
|
|
85
|
+
inputSize: input.toBuffer().length,
|
|
86
|
+
outputSize: result.toBuffer().length,
|
|
87
|
+
} satisfies CircuitSimulationStats);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Simulates the public kernel teardown circuit from its inputs.
|
|
93
|
+
* @param input - Inputs to the circuit.
|
|
94
|
+
* @returns The public inputs as outputs of the simulation.
|
|
95
|
+
*/
|
|
96
|
+
public async publicKernelCircuitTeardown(
|
|
97
|
+
input: PublicKernelCircuitPrivateInputs,
|
|
98
|
+
): Promise<PublicKernelCircuitPublicInputs> {
|
|
99
|
+
if (!input.previousKernel.publicInputs.needsTeardown) {
|
|
100
|
+
throw new Error(`Expected previous kernel inputs to need teardown`);
|
|
101
|
+
}
|
|
102
|
+
const inputWitness = convertPublicTeardownRollupInputsToWitnessMap(input);
|
|
103
|
+
const [duration, witness] = await elapsed(() =>
|
|
104
|
+
this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelTeardownArtifact),
|
|
105
|
+
);
|
|
106
|
+
const result = convertPublicTeardownRollupOutputFromWitnessMap(witness);
|
|
107
|
+
this.log.debug(`Simulated public kernel teardown circuit`, {
|
|
108
|
+
eventName: 'circuit-simulation',
|
|
109
|
+
circuitName: 'public-kernel-teardown',
|
|
110
|
+
duration,
|
|
111
|
+
inputSize: input.toBuffer().length,
|
|
112
|
+
outputSize: result.toBuffer().length,
|
|
113
|
+
} satisfies CircuitSimulationStats);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Simulates the public kernel tail circuit from its inputs.
|
|
119
|
+
* @param input - Inputs to the circuit.
|
|
120
|
+
* @returns The public inputs as outputs of the simulation.
|
|
121
|
+
*/
|
|
122
|
+
public async publicKernelCircuitTail(
|
|
123
|
+
input: PublicKernelTailCircuitPrivateInputs,
|
|
124
|
+
): Promise<KernelCircuitPublicInputs> {
|
|
125
|
+
const inputWitness = convertPublicTailInputsToWitnessMap(input);
|
|
126
|
+
const [duration, witness] = await elapsed(() =>
|
|
127
|
+
this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelTailArtifact),
|
|
128
|
+
);
|
|
129
|
+
const result = convertPublicTailOutputFromWitnessMap(witness);
|
|
130
|
+
this.log.debug(`Simulated public kernel tail circuit`, {
|
|
131
|
+
eventName: 'circuit-simulation',
|
|
132
|
+
circuitName: 'public-kernel-tail',
|
|
133
|
+
duration,
|
|
134
|
+
inputSize: input.toBuffer().length,
|
|
135
|
+
outputSize: result.toBuffer().length,
|
|
136
|
+
} satisfies CircuitSimulationStats);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type KernelCircuitPublicInputs,
|
|
3
|
+
type PublicKernelCircuitPrivateInputs,
|
|
4
|
+
type PublicKernelCircuitPublicInputs,
|
|
5
|
+
type PublicKernelTailCircuitPrivateInputs,
|
|
6
|
+
} from '@aztec/circuits.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Circuit simulator for the public kernel circuits.
|
|
10
|
+
*/
|
|
11
|
+
export interface PublicKernelCircuitSimulator {
|
|
12
|
+
/**
|
|
13
|
+
* Simulates the public kernel setup circuit from its inputs.
|
|
14
|
+
* @param inputs - Inputs to the circuit.
|
|
15
|
+
* @returns The public inputs as outputs of the simulation.
|
|
16
|
+
*/
|
|
17
|
+
publicKernelCircuitSetup(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
|
|
18
|
+
/**
|
|
19
|
+
* Simulates the public kernel app logic circuit from its inputs.
|
|
20
|
+
* @param inputs - Inputs to the circuit.
|
|
21
|
+
* @returns The public inputs as outputs of the simulation.
|
|
22
|
+
*/
|
|
23
|
+
publicKernelCircuitAppLogic(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
|
|
24
|
+
/**
|
|
25
|
+
* Simulates the public kernel teardown circuit from its inputs.
|
|
26
|
+
* @param inputs - Inputs to the circuit.
|
|
27
|
+
* @returns The public inputs as outputs of the simulation.
|
|
28
|
+
*/
|
|
29
|
+
publicKernelCircuitTeardown(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
|
|
30
|
+
/**
|
|
31
|
+
* Simulates the public kernel tail circuit from its inputs.
|
|
32
|
+
* @param inputs - Inputs to the circuit.
|
|
33
|
+
* @returns The public inputs as outputs of the simulation.
|
|
34
|
+
*/
|
|
35
|
+
publicKernelCircuitTail(inputs: PublicKernelTailCircuitPrivateInputs): Promise<KernelCircuitPublicInputs>;
|
|
36
|
+
}
|