@aztec/simulator 0.23.0 → 0.24.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 +2 -2
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +5 -5
- package/dest/acvm/oracle/typed_oracle.d.ts +2 -2
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +3 -3
- package/dest/avm/avm_execution_environment.d.ts +3 -2
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +6 -5
- package/dest/avm/avm_memory_types.d.ts +119 -38
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +91 -109
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +2 -3
- package/dest/avm/errors.d.ts +3 -1
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +9 -3
- package/dest/avm/fixtures/index.d.ts +4 -0
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +10 -2
- package/dest/avm/journal/host_storage.d.ts +1 -1
- package/dest/avm/journal/host_storage.d.ts.map +1 -1
- package/dest/avm/opcodes/addressing_mode.d.ts +24 -0
- package/dest/avm/opcodes/addressing_mode.d.ts.map +1 -0
- package/dest/avm/opcodes/addressing_mode.js +62 -0
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +8 -5
- package/dest/avm/opcodes/instruction.d.ts +4 -4
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +1 -1
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +5 -3
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +24 -22
- package/dest/avm/serialization/instruction_serialization.d.ts +17 -15
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +18 -16
- package/dest/avm/temporary_executor_migration.d.ts +25 -0
- package/dest/avm/temporary_executor_migration.d.ts.map +1 -0
- package/dest/avm/temporary_executor_migration.js +71 -0
- package/dest/client/client_execution_context.d.ts +4 -2
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +7 -4
- package/dest/client/execution_result.d.ts +2 -0
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +1 -1
- package/dest/client/simulator.d.ts +10 -5
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +19 -11
- package/dest/client/unconstrained_execution.js +2 -2
- package/dest/public/execution.js +2 -2
- package/dest/public/executor.d.ts +7 -0
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +26 -1
- package/dest/public/public_execution_context.js +2 -2
- package/dest/public/state_actions.d.ts +1 -1
- package/dest/public/state_actions.d.ts.map +1 -1
- package/dest/public/state_actions.js +5 -6
- package/dest/utils.d.ts +5 -20
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +4 -20
- package/package.json +7 -5
- package/src/acvm/acvm.ts +156 -0
- package/src/acvm/acvm_types.ts +11 -0
- package/src/acvm/deserialize.ts +36 -0
- package/src/acvm/index.ts +5 -0
- package/src/acvm/oracle/debug.ts +109 -0
- package/src/acvm/oracle/index.ts +17 -0
- package/src/acvm/oracle/oracle.ts +332 -0
- package/src/acvm/oracle/typed_oracle.ts +217 -0
- package/src/acvm/serialize.ts +75 -0
- package/src/avm/avm_context.ts +63 -0
- package/src/avm/avm_execution_environment.ts +98 -0
- package/src/avm/avm_machine_state.ts +93 -0
- package/src/avm/avm_memory_types.ts +309 -0
- package/src/avm/avm_message_call_result.ts +29 -0
- package/src/avm/avm_simulator.ts +89 -0
- package/src/avm/errors.ts +57 -0
- package/src/avm/fixtures/index.ts +90 -0
- package/src/avm/journal/host_storage.ts +20 -0
- package/src/avm/journal/index.ts +2 -0
- package/src/avm/journal/journal.ts +266 -0
- package/src/avm/opcodes/.eslintrc.cjs +8 -0
- package/src/avm/opcodes/accrued_substate.ts +92 -0
- package/src/avm/opcodes/addressing_mode.ts +66 -0
- package/src/avm/opcodes/arithmetic.ts +79 -0
- package/src/avm/opcodes/bitwise.ts +129 -0
- package/src/avm/opcodes/comparators.ts +72 -0
- package/src/avm/opcodes/control_flow.ts +129 -0
- package/src/avm/opcodes/environment_getters.ts +199 -0
- package/src/avm/opcodes/external_calls.ts +122 -0
- package/src/avm/opcodes/index.ts +10 -0
- package/src/avm/opcodes/instruction.ts +64 -0
- package/src/avm/opcodes/instruction_impl.ts +52 -0
- package/src/avm/opcodes/memory.ts +193 -0
- package/src/avm/opcodes/storage.ts +76 -0
- package/src/avm/serialization/buffer_cursor.ts +109 -0
- package/src/avm/serialization/bytecode_serialization.ts +172 -0
- package/src/avm/serialization/instruction_serialization.ts +167 -0
- package/src/avm/temporary_executor_migration.ts +108 -0
- package/src/client/client_execution_context.ts +472 -0
- package/src/client/db_oracle.ts +184 -0
- package/src/client/execution_note_cache.ts +90 -0
- package/src/client/execution_result.ts +89 -0
- package/src/client/index.ts +3 -0
- package/src/client/pick_notes.ts +125 -0
- package/src/client/private_execution.ts +78 -0
- package/src/client/simulator.ts +316 -0
- package/src/client/unconstrained_execution.ts +49 -0
- package/src/client/view_data_oracle.ts +243 -0
- package/src/common/errors.ts +61 -0
- package/src/common/index.ts +3 -0
- package/src/common/packed_args_cache.ts +55 -0
- package/src/common/side_effect_counter.ts +12 -0
- package/src/index.ts +3 -0
- package/src/public/db.ts +85 -0
- package/src/public/execution.ts +137 -0
- package/src/public/executor.ts +158 -0
- package/src/public/index.ts +9 -0
- package/src/public/public_execution_context.ts +217 -0
- package/src/public/state_actions.ts +100 -0
- package/src/test/utils.ts +38 -0
- package/src/utils.ts +18 -0
package/dest/utils.js
CHANGED
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
2
1
|
import { pedersenHash } from '@aztec/foundation/crypto';
|
|
3
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
3
|
/**
|
|
5
4
|
* Computes the resulting storage slot for an entry in a mapping.
|
|
6
5
|
* @param mappingSlot - The slot of the mapping within state.
|
|
7
|
-
* @param
|
|
6
|
+
* @param key - The key of the mapping.
|
|
8
7
|
* @returns The slot in the contract storage where the value is stored.
|
|
9
8
|
*/
|
|
10
|
-
export function computeSlotForMapping(mappingSlot,
|
|
11
|
-
|
|
12
|
-
const ownerField = isFr(owner) ? owner : new Fr(owner.x);
|
|
13
|
-
return Fr.fromBuffer(pedersenHash([mappingSlot, ownerField].map(f => f.toBuffer())));
|
|
9
|
+
export function computeSlotForMapping(mappingSlot, key) {
|
|
10
|
+
return Fr.fromBuffer(pedersenHash([mappingSlot, key.toField()].map(field => field.toBuffer())));
|
|
14
11
|
}
|
|
15
|
-
|
|
16
|
-
* Computes the public key for a private key.
|
|
17
|
-
* @param privateKey - The private key.
|
|
18
|
-
* @param grumpkin - The grumpkin instance.
|
|
19
|
-
* @returns The public key.
|
|
20
|
-
*/
|
|
21
|
-
export function toPublicKey(privateKey, grumpkin) {
|
|
22
|
-
const point = grumpkin.mul(Grumpkin.generator, privateKey);
|
|
23
|
-
return {
|
|
24
|
-
x: point.x.value,
|
|
25
|
-
y: point.y.value,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFZOUM7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsV0FBZSxFQUFFLEtBQXFCO0lBQzFFLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBcUIsRUFBZSxFQUFFLENBQUMsT0FBUSxLQUFZLENBQUMsS0FBSyxLQUFLLFFBQVEsQ0FBQztJQUM3RixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXpELE9BQU8sRUFBRSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZGLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsVUFBOEIsRUFBRSxRQUFrQjtJQUM1RSxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDM0QsT0FBTztRQUNMLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUs7UUFDaEIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSztLQUNqQixDQUFDO0FBQ0osQ0FBQyJ9
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU5Qzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsV0FBZSxFQUNmLEdBR0M7SUFFRCxPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsRyxDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/simulator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"typedocOptions": {
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"rootDir": "./src"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@aztec/circuit-types": "0.
|
|
34
|
-
"@aztec/circuits.js": "0.
|
|
35
|
-
"@aztec/foundation": "0.
|
|
33
|
+
"@aztec/circuit-types": "0.24.0",
|
|
34
|
+
"@aztec/circuits.js": "0.24.0",
|
|
35
|
+
"@aztec/foundation": "0.24.0",
|
|
36
36
|
"@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js",
|
|
37
37
|
"levelup": "^5.1.1",
|
|
38
38
|
"memdown": "^6.1.1",
|
|
@@ -41,14 +41,16 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@aztec/kv-store": "workspace:^",
|
|
43
43
|
"@aztec/merkle-tree": "workspace:^",
|
|
44
|
-
"@aztec/noir-contracts": "workspace:^",
|
|
44
|
+
"@aztec/noir-contracts.js": "workspace:^",
|
|
45
45
|
"@jest/globals": "^29.5.0",
|
|
46
46
|
"@types/jest": "^29.5.0",
|
|
47
47
|
"@types/levelup": "^5.1.3",
|
|
48
|
+
"@types/lodash.merge": "^4.6.9",
|
|
48
49
|
"@types/memdown": "^3.0.2",
|
|
49
50
|
"@types/node": "^18.7.23",
|
|
50
51
|
"jest": "^29.5.0",
|
|
51
52
|
"jest-mock-extended": "^3.0.4",
|
|
53
|
+
"lodash.merge": "^4.6.2",
|
|
52
54
|
"ts-jest": "^29.1.0",
|
|
53
55
|
"ts-node": "^10.9.1",
|
|
54
56
|
"typescript": "^5.0.4",
|
package/src/acvm/acvm.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { NoirCallStack, SourceCodeLocation } from '@aztec/circuit-types';
|
|
2
|
+
import { FunctionDebugMetadata, OpcodeLocation } from '@aztec/foundation/abi';
|
|
3
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
ExecutionError,
|
|
7
|
+
ForeignCallInput,
|
|
8
|
+
ForeignCallOutput,
|
|
9
|
+
WasmBlackBoxFunctionSolver,
|
|
10
|
+
executeCircuitWithBlackBoxSolver,
|
|
11
|
+
} from '@noir-lang/acvm_js';
|
|
12
|
+
|
|
13
|
+
import { traverseCauseChain } from '../common/errors.js';
|
|
14
|
+
import { ACVMWitness } from './acvm_types.js';
|
|
15
|
+
import { ORACLE_NAMES } from './oracle/index.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The callback interface for the ACIR.
|
|
19
|
+
*/
|
|
20
|
+
type ACIRCallback = Record<
|
|
21
|
+
ORACLE_NAMES,
|
|
22
|
+
(...args: ForeignCallInput[]) => ForeignCallOutput | Promise<ForeignCallOutput>
|
|
23
|
+
>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The result of executing an ACIR.
|
|
27
|
+
*/
|
|
28
|
+
export interface ACIRExecutionResult {
|
|
29
|
+
/**
|
|
30
|
+
* The partial witness of the execution.
|
|
31
|
+
*/
|
|
32
|
+
partialWitness: ACVMWitness;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Extracts the call stack from the location of a failing opcode and the debug metadata.
|
|
37
|
+
* One opcode can point to multiple calls due to inlining.
|
|
38
|
+
*/
|
|
39
|
+
function getSourceCodeLocationsFromOpcodeLocation(
|
|
40
|
+
opcodeLocation: string,
|
|
41
|
+
debug: FunctionDebugMetadata,
|
|
42
|
+
): SourceCodeLocation[] {
|
|
43
|
+
const { debugSymbols, files } = debug;
|
|
44
|
+
|
|
45
|
+
const callStack = debugSymbols.locations[opcodeLocation] || [];
|
|
46
|
+
return callStack.map(call => {
|
|
47
|
+
const { file: fileId, span } = call;
|
|
48
|
+
|
|
49
|
+
const { path, source } = files[fileId];
|
|
50
|
+
|
|
51
|
+
const locationText = source.substring(span.start, span.end);
|
|
52
|
+
const precedingText = source.substring(0, span.start);
|
|
53
|
+
const previousLines = precedingText.split('\n');
|
|
54
|
+
// Lines and columns in stacks are one indexed.
|
|
55
|
+
const line = previousLines.length;
|
|
56
|
+
const column = previousLines[previousLines.length - 1].length + 1;
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
filePath: path,
|
|
60
|
+
line,
|
|
61
|
+
column,
|
|
62
|
+
fileSource: source,
|
|
63
|
+
locationText,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Extracts the source code locations for an array of opcode locations
|
|
70
|
+
* @param opcodeLocations - The opcode locations that caused the error.
|
|
71
|
+
* @param debug - The debug metadata of the function.
|
|
72
|
+
* @returns The source code locations.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveOpcodeLocations(
|
|
75
|
+
opcodeLocations: OpcodeLocation[],
|
|
76
|
+
debug: FunctionDebugMetadata,
|
|
77
|
+
): SourceCodeLocation[] {
|
|
78
|
+
return opcodeLocations.flatMap(opcodeLocation => getSourceCodeLocationsFromOpcodeLocation(opcodeLocation, debug));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The function call that executes an ACIR.
|
|
83
|
+
*/
|
|
84
|
+
export async function acvm(
|
|
85
|
+
solver: WasmBlackBoxFunctionSolver,
|
|
86
|
+
acir: Buffer,
|
|
87
|
+
initialWitness: ACVMWitness,
|
|
88
|
+
callback: ACIRCallback,
|
|
89
|
+
): Promise<ACIRExecutionResult> {
|
|
90
|
+
const logger = createDebugLogger('aztec:simulator:acvm');
|
|
91
|
+
|
|
92
|
+
const partialWitness = await executeCircuitWithBlackBoxSolver(
|
|
93
|
+
solver,
|
|
94
|
+
acir,
|
|
95
|
+
initialWitness,
|
|
96
|
+
async (name: string, args: ForeignCallInput[]) => {
|
|
97
|
+
try {
|
|
98
|
+
logger(`Oracle callback ${name}`);
|
|
99
|
+
const oracleFunction = callback[name as ORACLE_NAMES];
|
|
100
|
+
if (!oracleFunction) {
|
|
101
|
+
throw new Error(`Oracle callback ${name} not found`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const result = await oracleFunction.call(callback, ...args);
|
|
105
|
+
return [result];
|
|
106
|
+
} catch (err) {
|
|
107
|
+
let typedError: Error;
|
|
108
|
+
if (err instanceof Error) {
|
|
109
|
+
typedError = err;
|
|
110
|
+
} else {
|
|
111
|
+
typedError = new Error(`Error in oracle callback ${err}`);
|
|
112
|
+
}
|
|
113
|
+
logger.error(`Error in oracle callback ${name}`);
|
|
114
|
+
throw typedError;
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
).catch((err: Error) => {
|
|
118
|
+
// Wasm callbacks act as a boundary for stack traces, so we capture it here and complete the error if it happens.
|
|
119
|
+
const stack = new Error().stack;
|
|
120
|
+
|
|
121
|
+
traverseCauseChain(err, cause => {
|
|
122
|
+
if (cause.stack) {
|
|
123
|
+
cause.stack += stack;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
throw err;
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return { partialWitness };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Extracts the call stack from an thrown by the acvm.
|
|
135
|
+
* @param error - The error to extract from.
|
|
136
|
+
* @param debug - The debug metadata of the function called.
|
|
137
|
+
* @returns The call stack, if available.
|
|
138
|
+
*/
|
|
139
|
+
export function extractCallStack(
|
|
140
|
+
error: Error | ExecutionError,
|
|
141
|
+
debug?: FunctionDebugMetadata,
|
|
142
|
+
): NoirCallStack | undefined {
|
|
143
|
+
if (!('callStack' in error) || !error.callStack) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const { callStack } = error;
|
|
147
|
+
if (!debug) {
|
|
148
|
+
return callStack;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
return resolveOpcodeLocations(callStack, debug);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
return callStack;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
|
|
3
|
+
import { getReturnWitness } from '@noir-lang/acvm_js';
|
|
4
|
+
|
|
5
|
+
import { ACVMField, ACVMWitness } from './acvm_types.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Converts an ACVM field to a Fr.
|
|
9
|
+
* @param field - The ACVM field to convert.
|
|
10
|
+
* @returns The Fr.
|
|
11
|
+
*/
|
|
12
|
+
export function fromACVMField(field: ACVMField): Fr {
|
|
13
|
+
return Fr.fromBuffer(Buffer.from(field.slice(2), 'hex'));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Converts a field to a number.
|
|
18
|
+
* @param fr - The field to convert.
|
|
19
|
+
* @returns The number.
|
|
20
|
+
* TODO(#4102): Nuke this once block number is big int.
|
|
21
|
+
*/
|
|
22
|
+
export function frToNumber(fr: Fr): number {
|
|
23
|
+
return Number(fr.value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Extracts the return fields of a given partial witness.
|
|
28
|
+
* @param acir - The bytecode of the function.
|
|
29
|
+
* @param partialWitness - The witness to extract from.
|
|
30
|
+
* @returns The return values.
|
|
31
|
+
*/
|
|
32
|
+
export function extractReturnWitness(acir: Buffer, partialWitness: ACVMWitness): Fr[] {
|
|
33
|
+
const returnWitness = getReturnWitness(acir, partialWitness);
|
|
34
|
+
const sortedKeys = [...returnWitness.keys()].sort((a, b) => a - b);
|
|
35
|
+
return sortedKeys.map(key => returnWitness.get(key)!).map(fromACVMField);
|
|
36
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ForeignCallInput } from '@noir-lang/acvm_js';
|
|
2
|
+
|
|
3
|
+
import { ACVMField } from '../acvm_types.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert an array of ACVMFields to a string.
|
|
7
|
+
*
|
|
8
|
+
* @param msg - array of ACVMFields where each represents a single ascii character
|
|
9
|
+
* @returns string representation of the message
|
|
10
|
+
*/
|
|
11
|
+
export function acvmFieldMessageToString(msg: ACVMField[]): string {
|
|
12
|
+
let msgStr = '';
|
|
13
|
+
for (const msgChar of msg) {
|
|
14
|
+
const asciiCode = Number(msgChar);
|
|
15
|
+
const asciiChar = String.fromCharCode(asciiCode);
|
|
16
|
+
msgStr = msgStr.concat(asciiChar);
|
|
17
|
+
}
|
|
18
|
+
// cut off string in case of preemptive null termination
|
|
19
|
+
const nullCharIndex = msgStr.indexOf('\\0');
|
|
20
|
+
if (nullCharIndex >= 0) {
|
|
21
|
+
msgStr = msgStr.substring(0, nullCharIndex);
|
|
22
|
+
}
|
|
23
|
+
return msgStr.replaceAll('\\n', '\n').replaceAll('\\t', '\t');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Format a debug string for Aztec.nr filling in `'{0}'` entries with their
|
|
28
|
+
* corresponding values from the args array.
|
|
29
|
+
*
|
|
30
|
+
* @param formatStr - str of form `'this is a string with some entries like {0} and {1}'`
|
|
31
|
+
* @param args - array of fields to fill in the string format entries with
|
|
32
|
+
* @returns formatted string
|
|
33
|
+
*/
|
|
34
|
+
function applyStringFormatting(formatStr: string, args: ACVMField[]): string {
|
|
35
|
+
const matches = formatStr.match(/{\d+}/g);
|
|
36
|
+
if (matches == null) {
|
|
37
|
+
return formatStr;
|
|
38
|
+
}
|
|
39
|
+
// Get the numeric values within the curly braces, convert them to numbers,
|
|
40
|
+
// and find the maximum value.
|
|
41
|
+
const maxIndex = Math.max(...matches.map(match => Number(match.slice(1, -1))));
|
|
42
|
+
const argsPadded = args.concat(Array.from({ length: Math.max(0, maxIndex - args.length) }, () => '0xBAD'));
|
|
43
|
+
|
|
44
|
+
return formatStr.replace(/{(\d+)}/g, function (match, index) {
|
|
45
|
+
return typeof args[index] != 'undefined' ? argsPadded[index] : match;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Convert an array of ACVMFields from ACVM to a formatted string.
|
|
51
|
+
*
|
|
52
|
+
* @param parameters - either one parameter representing a simple field or array, or two parameters when
|
|
53
|
+
* It's a message without args or three parameters when it's a message with arguments.
|
|
54
|
+
*
|
|
55
|
+
* @returns formatted string
|
|
56
|
+
*/
|
|
57
|
+
export function oracleDebugCallToFormattedStr(parameters: ForeignCallInput[]): string {
|
|
58
|
+
if (parameters.length === 1) {
|
|
59
|
+
return processFieldOrArray(parameters[0]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let formatArgs: string[] = [];
|
|
63
|
+
|
|
64
|
+
if (parameters.length > 2) {
|
|
65
|
+
formatArgs = parameters[1];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const formattedMsg = applyStringFormatting(acvmFieldMessageToString(parameters[0]), formatArgs);
|
|
69
|
+
|
|
70
|
+
return formattedMsg;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Processes a field or an array and returns a string representation.
|
|
75
|
+
* @param fieldOrArray - The field or array to be processed.
|
|
76
|
+
* @returns Returns the processed string representation of the field or array.
|
|
77
|
+
*/
|
|
78
|
+
function processFieldOrArray(fieldOrArray: string[]) {
|
|
79
|
+
if (fieldOrArray.length === 1) {
|
|
80
|
+
return `${fieldOrArray[0]}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check if all the elements start with 63 zero bytes
|
|
84
|
+
// --> if yes, we have an array of bytes and we print as hex
|
|
85
|
+
if (onlyBytes(fieldOrArray)) {
|
|
86
|
+
const decimalArray = fieldOrArray.map(element => parseInt(element, 16));
|
|
87
|
+
return '0x' + Buffer.from(decimalArray).toString('hex');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return '[' + fieldOrArray.join(', ') + ']';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Checks if all elements in the array are valid byte representations.
|
|
95
|
+
* @param array - The array to be checked.
|
|
96
|
+
* @returns Returns `true` if all elements are valid byte representations, `false` otherwise.
|
|
97
|
+
* @throws Throws an error if any element has an invalid length.
|
|
98
|
+
*/
|
|
99
|
+
function onlyBytes(array: string[]): boolean {
|
|
100
|
+
for (const element of array) {
|
|
101
|
+
if (element.length != 66) {
|
|
102
|
+
throw new Error('Invalid element length. Expected 66 chars, got ' + element.length + ' chars.');
|
|
103
|
+
}
|
|
104
|
+
if (!element.startsWith('0x00000000000000000000000000000000000000000000000000000000000000')) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Oracle } from './oracle.js';
|
|
2
|
+
|
|
3
|
+
export * from './debug.js';
|
|
4
|
+
export * from './oracle.js';
|
|
5
|
+
export * from './typed_oracle.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A conditional type that takes a type `T` and returns a union of its method names.
|
|
9
|
+
*/
|
|
10
|
+
type MethodNames<T> = {
|
|
11
|
+
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
|
|
12
|
+
}[keyof T];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Available oracle function names.
|
|
16
|
+
*/
|
|
17
|
+
export type ORACLE_NAMES = MethodNames<Oracle>;
|