@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
package/src/public/executor.ts
CHANGED
|
@@ -1,58 +1,110 @@
|
|
|
1
1
|
import { UnencryptedFunctionL2Logs } from '@aztec/circuit-types';
|
|
2
|
-
import { Fr, type GlobalVariables, type Header, PublicCircuitPublicInputs } from '@aztec/circuits.js';
|
|
2
|
+
import { Fr, Gas, type GlobalVariables, type Header, PublicCircuitPublicInputs } from '@aztec/circuits.js';
|
|
3
3
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
4
|
|
|
5
5
|
import { spawn } from 'child_process';
|
|
6
6
|
import fs from 'fs/promises';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
|
|
9
|
-
import { Oracle, acvm, extractCallStack,
|
|
9
|
+
import { Oracle, acvm, extractCallStack, witnessMapToFields } from '../acvm/index.js';
|
|
10
10
|
import { AvmContext } from '../avm/avm_context.js';
|
|
11
11
|
import { AvmMachineState } from '../avm/avm_machine_state.js';
|
|
12
12
|
import { AvmSimulator } from '../avm/avm_simulator.js';
|
|
13
13
|
import { HostStorage } from '../avm/journal/host_storage.js';
|
|
14
14
|
import { AvmPersistableStateManager } from '../avm/journal/index.js';
|
|
15
|
-
import {
|
|
16
|
-
isAvmBytecode,
|
|
17
|
-
temporaryConvertAvmResults,
|
|
18
|
-
temporaryCreateAvmExecutionEnvironment,
|
|
19
|
-
} from '../avm/temporary_executor_migration.js';
|
|
20
15
|
import { AcirSimulator } from '../client/simulator.js';
|
|
21
16
|
import { ExecutionError, createSimulationError } from '../common/errors.js';
|
|
22
17
|
import { SideEffectCounter } from '../common/index.js';
|
|
23
|
-
import {
|
|
18
|
+
import { PackedValuesCache } from '../common/packed_values_cache.js';
|
|
24
19
|
import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db.js';
|
|
25
20
|
import { type PublicExecution, type PublicExecutionResult, checkValidStaticCall } from './execution.js';
|
|
26
21
|
import { PublicExecutionContext } from './public_execution_context.js';
|
|
22
|
+
import { convertAvmResults, createAvmExecutionEnvironment, isAvmBytecode } from './transitional_adaptors.js';
|
|
27
23
|
|
|
28
24
|
/**
|
|
29
25
|
* Execute a public function and return the execution result.
|
|
30
26
|
*/
|
|
31
27
|
export async function executePublicFunction(
|
|
28
|
+
context: PublicExecutionContext,
|
|
29
|
+
nested: boolean,
|
|
30
|
+
): Promise<PublicExecutionResult> {
|
|
31
|
+
const bytecode = await context.contractsDb.getBytecode(
|
|
32
|
+
context.execution.contractAddress,
|
|
33
|
+
context.execution.functionData.selector,
|
|
34
|
+
);
|
|
35
|
+
if (!bytecode) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Bytecode not found for ${context.execution.contractAddress}:${context.execution.functionData.selector}`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isAvmBytecode(bytecode)) {
|
|
42
|
+
return await executePublicFunctionAvm(context);
|
|
43
|
+
} else {
|
|
44
|
+
return await executePublicFunctionAcvm(context, bytecode, nested);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function executePublicFunctionAvm(executionContext: PublicExecutionContext): Promise<PublicExecutionResult> {
|
|
49
|
+
const address = executionContext.execution.contractAddress;
|
|
50
|
+
const selector = executionContext.execution.functionData.selector;
|
|
51
|
+
const log = createDebugLogger('aztec:simulator:public_execution');
|
|
52
|
+
log.verbose(`[AVM] Executing public external function ${address.toString()}:${selector}.`);
|
|
53
|
+
|
|
54
|
+
// Temporary code to construct the AVM context
|
|
55
|
+
// These data structures will permeate across the simulator when the public executor is phased out
|
|
56
|
+
const hostStorage = new HostStorage(
|
|
57
|
+
executionContext.stateDb,
|
|
58
|
+
executionContext.contractsDb,
|
|
59
|
+
executionContext.commitmentsDb,
|
|
60
|
+
);
|
|
61
|
+
const worldStateJournal = new AvmPersistableStateManager(hostStorage);
|
|
62
|
+
|
|
63
|
+
const executionEnv = createAvmExecutionEnvironment(
|
|
64
|
+
executionContext.execution,
|
|
65
|
+
executionContext.header,
|
|
66
|
+
executionContext.globalVariables,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const machineState = new AvmMachineState(executionContext.execution.callContext.gasLeft);
|
|
70
|
+
const context = new AvmContext(worldStateJournal, executionEnv, machineState);
|
|
71
|
+
const simulator = new AvmSimulator(context);
|
|
72
|
+
|
|
73
|
+
const result = await simulator.execute();
|
|
74
|
+
const newWorldState = context.persistableState.flush();
|
|
75
|
+
|
|
76
|
+
log.verbose(
|
|
77
|
+
`[AVM] ${address.toString()}:${selector} returned, reverted: ${result.reverted}, reason: ${result.revertReason}.`,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
return await convertAvmResults(executionContext, newWorldState, result, machineState);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function executePublicFunctionAcvm(
|
|
32
84
|
context: PublicExecutionContext,
|
|
33
85
|
acir: Buffer,
|
|
34
86
|
nested: boolean,
|
|
35
|
-
log = createDebugLogger('aztec:simulator:public_execution'),
|
|
36
87
|
): Promise<PublicExecutionResult> {
|
|
37
88
|
const execution = context.execution;
|
|
38
89
|
const { contractAddress, functionData } = execution;
|
|
39
90
|
const selector = functionData.selector;
|
|
40
|
-
log
|
|
91
|
+
const log = createDebugLogger('aztec:simulator:public_execution');
|
|
92
|
+
log.verbose(`[ACVM] Executing public external function ${contractAddress.toString()}:${selector}.`);
|
|
41
93
|
|
|
42
94
|
const initialWitness = context.getInitialWitness();
|
|
43
95
|
const acvmCallback = new Oracle(context);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})
|
|
55
|
-
|
|
96
|
+
|
|
97
|
+
const { partialWitness, returnWitnessMap, reverted, revertReason } = await (async () => {
|
|
98
|
+
try {
|
|
99
|
+
const result = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback);
|
|
100
|
+
return {
|
|
101
|
+
partialWitness: result.partialWitness,
|
|
102
|
+
returnWitnessMap: result.returnWitness,
|
|
103
|
+
reverted: false,
|
|
104
|
+
revertReason: undefined,
|
|
105
|
+
};
|
|
106
|
+
} catch (err_) {
|
|
107
|
+
const err = err_ as Error;
|
|
56
108
|
const ee = new ExecutionError(
|
|
57
109
|
err.message,
|
|
58
110
|
{
|
|
@@ -69,11 +121,14 @@ export async function executePublicFunction(
|
|
|
69
121
|
} else {
|
|
70
122
|
return {
|
|
71
123
|
partialWitness: undefined,
|
|
124
|
+
returnWitnessMap: undefined,
|
|
72
125
|
reverted: true,
|
|
73
126
|
revertReason: createSimulationError(ee),
|
|
74
127
|
};
|
|
75
128
|
}
|
|
76
|
-
}
|
|
129
|
+
}
|
|
130
|
+
})();
|
|
131
|
+
|
|
77
132
|
if (reverted) {
|
|
78
133
|
if (!revertReason) {
|
|
79
134
|
throw new Error('Reverted but no revert reason');
|
|
@@ -96,6 +151,7 @@ export async function executePublicFunction(
|
|
|
96
151
|
unencryptedLogs: UnencryptedFunctionL2Logs.empty(),
|
|
97
152
|
reverted,
|
|
98
153
|
revertReason,
|
|
154
|
+
gasLeft: Gas.empty(),
|
|
99
155
|
};
|
|
100
156
|
}
|
|
101
157
|
|
|
@@ -103,9 +159,9 @@ export async function executePublicFunction(
|
|
|
103
159
|
throw new Error('No partial witness returned from ACVM');
|
|
104
160
|
}
|
|
105
161
|
|
|
106
|
-
const returnWitness =
|
|
162
|
+
const returnWitness = witnessMapToFields(returnWitnessMap);
|
|
107
163
|
const {
|
|
108
|
-
|
|
164
|
+
returnsHash,
|
|
109
165
|
nullifierReadRequests: nullifierReadRequestsPadded,
|
|
110
166
|
nullifierNonExistentReadRequests: nullifierNonExistentReadRequestsPadded,
|
|
111
167
|
newL2ToL1Msgs,
|
|
@@ -114,6 +170,7 @@ export async function executePublicFunction(
|
|
|
114
170
|
startSideEffectCounter,
|
|
115
171
|
endSideEffectCounter,
|
|
116
172
|
} = PublicCircuitPublicInputs.fromFields(returnWitness);
|
|
173
|
+
const returnValues = await context.unpackReturns(returnsHash);
|
|
117
174
|
|
|
118
175
|
const nullifierReadRequests = nullifierReadRequestsPadded.filter(v => !v.isEmpty());
|
|
119
176
|
const nullifierNonExistentReadRequests = nullifierNonExistentReadRequestsPadded.filter(v => !v.isEmpty());
|
|
@@ -123,12 +180,12 @@ export async function executePublicFunction(
|
|
|
123
180
|
|
|
124
181
|
const { contractStorageReads, contractStorageUpdateRequests } = context.getStorageActionData();
|
|
125
182
|
|
|
126
|
-
log(
|
|
183
|
+
log.debug(
|
|
127
184
|
`Contract storage reads: ${contractStorageReads
|
|
128
185
|
.map(r => r.toFriendlyJSON() + ` - sec: ${r.sideEffectCounter}`)
|
|
129
186
|
.join(', ')}`,
|
|
130
187
|
);
|
|
131
|
-
log(
|
|
188
|
+
log.debug(
|
|
132
189
|
`Contract storage update requests: ${contractStorageUpdateRequests
|
|
133
190
|
.map(r => r.toFriendlyJSON() + ` - sec: ${r.sideEffectCounter}`)
|
|
134
191
|
.join(', ')}`,
|
|
@@ -136,6 +193,7 @@ export async function executePublicFunction(
|
|
|
136
193
|
|
|
137
194
|
const nestedExecutions = context.getNestedExecutions();
|
|
138
195
|
const unencryptedLogs = context.getUnencryptedLogs();
|
|
196
|
+
const gasLeft = context.execution.callContext.gasLeft; // No gas metering for ACVM
|
|
139
197
|
|
|
140
198
|
return {
|
|
141
199
|
execution,
|
|
@@ -153,6 +211,7 @@ export async function executePublicFunction(
|
|
|
153
211
|
unencryptedLogs,
|
|
154
212
|
reverted: false,
|
|
155
213
|
revertReason: undefined,
|
|
214
|
+
gasLeft,
|
|
156
215
|
};
|
|
157
216
|
}
|
|
158
217
|
|
|
@@ -179,39 +238,9 @@ export class PublicExecutor {
|
|
|
179
238
|
globalVariables: GlobalVariables,
|
|
180
239
|
sideEffectCounter: number = 0,
|
|
181
240
|
): Promise<PublicExecutionResult> {
|
|
182
|
-
const selector = execution.functionData.selector;
|
|
183
|
-
const bytecode = await this.contractsDb.getBytecode(execution.contractAddress, selector);
|
|
184
|
-
if (!bytecode) {
|
|
185
|
-
throw new Error(`Bytecode not found for ${execution.contractAddress}:${selector}`);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (isAvmBytecode(bytecode)) {
|
|
189
|
-
return await this.simulateAvm(execution, globalVariables, sideEffectCounter);
|
|
190
|
-
} else {
|
|
191
|
-
return await this.simulateAcvm(execution, globalVariables, sideEffectCounter);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Executes a public execution request with the ACVM.
|
|
197
|
-
* @param execution - The execution to run.
|
|
198
|
-
* @param globalVariables - The global variables to use.
|
|
199
|
-
* @returns The result of the run plus all nested runs.
|
|
200
|
-
*/
|
|
201
|
-
private async simulateAcvm(
|
|
202
|
-
execution: PublicExecution,
|
|
203
|
-
globalVariables: GlobalVariables,
|
|
204
|
-
sideEffectCounter: number = 0,
|
|
205
|
-
): Promise<PublicExecutionResult> {
|
|
206
|
-
const selector = execution.functionData.selector;
|
|
207
|
-
const acir = await this.contractsDb.getBytecode(execution.contractAddress, selector);
|
|
208
|
-
if (!acir) {
|
|
209
|
-
throw new Error(`Bytecode not found for ${execution.contractAddress}:${selector}`);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
241
|
// Functions can request to pack arguments before calling other functions.
|
|
213
242
|
// We use this cache to hold the packed arguments.
|
|
214
|
-
const packedArgs =
|
|
243
|
+
const packedArgs = PackedValuesCache.create([]);
|
|
215
244
|
|
|
216
245
|
const context = new PublicExecutionContext(
|
|
217
246
|
execution,
|
|
@@ -224,7 +253,7 @@ export class PublicExecutor {
|
|
|
224
253
|
this.commitmentsDb,
|
|
225
254
|
);
|
|
226
255
|
|
|
227
|
-
const executionResult = await executePublicFunction(context,
|
|
256
|
+
const executionResult = await executePublicFunction(context, /*nested=*/ false);
|
|
228
257
|
|
|
229
258
|
if (executionResult.execution.callContext.isStaticCall) {
|
|
230
259
|
checkValidStaticCall(
|
|
@@ -239,35 +268,6 @@ export class PublicExecutor {
|
|
|
239
268
|
return executionResult;
|
|
240
269
|
}
|
|
241
270
|
|
|
242
|
-
/**
|
|
243
|
-
* Executes a public execution request in the AVM.
|
|
244
|
-
* @param execution - The execution to run.
|
|
245
|
-
* @param globalVariables - The global variables to use.
|
|
246
|
-
* @returns The result of the run plus all nested runs.
|
|
247
|
-
*/
|
|
248
|
-
private async simulateAvm(
|
|
249
|
-
execution: PublicExecution,
|
|
250
|
-
globalVariables: GlobalVariables,
|
|
251
|
-
_sideEffectCounter = 0,
|
|
252
|
-
): Promise<PublicExecutionResult> {
|
|
253
|
-
// Temporary code to construct the AVM context
|
|
254
|
-
// These data structures will permeate across the simulator when the public executor is phased out
|
|
255
|
-
const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb);
|
|
256
|
-
const worldStateJournal = new AvmPersistableStateManager(hostStorage);
|
|
257
|
-
const executionEnv = temporaryCreateAvmExecutionEnvironment(execution, globalVariables);
|
|
258
|
-
// TODO(@spalladino) Load initial gas from the public execution request
|
|
259
|
-
const machineState = new AvmMachineState(1e10, 1e10, 1e10);
|
|
260
|
-
|
|
261
|
-
const context = new AvmContext(worldStateJournal, executionEnv, machineState);
|
|
262
|
-
const simulator = new AvmSimulator(context);
|
|
263
|
-
|
|
264
|
-
const result = await simulator.execute();
|
|
265
|
-
const newWorldState = context.persistableState.flush();
|
|
266
|
-
|
|
267
|
-
// TODO(@spalladino) Read gas left from machineState and return it
|
|
268
|
-
return temporaryConvertAvmResults(execution, newWorldState, result);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
271
|
/**
|
|
272
272
|
* These functions are currently housed in the temporary executor as it relies on access to
|
|
273
273
|
* oracles like the contractsDB and this is the least intrusive way to achieve this.
|
|
@@ -305,7 +305,7 @@ export class PublicExecutor {
|
|
|
305
305
|
|
|
306
306
|
const bbExec = path.join(bbPath, 'build', 'bin', 'bb');
|
|
307
307
|
const bbArgs = ['avm_prove', '-b', bytecodePath, '-d', calldataPath, '-o', proofPath];
|
|
308
|
-
this.log(`calling '${bbExec} ${bbArgs.join(' ')}'`);
|
|
308
|
+
this.log.debug(`calling '${bbExec} ${bbArgs.join(' ')}'`);
|
|
309
309
|
const bbBinary = spawn(bbExec, bbArgs);
|
|
310
310
|
|
|
311
311
|
// The binary writes the proof and the verification key to the write path.
|
|
@@ -314,7 +314,7 @@ export class PublicExecutor {
|
|
|
314
314
|
let stderr: string = '';
|
|
315
315
|
|
|
316
316
|
bbBinary.on('close', () => {
|
|
317
|
-
this.log(`Proof generation complete. Reading proof and vk from ${proofPath}.`);
|
|
317
|
+
this.log.verbose(`Proof generation complete. Reading proof and vk from ${proofPath}.`);
|
|
318
318
|
return resolve(Promise.all([fs.readFile(proofPath), fs.readFile(path.join(artifactsPath, 'vk'))]));
|
|
319
319
|
});
|
|
320
320
|
|
|
@@ -324,7 +324,7 @@ export class PublicExecutor {
|
|
|
324
324
|
});
|
|
325
325
|
bbBinary.stdout.on('end', () => {
|
|
326
326
|
if (stdout.length > 0) {
|
|
327
|
-
this.log(`stdout: ${stdout}`);
|
|
327
|
+
this.log.debug(`stdout: ${stdout}`);
|
|
328
328
|
}
|
|
329
329
|
});
|
|
330
330
|
|
|
@@ -334,7 +334,7 @@ export class PublicExecutor {
|
|
|
334
334
|
});
|
|
335
335
|
bbBinary.stderr.on('end', () => {
|
|
336
336
|
if (stderr.length > 0) {
|
|
337
|
-
this.log(`stderr: ${stderr}`);
|
|
337
|
+
this.log.warn(`stderr: ${stderr}`);
|
|
338
338
|
}
|
|
339
339
|
});
|
|
340
340
|
|
|
@@ -366,7 +366,7 @@ export class PublicExecutor {
|
|
|
366
366
|
|
|
367
367
|
const bbExec = path.join(bbPath, 'build', 'bin', 'bb');
|
|
368
368
|
const bbArgs = ['avm_verify', '-p', proofPath];
|
|
369
|
-
this.log(`calling '${bbPath} ${bbArgs.join(' ')}'`);
|
|
369
|
+
this.log.debug(`calling '${bbPath} ${bbArgs.join(' ')}'`);
|
|
370
370
|
const bbBinary = spawn(bbExec, bbArgs);
|
|
371
371
|
|
|
372
372
|
// The binary prints to stdout 1 if the proof is valid and 0 if it is not.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
+
import {
|
|
3
|
+
type Fr,
|
|
4
|
+
MAX_NEW_NULLIFIERS_PER_TX,
|
|
5
|
+
type MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX,
|
|
6
|
+
type MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
7
|
+
MAX_PUBLIC_DATA_READS_PER_TX,
|
|
8
|
+
MembershipWitness,
|
|
9
|
+
NULLIFIER_TREE_HEIGHT,
|
|
10
|
+
PUBLIC_DATA_TREE_HEIGHT,
|
|
11
|
+
type PublicDataRead,
|
|
12
|
+
PublicDataTreeLeafPreimage,
|
|
13
|
+
type ReadRequestContext,
|
|
14
|
+
type SideEffectLinkedToNoteHash,
|
|
15
|
+
buildNullifierNonExistentReadRequestHints,
|
|
16
|
+
buildNullifierReadRequestHints,
|
|
17
|
+
mergeAccumulatedData,
|
|
18
|
+
} from '@aztec/circuits.js';
|
|
19
|
+
import { makeTuple } from '@aztec/foundation/array';
|
|
20
|
+
import { type Tuple } from '@aztec/foundation/serialize';
|
|
21
|
+
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
22
|
+
|
|
23
|
+
export class HintsBuilder {
|
|
24
|
+
constructor(private db: MerkleTreeOperations) {}
|
|
25
|
+
|
|
26
|
+
getNullifierReadRequestHints(
|
|
27
|
+
nullifierReadRequests: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
|
|
28
|
+
nullifiersNonRevertible: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
29
|
+
nullifiersRevertible: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
30
|
+
) {
|
|
31
|
+
return buildNullifierReadRequestHints(
|
|
32
|
+
this,
|
|
33
|
+
nullifierReadRequests,
|
|
34
|
+
mergeAccumulatedData(MAX_NEW_NULLIFIERS_PER_TX, nullifiersNonRevertible, nullifiersRevertible),
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getNullifierNonExistentReadRequestHints(
|
|
39
|
+
nullifierNonExistentReadRequests: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX>,
|
|
40
|
+
nullifiersNonRevertible: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
41
|
+
nullifiersRevertible: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
42
|
+
) {
|
|
43
|
+
const pendingNullifiers = mergeAccumulatedData(
|
|
44
|
+
MAX_NEW_NULLIFIERS_PER_TX,
|
|
45
|
+
nullifiersNonRevertible,
|
|
46
|
+
nullifiersRevertible,
|
|
47
|
+
);
|
|
48
|
+
return buildNullifierNonExistentReadRequestHints(this, nullifierNonExistentReadRequests, pendingNullifiers);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async getNullifierMembershipWitness(nullifier: Fr) {
|
|
52
|
+
const index = await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
53
|
+
if (index === undefined) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return this.getNullifierMembershipWitnessWithPreimage(index);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async getLowNullifierMembershipWitness(nullifier: Fr) {
|
|
61
|
+
const res = await this.db.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
62
|
+
if (res === undefined) {
|
|
63
|
+
throw new Error(`Cannot find the low leaf for nullifier ${nullifier.toBigInt()}.`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const { index, alreadyPresent } = res;
|
|
67
|
+
if (alreadyPresent) {
|
|
68
|
+
throw new Error(`Nullifier ${nullifier.toBigInt()} already exists in the tree.`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return this.getNullifierMembershipWitnessWithPreimage(index);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private async getNullifierMembershipWitnessWithPreimage(index: bigint) {
|
|
75
|
+
const siblingPath = await this.db.getSiblingPath<typeof NULLIFIER_TREE_HEIGHT>(MerkleTreeId.NULLIFIER_TREE, index);
|
|
76
|
+
const membershipWitness = new MembershipWitness(
|
|
77
|
+
NULLIFIER_TREE_HEIGHT,
|
|
78
|
+
index,
|
|
79
|
+
siblingPath.toTuple<typeof NULLIFIER_TREE_HEIGHT>(),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const leafPreimage = await this.db.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
|
|
83
|
+
if (!leafPreimage) {
|
|
84
|
+
throw new Error(`Cannot find the leaf preimage at index ${index}.`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { membershipWitness, leafPreimage };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async getPublicDataReadsInfo(publicDataReads: PublicDataRead[]) {
|
|
91
|
+
const newPublicDataReadsWitnesses: Tuple<
|
|
92
|
+
MembershipWitness<typeof PUBLIC_DATA_TREE_HEIGHT>,
|
|
93
|
+
typeof MAX_PUBLIC_DATA_READS_PER_TX
|
|
94
|
+
> = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT, 0n));
|
|
95
|
+
|
|
96
|
+
const newPublicDataReadsPreimages: Tuple<PublicDataTreeLeafPreimage, typeof MAX_PUBLIC_DATA_READS_PER_TX> =
|
|
97
|
+
makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataTreeLeafPreimage.empty());
|
|
98
|
+
|
|
99
|
+
for (const i in publicDataReads) {
|
|
100
|
+
const leafSlot = publicDataReads[i].leafSlot.value;
|
|
101
|
+
const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
102
|
+
if (!lowLeafResult) {
|
|
103
|
+
throw new Error(`Public data tree should have one initial leaf`);
|
|
104
|
+
}
|
|
105
|
+
const preimage = await this.db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
106
|
+
const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
107
|
+
newPublicDataReadsWitnesses[i] = new MembershipWitness(
|
|
108
|
+
PUBLIC_DATA_TREE_HEIGHT,
|
|
109
|
+
BigInt(lowLeafResult.index),
|
|
110
|
+
path.toTuple<typeof PUBLIC_DATA_TREE_HEIGHT>(),
|
|
111
|
+
);
|
|
112
|
+
newPublicDataReadsPreimages[i] = preimage! as PublicDataTreeLeafPreimage;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
newPublicDataReadsWitnesses,
|
|
116
|
+
newPublicDataReadsPreimages,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
package/src/public/index.ts
CHANGED
|
@@ -7,3 +7,8 @@ export {
|
|
|
7
7
|
collectPublicDataUpdateRequests,
|
|
8
8
|
} from './execution.js';
|
|
9
9
|
export { PublicExecutor } from './executor.js';
|
|
10
|
+
export { PublicProcessor, PublicProcessorFactory } from './public_processor.js';
|
|
11
|
+
export * from './public_executor.js';
|
|
12
|
+
export * from './abstract_phase_manager.js';
|
|
13
|
+
export * from './public_kernel_circuit_simulator.js';
|
|
14
|
+
export * from './public_kernel.js';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { type Tx } from '@aztec/circuit-types';
|
|
2
|
+
import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
|
|
3
|
+
import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
|
|
4
|
+
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
5
|
+
|
|
6
|
+
import { type AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js';
|
|
7
|
+
import { AppLogicPhaseManager } from './app_logic_phase_manager.js';
|
|
8
|
+
import { type ContractsDataSourcePublicDB } from './public_executor.js';
|
|
9
|
+
import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js';
|
|
10
|
+
import { SetupPhaseManager } from './setup_phase_manager.js';
|
|
11
|
+
import { TailPhaseManager } from './tail_phase_manager.js';
|
|
12
|
+
import { TeardownPhaseManager } from './teardown_phase_manager.js';
|
|
13
|
+
|
|
14
|
+
export class PhaseDidNotChangeError extends Error {
|
|
15
|
+
constructor(phase: PublicKernelPhase) {
|
|
16
|
+
super(`Tried to advance the phase from [${phase}] when the circuit still needs [${phase}]`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class CannotTransitionToSetupError extends Error {
|
|
21
|
+
constructor() {
|
|
22
|
+
super('Cannot transition to setup phase');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class PhaseManagerFactory {
|
|
27
|
+
public static phaseFromTx(
|
|
28
|
+
tx: Tx,
|
|
29
|
+
db: MerkleTreeOperations,
|
|
30
|
+
publicExecutor: PublicExecutor,
|
|
31
|
+
publicKernel: PublicKernelCircuitSimulator,
|
|
32
|
+
globalVariables: GlobalVariables,
|
|
33
|
+
historicalHeader: Header,
|
|
34
|
+
publicContractsDB: ContractsDataSourcePublicDB,
|
|
35
|
+
publicStateDB: PublicStateDB,
|
|
36
|
+
): AbstractPhaseManager | undefined {
|
|
37
|
+
const data = tx.data.forPublic!;
|
|
38
|
+
if (data.needsSetup) {
|
|
39
|
+
return new SetupPhaseManager(
|
|
40
|
+
db,
|
|
41
|
+
publicExecutor,
|
|
42
|
+
publicKernel,
|
|
43
|
+
globalVariables,
|
|
44
|
+
historicalHeader,
|
|
45
|
+
publicContractsDB,
|
|
46
|
+
publicStateDB,
|
|
47
|
+
);
|
|
48
|
+
} else if (data.needsAppLogic) {
|
|
49
|
+
return new AppLogicPhaseManager(
|
|
50
|
+
db,
|
|
51
|
+
publicExecutor,
|
|
52
|
+
publicKernel,
|
|
53
|
+
globalVariables,
|
|
54
|
+
historicalHeader,
|
|
55
|
+
publicContractsDB,
|
|
56
|
+
publicStateDB,
|
|
57
|
+
);
|
|
58
|
+
} else if (data.needsTeardown) {
|
|
59
|
+
return new TeardownPhaseManager(
|
|
60
|
+
db,
|
|
61
|
+
publicExecutor,
|
|
62
|
+
publicKernel,
|
|
63
|
+
globalVariables,
|
|
64
|
+
historicalHeader,
|
|
65
|
+
publicContractsDB,
|
|
66
|
+
publicStateDB,
|
|
67
|
+
);
|
|
68
|
+
} else {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public static phaseFromOutput(
|
|
74
|
+
output: PublicKernelCircuitPublicInputs,
|
|
75
|
+
currentPhaseManager: AbstractPhaseManager,
|
|
76
|
+
db: MerkleTreeOperations,
|
|
77
|
+
publicExecutor: PublicExecutor,
|
|
78
|
+
publicKernel: PublicKernelCircuitSimulator,
|
|
79
|
+
globalVariables: GlobalVariables,
|
|
80
|
+
historicalHeader: Header,
|
|
81
|
+
publicContractsDB: ContractsDataSourcePublicDB,
|
|
82
|
+
publicStateDB: PublicStateDB,
|
|
83
|
+
): AbstractPhaseManager | undefined {
|
|
84
|
+
if (output.needsSetup) {
|
|
85
|
+
throw new CannotTransitionToSetupError();
|
|
86
|
+
} else if (output.needsAppLogic) {
|
|
87
|
+
if (currentPhaseManager.phase === PublicKernelPhase.APP_LOGIC) {
|
|
88
|
+
throw new PhaseDidNotChangeError(currentPhaseManager.phase);
|
|
89
|
+
}
|
|
90
|
+
return new AppLogicPhaseManager(
|
|
91
|
+
db,
|
|
92
|
+
publicExecutor,
|
|
93
|
+
publicKernel,
|
|
94
|
+
globalVariables,
|
|
95
|
+
historicalHeader,
|
|
96
|
+
publicContractsDB,
|
|
97
|
+
publicStateDB,
|
|
98
|
+
);
|
|
99
|
+
} else if (output.needsTeardown) {
|
|
100
|
+
if (currentPhaseManager.phase === PublicKernelPhase.TEARDOWN) {
|
|
101
|
+
throw new PhaseDidNotChangeError(currentPhaseManager.phase);
|
|
102
|
+
}
|
|
103
|
+
return new TeardownPhaseManager(
|
|
104
|
+
db,
|
|
105
|
+
publicExecutor,
|
|
106
|
+
publicKernel,
|
|
107
|
+
globalVariables,
|
|
108
|
+
historicalHeader,
|
|
109
|
+
publicContractsDB,
|
|
110
|
+
publicStateDB,
|
|
111
|
+
);
|
|
112
|
+
} else if (currentPhaseManager.phase !== PublicKernelPhase.TAIL) {
|
|
113
|
+
return new TailPhaseManager(
|
|
114
|
+
db,
|
|
115
|
+
publicExecutor,
|
|
116
|
+
publicKernel,
|
|
117
|
+
globalVariables,
|
|
118
|
+
historicalHeader,
|
|
119
|
+
publicContractsDB,
|
|
120
|
+
publicStateDB,
|
|
121
|
+
);
|
|
122
|
+
} else {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|