@aztec/simulator 0.79.0 → 0.81.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/common/db_interfaces.d.ts +24 -5
- package/dest/common/db_interfaces.d.ts.map +1 -1
- package/dest/common/debug_fn_name.d.ts +2 -2
- package/dest/common/debug_fn_name.d.ts.map +1 -1
- package/dest/private/acvm/deserialize.d.ts +19 -0
- package/dest/private/acvm/deserialize.d.ts.map +1 -1
- package/dest/private/acvm/deserialize.js +29 -0
- package/dest/private/acvm/oracle/oracle.d.ts +2 -0
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +18 -3
- package/dest/private/acvm/oracle/typed_oracle.d.ts +2 -1
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/typed_oracle.js +3 -0
- package/dest/private/acvm/serialize.d.ts +11 -0
- package/dest/private/acvm/serialize.d.ts.map +1 -1
- package/dest/private/acvm/serialize.js +27 -0
- package/dest/private/execution_data_provider.d.ts +12 -4
- package/dest/private/execution_data_provider.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.js +1 -1
- package/dest/private/unconstrained_execution_oracle.d.ts +4 -2
- package/dest/private/unconstrained_execution_oracle.d.ts.map +1 -1
- package/dest/private/unconstrained_execution_oracle.js +6 -2
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +5 -5
- package/dest/public/avm/fixtures/index.d.ts +6 -6
- package/dest/public/avm/fixtures/index.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.js +22 -18
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +1 -2
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +1 -1
- package/dest/public/avm/fixtures/simple_contract_data_source.js +0 -3
- package/dest/public/avm/journal/journal.d.ts +16 -70
- package/dest/public/avm/journal/journal.d.ts.map +1 -1
- package/dest/public/avm/journal/journal.js +88 -210
- package/dest/public/avm/journal/nullifiers.d.ts +2 -2
- package/dest/public/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/public/avm/journal/public_storage.d.ts +2 -2
- package/dest/public/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/public/avm/test_utils.d.ts +10 -13
- package/dest/public/avm/test_utils.d.ts.map +1 -1
- package/dest/public/avm/test_utils.js +7 -12
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +3 -3
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +10 -9
- package/dest/public/hinting_db_sources.d.ts +19 -0
- package/dest/public/hinting_db_sources.d.ts.map +1 -0
- package/dest/public/hinting_db_sources.js +36 -0
- package/dest/public/public_db_sources.d.ts +45 -21
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +79 -24
- package/dest/public/public_processor/public_processor.d.ts +5 -5
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +21 -20
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +9 -14
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +15 -19
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +9 -6
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +28 -14
- package/dest/public/side_effect_trace.d.ts +6 -22
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +11 -70
- package/dest/public/side_effect_trace_interface.d.ts +5 -19
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/common/db_interfaces.ts +26 -5
- package/src/common/debug_fn_name.ts +2 -2
- package/src/private/acvm/deserialize.ts +33 -0
- package/src/private/acvm/oracle/oracle.ts +37 -3
- package/src/private/acvm/oracle/typed_oracle.ts +5 -1
- package/src/private/acvm/serialize.ts +28 -0
- package/src/private/execution_data_provider.ts +13 -4
- package/src/private/private_execution_oracle.ts +5 -1
- package/src/private/unconstrained_execution_oracle.ts +12 -3
- package/src/public/avm/fixtures/avm_simulation_tester.ts +8 -5
- package/src/public/avm/fixtures/index.ts +38 -24
- package/src/public/avm/fixtures/simple_contract_data_source.ts +1 -10
- package/src/public/avm/journal/journal.ts +119 -353
- package/src/public/avm/journal/nullifiers.ts +2 -2
- package/src/public/avm/journal/public_storage.ts +2 -2
- package/src/public/avm/test_utils.ts +20 -29
- package/src/public/fixtures/public_tx_simulation_tester.ts +9 -12
- package/src/public/hinting_db_sources.ts +71 -0
- package/src/public/public_db_sources.ts +131 -29
- package/src/public/public_processor/public_processor.ts +22 -21
- package/src/public/public_tx_simulator/public_tx_context.ts +30 -38
- package/src/public/public_tx_simulator/public_tx_simulator.ts +47 -17
- package/src/public/side_effect_trace.ts +8 -172
- package/src/public/side_effect_trace_interface.ts +4 -55
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/simulator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.81.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dest/server.js",
|
|
@@ -59,16 +59,16 @@
|
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@aztec/constants": "0.
|
|
63
|
-
"@aztec/foundation": "0.
|
|
64
|
-
"@aztec/noir-acvm_js": "0.
|
|
65
|
-
"@aztec/noir-noirc_abi": "0.
|
|
66
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
67
|
-
"@aztec/noir-types": "0.
|
|
68
|
-
"@aztec/protocol-contracts": "0.
|
|
69
|
-
"@aztec/stdlib": "0.
|
|
70
|
-
"@aztec/telemetry-client": "0.
|
|
71
|
-
"@aztec/world-state": "0.
|
|
62
|
+
"@aztec/constants": "0.81.0",
|
|
63
|
+
"@aztec/foundation": "0.81.0",
|
|
64
|
+
"@aztec/noir-acvm_js": "0.81.0",
|
|
65
|
+
"@aztec/noir-noirc_abi": "0.81.0",
|
|
66
|
+
"@aztec/noir-protocol-circuits-types": "0.81.0",
|
|
67
|
+
"@aztec/noir-types": "0.81.0",
|
|
68
|
+
"@aztec/protocol-contracts": "0.81.0",
|
|
69
|
+
"@aztec/stdlib": "0.81.0",
|
|
70
|
+
"@aztec/telemetry-client": "0.81.0",
|
|
71
|
+
"@aztec/world-state": "0.81.0",
|
|
72
72
|
"levelup": "^5.1.1",
|
|
73
73
|
"lodash.clonedeep": "^4.5.0",
|
|
74
74
|
"lodash.merge": "^4.6.2",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"tslib": "^2.4.0"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@aztec/kv-store": "0.
|
|
80
|
-
"@aztec/merkle-tree": "0.
|
|
81
|
-
"@aztec/noir-contracts.js": "0.
|
|
79
|
+
"@aztec/kv-store": "0.81.0",
|
|
80
|
+
"@aztec/merkle-tree": "0.81.0",
|
|
81
|
+
"@aztec/noir-contracts.js": "0.81.0",
|
|
82
82
|
"@jest/globals": "^29.5.0",
|
|
83
83
|
"@types/jest": "^29.5.0",
|
|
84
84
|
"@types/levelup": "^5.1.3",
|
|
@@ -2,7 +2,7 @@ import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
|
2
2
|
import type { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
5
|
+
import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
6
6
|
import type { NullifierMembershipWitness } from '@aztec/stdlib/trees';
|
|
7
7
|
|
|
8
8
|
import type { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
|
|
@@ -10,7 +10,7 @@ import type { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
|
|
|
10
10
|
/**
|
|
11
11
|
* Database interface for providing access to public state.
|
|
12
12
|
*/
|
|
13
|
-
export interface
|
|
13
|
+
export interface PublicStateDBInterface {
|
|
14
14
|
/**
|
|
15
15
|
* Reads a value from public storage, returning zero if none.
|
|
16
16
|
* @param contract - Owner of the storage.
|
|
@@ -31,19 +31,40 @@ export interface PublicStateDB {
|
|
|
31
31
|
/**
|
|
32
32
|
* Database interface for providing access to public contract data.
|
|
33
33
|
*/
|
|
34
|
-
export interface
|
|
34
|
+
export interface PublicContractsDBInterface {
|
|
35
35
|
/**
|
|
36
36
|
* Returns a publicly deployed contract instance.
|
|
37
37
|
* @param address - Address of the contract.
|
|
38
|
+
* @param blockNumber - The block number at which to retrieve the contract instance.
|
|
38
39
|
* @returns The contract instance or undefined if not found.
|
|
39
40
|
*/
|
|
40
|
-
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;
|
|
41
|
+
getContractInstance(address: AztecAddress, blockNumber: number): Promise<ContractInstanceWithAddress | undefined>;
|
|
41
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Returns a publicly deployed contract class.
|
|
45
|
+
* @param contractClassId - ID of the contract class.
|
|
46
|
+
* @returns The contract class or undefined if not found
|
|
47
|
+
*/
|
|
48
|
+
getContractClass(contractClassId: Fr): Promise<ContractClassPublic | undefined>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Returns the commitment to the bytecode of a contract class.
|
|
52
|
+
* @param contractClassId - ID of the contract class.
|
|
53
|
+
* @returns The commitment to the bytecode or undefined if not found.
|
|
54
|
+
*/
|
|
55
|
+
getBytecodeCommitment(contractClassId: Fr): Promise<Fr | undefined>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Returns the function name of a contract's function given its selector.
|
|
59
|
+
* @param contractAddress - Address of the contract.
|
|
60
|
+
* @param selector - Selector of the function.
|
|
61
|
+
* @returns The name of the function or undefined if not found.
|
|
62
|
+
*/
|
|
42
63
|
getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
|
|
43
64
|
}
|
|
44
65
|
|
|
45
66
|
/** Database interface for providing access to commitment tree, l1 to l2 message tree, and nullifier tree. */
|
|
46
|
-
export interface
|
|
67
|
+
export interface CommitmentsDBInterface {
|
|
47
68
|
/**
|
|
48
69
|
* Fetches a message from the db, given its key.
|
|
49
70
|
* @param contractAddress - Address of a contract by which the message was emitted.
|
|
@@ -2,10 +2,10 @@ import type { Fr } from '@aztec/foundation/fields';
|
|
|
2
2
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { PublicContractsDBInterface } from './db_interfaces.js';
|
|
6
6
|
|
|
7
7
|
export async function getPublicFunctionDebugName(
|
|
8
|
-
db:
|
|
8
|
+
db: PublicContractsDBInterface,
|
|
9
9
|
contractAddress: AztecAddress,
|
|
10
10
|
calldata: Fr[],
|
|
11
11
|
): Promise<string> {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { hexToBuffer } from '@aztec/foundation/string';
|
|
2
3
|
|
|
3
4
|
import type { ACVMField, ACVMWitness } from './acvm_types.js';
|
|
4
5
|
|
|
@@ -41,6 +42,24 @@ export function fromBoundedVec(storage: ACVMField[], length: ACVMField): Fr[] {
|
|
|
41
42
|
return storage.slice(0, frToNumber(fromACVMField(length))).map(fromACVMField);
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Converts a Noir BoundedVec of unsigned integers into a Buffer. Note that BoundedVecs are structs, and therefore
|
|
47
|
+
* translated as two separate ACVMField values (an array and a single field).
|
|
48
|
+
*
|
|
49
|
+
* @param storage The array with the BoundedVec's storage (i.e. BoundedVec::storage())
|
|
50
|
+
* @param length The length of the BoundedVec (i.e. BoundedVec::len())
|
|
51
|
+
* @param uintBitSize If it's an array of Noir u8's, put `8`, etc.
|
|
52
|
+
* @returns A buffer containing the unsigned integers tightly packed
|
|
53
|
+
*/
|
|
54
|
+
export function fromUintBoundedVec(storage: ACVMField[], length: ACVMField, uintBitSize: number): Buffer {
|
|
55
|
+
if (uintBitSize % 8 !== 0) {
|
|
56
|
+
throw new Error(`u${uintBitSize} is not a supported type in Noir`);
|
|
57
|
+
}
|
|
58
|
+
const uintByteSize = uintBitSize / 8;
|
|
59
|
+
const boundedStorage = storage.slice(0, frToNumber(fromACVMField(length)));
|
|
60
|
+
return Buffer.concat(boundedStorage.map(str => hexToBuffer(str).subarray(-uintByteSize)));
|
|
61
|
+
}
|
|
62
|
+
|
|
44
63
|
/**
|
|
45
64
|
* Transforms a witness map to its field elements.
|
|
46
65
|
* @param witness - The witness to extract from.
|
|
@@ -50,3 +69,17 @@ export function witnessMapToFields(witness: ACVMWitness): Fr[] {
|
|
|
50
69
|
const sortedKeys = [...witness.keys()].sort((a, b) => a - b);
|
|
51
70
|
return sortedKeys.map(key => witness.get(key)!).map(fromACVMField);
|
|
52
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Converts an array of Noir unsigned integers to a single tightly-packed buffer.
|
|
75
|
+
* @param uintBitSize If it's an array of Noir u8's, put `8`, etc.
|
|
76
|
+
* @returns A buffer where each byte is correctly represented as a single byte in the buffer.
|
|
77
|
+
* Copy of the function in txe/src/util/encoding.ts.
|
|
78
|
+
*/
|
|
79
|
+
export function fromUintArray(obj: ACVMField[], uintBitSize: number): Buffer {
|
|
80
|
+
if (uintBitSize % 8 !== 0) {
|
|
81
|
+
throw new Error(`u${uintBitSize} is not a supported type in Noir`);
|
|
82
|
+
}
|
|
83
|
+
const uintByteSize = uintBitSize / 8;
|
|
84
|
+
return Buffer.concat(obj.map(str => hexToBuffer(str).slice(-uintByteSize)));
|
|
85
|
+
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import { Fr, Point } from '@aztec/foundation/fields';
|
|
2
2
|
import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
3
3
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
4
|
import { ContractClassLog, LogWithTxData } from '@aztec/stdlib/logs';
|
|
5
5
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
6
6
|
|
|
7
7
|
import type { ACVMField } from '../acvm_types.js';
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
frToBoolean,
|
|
10
|
+
frToNumber,
|
|
11
|
+
fromACVMField,
|
|
12
|
+
fromBoundedVec,
|
|
13
|
+
fromUintArray,
|
|
14
|
+
fromUintBoundedVec,
|
|
15
|
+
} from '../deserialize.js';
|
|
16
|
+
import { bufferToBoundedVec, toACVMField, toACVMFieldSingleOrArray } from '../serialize.js';
|
|
10
17
|
import type { TypedOracle } from './typed_oracle.js';
|
|
11
18
|
|
|
12
19
|
/**
|
|
@@ -452,4 +459,31 @@ export class Oracle {
|
|
|
452
459
|
frToNumber(fromACVMField(numEntries)),
|
|
453
460
|
);
|
|
454
461
|
}
|
|
462
|
+
|
|
463
|
+
async aes128Decrypt(
|
|
464
|
+
ciphertextBVecStorage: ACVMField[],
|
|
465
|
+
[ciphertextLength]: ACVMField[],
|
|
466
|
+
iv: ACVMField[],
|
|
467
|
+
symKey: ACVMField[],
|
|
468
|
+
): Promise<(ACVMField | ACVMField[])[]> {
|
|
469
|
+
const ciphertext = fromUintBoundedVec(ciphertextBVecStorage, ciphertextLength, 8);
|
|
470
|
+
const ivBuffer = fromUintArray(iv, 8);
|
|
471
|
+
const symKeyBuffer = fromUintArray(symKey, 8);
|
|
472
|
+
|
|
473
|
+
const plaintext = await this.typedOracle.aes128Decrypt(ciphertext, ivBuffer, symKeyBuffer);
|
|
474
|
+
return bufferToBoundedVec(plaintext, ciphertextBVecStorage.length);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
async getSharedSecret(
|
|
478
|
+
[address]: ACVMField[],
|
|
479
|
+
[ephPKField0]: ACVMField[],
|
|
480
|
+
[ephPKField1]: ACVMField[],
|
|
481
|
+
[ephPKField2]: ACVMField[],
|
|
482
|
+
): Promise<ACVMField[]> {
|
|
483
|
+
const secret = await this.typedOracle.getSharedSecret(
|
|
484
|
+
AztecAddress.fromField(fromACVMField(address)),
|
|
485
|
+
Point.fromFields([ephPKField0, ephPKField1, ephPKField2].map(fromACVMField)),
|
|
486
|
+
);
|
|
487
|
+
return secret.toFields().map(toACVMField);
|
|
488
|
+
}
|
|
455
489
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { Fr, Point } from '@aztec/foundation/fields';
|
|
3
3
|
import type { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
@@ -256,4 +256,8 @@ export abstract class TypedOracle {
|
|
|
256
256
|
aes128Decrypt(_ciphertext: Buffer, _iv: Buffer, _symKey: Buffer): Promise<Buffer> {
|
|
257
257
|
return Promise.reject(new OracleMethodNotAvailableError('aes128Decrypt'));
|
|
258
258
|
}
|
|
259
|
+
|
|
260
|
+
getSharedSecret(_address: AztecAddress, _ephPk: Point): Promise<Point> {
|
|
261
|
+
return Promise.reject(new OracleMethodNotAvailableError('getSharedSecret'));
|
|
262
|
+
}
|
|
259
263
|
}
|
|
@@ -58,3 +58,31 @@ export function toACVMWitness(witnessStartIndex: number, fields: Parameters<type
|
|
|
58
58
|
return witness;
|
|
59
59
|
}, new Map<number, ACVMField>());
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
export function bufferToU8Array(buffer: Buffer): ACVMField[] {
|
|
63
|
+
return Array.from(buffer).map(byte => toACVMField(BigInt(byte)));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function bufferToBoundedVec(buffer: Buffer, maxLen: number): [ACVMField[], ACVMField] {
|
|
67
|
+
const u8Array = bufferToU8Array(buffer);
|
|
68
|
+
return arrayToBoundedVec(u8Array, maxLen);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Converts a ForeignCallArray into a tuple which represents a nr BoundedVec.
|
|
73
|
+
* If the input array is shorter than the maxLen, it pads the result with zeros,
|
|
74
|
+
* so that nr can correctly coerce this result into a BoundedVec.
|
|
75
|
+
* @param bVecStorage - The array underlying the BoundedVec.
|
|
76
|
+
* @param maxLen - the max length of the BoundedVec.
|
|
77
|
+
* @returns a tuple representing a BoundedVec.
|
|
78
|
+
*/
|
|
79
|
+
export function arrayToBoundedVec(bVecStorage: ACVMField[], maxLen: number): [ACVMField[], ACVMField] {
|
|
80
|
+
if (bVecStorage.length > maxLen) {
|
|
81
|
+
throw new Error(`Array of length ${bVecStorage.length} larger than maxLen ${maxLen}`);
|
|
82
|
+
}
|
|
83
|
+
const lengthDiff = maxLen - bVecStorage.length;
|
|
84
|
+
const zeroPaddingArray = Array(lengthDiff).fill(toACVMField(BigInt(0)));
|
|
85
|
+
const storage = bVecStorage.concat(zeroPaddingArray);
|
|
86
|
+
const len = toACVMField(BigInt(bVecStorage.length));
|
|
87
|
+
return [storage, len];
|
|
88
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import type { Fr, Point } from '@aztec/foundation/fields';
|
|
2
2
|
import type { FunctionArtifact, FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
4
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
@@ -9,7 +9,7 @@ import type { NoteStatus } from '@aztec/stdlib/note';
|
|
|
9
9
|
import { type MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
10
10
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
11
11
|
|
|
12
|
-
import type {
|
|
12
|
+
import type { CommitmentsDBInterface } from '../common/db_interfaces.js';
|
|
13
13
|
import type { NoteData } from './acvm/index.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -33,7 +33,7 @@ export class ContractClassNotFoundError extends Error {
|
|
|
33
33
|
/**
|
|
34
34
|
* The interface for the data layer required to perform private and unconstrained execution.
|
|
35
35
|
*/
|
|
36
|
-
export interface ExecutionDataProvider extends
|
|
36
|
+
export interface ExecutionDataProvider extends CommitmentsDBInterface {
|
|
37
37
|
/**
|
|
38
38
|
* Returns a contract instance associated with an address, if available.
|
|
39
39
|
* @param address - Address.
|
|
@@ -239,10 +239,11 @@ export interface ExecutionDataProvider extends CommitmentsDB {
|
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
241
|
* Processes the tagged logs returned by syncTaggedLogs by decrypting them and storing them in the database.
|
|
242
|
+
* @param contractAddress - The address of the contract that emitted the logs.
|
|
242
243
|
* @param logs - The logs to process.
|
|
243
244
|
* @param recipient - The recipient of the logs.
|
|
244
245
|
*/
|
|
245
|
-
processTaggedLogs(logs: TxScopedL2Log[], recipient: AztecAddress): Promise<void>;
|
|
246
|
+
processTaggedLogs(contractAddress: AztecAddress, logs: TxScopedL2Log[], recipient: AztecAddress): Promise<void>;
|
|
246
247
|
|
|
247
248
|
/**
|
|
248
249
|
* Delivers the preimage and metadata of a committed note so that it can be later requested via the `getNotes`
|
|
@@ -320,4 +321,12 @@ export interface ExecutionDataProvider extends CommitmentsDB {
|
|
|
320
321
|
* @param numEntries - The number of entries to copy.
|
|
321
322
|
*/
|
|
322
323
|
copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void>;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Retrieves the shared secret for a given address and ephemeral public key.
|
|
327
|
+
* @param address - The address to get the secret for.
|
|
328
|
+
* @param ephPk - The ephemeral public key to get the secret for.
|
|
329
|
+
* @returns The secret for the given address.
|
|
330
|
+
*/
|
|
331
|
+
getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point>;
|
|
323
332
|
}
|
|
@@ -606,7 +606,11 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
606
606
|
this.scopes,
|
|
607
607
|
);
|
|
608
608
|
for (const [recipient, taggedLogs] of taggedLogsByRecipient.entries()) {
|
|
609
|
-
await this.executionDataProvider.processTaggedLogs(
|
|
609
|
+
await this.executionDataProvider.processTaggedLogs(
|
|
610
|
+
this.contractAddress,
|
|
611
|
+
taggedLogs,
|
|
612
|
+
AztecAddress.fromString(recipient),
|
|
613
|
+
);
|
|
610
614
|
}
|
|
611
615
|
|
|
612
616
|
await this.executionDataProvider.removeNullifiedNotes(this.contractAddress);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Aes128 } from '@aztec/foundation/crypto';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { Fr, Point } from '@aztec/foundation/fields';
|
|
3
3
|
import { applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
5
5
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -23,7 +23,7 @@ export class UnconstrainedExecutionOracle extends TypedOracle {
|
|
|
23
23
|
protected readonly contractAddress: AztecAddress,
|
|
24
24
|
/** List of transient auth witnesses to be used during this simulation */
|
|
25
25
|
protected readonly authWitnesses: AuthWitness[],
|
|
26
|
-
protected readonly capsules: Capsule[],
|
|
26
|
+
protected readonly capsules: Capsule[], // TODO(#12425): Rename to transientCapsules
|
|
27
27
|
protected readonly executionDataProvider: ExecutionDataProvider,
|
|
28
28
|
protected log = createLogger('simulator:client_view_context'),
|
|
29
29
|
protected readonly scopes?: AztecAddress[],
|
|
@@ -288,7 +288,11 @@ export class UnconstrainedExecutionOracle extends TypedOracle {
|
|
|
288
288
|
);
|
|
289
289
|
|
|
290
290
|
for (const [recipient, taggedLogs] of taggedLogsByRecipient.entries()) {
|
|
291
|
-
await this.executionDataProvider.processTaggedLogs(
|
|
291
|
+
await this.executionDataProvider.processTaggedLogs(
|
|
292
|
+
this.contractAddress,
|
|
293
|
+
taggedLogs,
|
|
294
|
+
AztecAddress.fromString(recipient),
|
|
295
|
+
);
|
|
292
296
|
}
|
|
293
297
|
|
|
294
298
|
await this.executionDataProvider.removeNullifiedNotes(this.contractAddress);
|
|
@@ -339,6 +343,7 @@ export class UnconstrainedExecutionOracle extends TypedOracle {
|
|
|
339
343
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
340
344
|
}
|
|
341
345
|
return (
|
|
346
|
+
// TODO(#12425): On the following line, the pertinent capsule gets overshadowed by the transient one. Tackle this.
|
|
342
347
|
this.capsules.find(c => c.contractAddress.equals(contractAddress) && c.storageSlot.equals(slot))?.data ??
|
|
343
348
|
(await this.executionDataProvider.loadCapsule(this.contractAddress, slot))
|
|
344
349
|
);
|
|
@@ -370,4 +375,8 @@ export class UnconstrainedExecutionOracle extends TypedOracle {
|
|
|
370
375
|
const aes128 = new Aes128();
|
|
371
376
|
return aes128.decryptBufferCBC(ciphertext, iv, symKey);
|
|
372
377
|
}
|
|
378
|
+
|
|
379
|
+
public override getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
|
|
380
|
+
return this.executionDataProvider.getSharedSecret(address, ephPk);
|
|
381
|
+
}
|
|
373
382
|
}
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
resolveContractAssertionMessage,
|
|
17
17
|
} from '../../avm/fixtures/index.js';
|
|
18
18
|
import { AvmPersistableStateManager } from '../../avm/journal/journal.js';
|
|
19
|
-
import {
|
|
19
|
+
import { DEFAULT_BLOCK_NUMBER } from '../../fixtures/public_tx_simulation_tester.js';
|
|
20
|
+
import { PublicContractsDB, PublicTreesDB } from '../../public_db_sources.js';
|
|
20
21
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
21
22
|
import { BaseAvmSimulationTester } from './base_avm_simulation_tester.js';
|
|
22
23
|
import { SimpleContractDataSource } from './simple_contract_data_source.js';
|
|
@@ -41,16 +42,18 @@ export class AvmSimulationTester extends BaseAvmSimulationTester {
|
|
|
41
42
|
static async create(): Promise<AvmSimulationTester> {
|
|
42
43
|
const contractDataSource = new SimpleContractDataSource();
|
|
43
44
|
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
|
|
44
|
-
const
|
|
45
|
+
const treesDB = new PublicTreesDB(merkleTrees);
|
|
46
|
+
const contractsDB = new PublicContractsDB(contractDataSource);
|
|
45
47
|
const trace = new SideEffectTrace();
|
|
46
48
|
const firstNullifier = new Fr(420000);
|
|
47
|
-
|
|
48
|
-
// failures on 2nd call to simulateCall with merkle ops on
|
|
49
|
+
|
|
49
50
|
const stateManager = AvmPersistableStateManager.create(
|
|
50
|
-
|
|
51
|
+
treesDB,
|
|
52
|
+
contractsDB,
|
|
51
53
|
trace,
|
|
52
54
|
/*doMerkleOperations=*/ false,
|
|
53
55
|
firstNullifier,
|
|
56
|
+
DEFAULT_BLOCK_NUMBER,
|
|
54
57
|
);
|
|
55
58
|
return new AvmSimulationTester(contractDataSource, merkleTrees, stateManager);
|
|
56
59
|
}
|
|
@@ -5,9 +5,15 @@ import {
|
|
|
5
5
|
} from '@aztec/constants';
|
|
6
6
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
7
|
import { Fr } from '@aztec/foundation/fields';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { AvmGadgetsTestContract } from '@aztec/noir-contracts.js/AvmGadgetsTest';
|
|
9
|
+
import { AvmTestContract } from '@aztec/noir-contracts.js/AvmTest';
|
|
10
|
+
import {
|
|
11
|
+
type ContractArtifact,
|
|
12
|
+
type FunctionAbi,
|
|
13
|
+
type FunctionArtifact,
|
|
14
|
+
FunctionSelector,
|
|
15
|
+
getAllFunctionAbis,
|
|
16
|
+
} from '@aztec/stdlib/abi';
|
|
11
17
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
18
|
import {
|
|
13
19
|
type ContractClassPublic,
|
|
@@ -17,7 +23,7 @@ import {
|
|
|
17
23
|
import { isNoirCallStackUnresolved } from '@aztec/stdlib/errors';
|
|
18
24
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
19
25
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
20
|
-
import
|
|
26
|
+
import { deriveKeys } from '@aztec/stdlib/keys';
|
|
21
27
|
import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/stdlib/testing';
|
|
22
28
|
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
23
29
|
|
|
@@ -26,7 +32,8 @@ import { mock } from 'jest-mock-extended';
|
|
|
26
32
|
import merge from 'lodash.merge';
|
|
27
33
|
|
|
28
34
|
import { resolveAssertionMessageFromRevertData, traverseCauseChain } from '../../../common/index.js';
|
|
29
|
-
import
|
|
35
|
+
import { DEFAULT_BLOCK_NUMBER } from '../../fixtures/public_tx_simulation_tester.js';
|
|
36
|
+
import type { PublicContractsDB, PublicTreesDB } from '../../public_db_sources.js';
|
|
30
37
|
import type { PublicSideEffectTraceInterface } from '../../side_effect_trace_interface.js';
|
|
31
38
|
import { AvmContext } from '../avm_context.js';
|
|
32
39
|
import { AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
@@ -59,23 +66,25 @@ export function initContext(overrides?: {
|
|
|
59
66
|
|
|
60
67
|
/** Creates an empty state manager with mocked host storage. */
|
|
61
68
|
export function initPersistableStateManager(overrides?: {
|
|
62
|
-
|
|
69
|
+
treesDB?: PublicTreesDB;
|
|
70
|
+
contractsDB?: PublicContractsDB;
|
|
63
71
|
trace?: PublicSideEffectTraceInterface;
|
|
64
72
|
publicStorage?: PublicStorage;
|
|
65
73
|
nullifiers?: NullifierManager;
|
|
66
74
|
doMerkleOperations?: boolean;
|
|
67
|
-
db?: MerkleTreeWriteOperations;
|
|
68
75
|
firstNullifier?: Fr;
|
|
76
|
+
blockNumber?: number;
|
|
69
77
|
}): AvmPersistableStateManager {
|
|
70
|
-
const
|
|
78
|
+
const treesDB = overrides?.treesDB || mock<PublicTreesDB>();
|
|
71
79
|
return new AvmPersistableStateManager(
|
|
72
|
-
|
|
80
|
+
treesDB,
|
|
81
|
+
overrides?.contractsDB || mock<PublicContractsDB>(),
|
|
73
82
|
overrides?.trace || mock<PublicSideEffectTraceInterface>(),
|
|
74
|
-
overrides?.publicStorage || new PublicStorage(worldStateDB),
|
|
75
|
-
overrides?.nullifiers || new NullifierManager(worldStateDB),
|
|
76
|
-
overrides?.doMerkleOperations || false,
|
|
77
|
-
overrides?.db || mock<MerkleTreeWriteOperations>(),
|
|
78
83
|
overrides?.firstNullifier || new Fr(27),
|
|
84
|
+
overrides?.blockNumber || DEFAULT_BLOCK_NUMBER,
|
|
85
|
+
overrides?.doMerkleOperations || false,
|
|
86
|
+
overrides?.publicStorage,
|
|
87
|
+
overrides?.nullifiers,
|
|
79
88
|
);
|
|
80
89
|
}
|
|
81
90
|
|
|
@@ -147,7 +156,7 @@ export function getFunctionSelector(
|
|
|
147
156
|
functionName: string,
|
|
148
157
|
contractArtifact: ContractArtifact,
|
|
149
158
|
): Promise<FunctionSelector> {
|
|
150
|
-
const fnArtifact = contractArtifact.
|
|
159
|
+
const fnArtifact = getAllFunctionAbis(contractArtifact).find(f => f.name === functionName)!;
|
|
151
160
|
assert(!!fnArtifact, `Function ${functionName} not found in ${contractArtifact.name}`);
|
|
152
161
|
const params = fnArtifact.parameters;
|
|
153
162
|
return FunctionSelector.fromNameAndParameters(fnArtifact.name, params);
|
|
@@ -156,10 +165,11 @@ export function getFunctionSelector(
|
|
|
156
165
|
export function getContractFunctionArtifact(
|
|
157
166
|
functionName: string,
|
|
158
167
|
contractArtifact: ContractArtifact,
|
|
159
|
-
): FunctionArtifact | undefined {
|
|
168
|
+
): FunctionArtifact | FunctionAbi | undefined {
|
|
160
169
|
const artifact = contractArtifact.functions.find(f => f.name === functionName)!;
|
|
161
170
|
if (!artifact) {
|
|
162
|
-
|
|
171
|
+
const abi = getAllFunctionAbis(contractArtifact).find(f => f.name === functionName);
|
|
172
|
+
return abi || undefined;
|
|
163
173
|
}
|
|
164
174
|
return artifact;
|
|
165
175
|
}
|
|
@@ -174,7 +184,7 @@ export function resolveContractAssertionMessage(
|
|
|
174
184
|
revertReason = cause as AvmRevertReason;
|
|
175
185
|
});
|
|
176
186
|
|
|
177
|
-
const functionArtifact = contractArtifact.
|
|
187
|
+
const functionArtifact = getAllFunctionAbis(contractArtifact).find(f => f.name === functionName);
|
|
178
188
|
if (!functionArtifact || !revertReason.noirCallStack || !isNoirCallStackUnresolved(revertReason.noirCallStack)) {
|
|
179
189
|
return undefined;
|
|
180
190
|
}
|
|
@@ -183,18 +193,18 @@ export function resolveContractAssertionMessage(
|
|
|
183
193
|
}
|
|
184
194
|
|
|
185
195
|
export function getAvmTestContractFunctionSelector(functionName: string): Promise<FunctionSelector> {
|
|
186
|
-
return getFunctionSelector(functionName,
|
|
196
|
+
return getFunctionSelector(functionName, AvmTestContract.artifactForPublic);
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
export function getAvmGadgetsTestContractFunctionSelector(functionName: string): Promise<FunctionSelector> {
|
|
190
|
-
const artifact =
|
|
200
|
+
const artifact = getAllFunctionAbis(AvmGadgetsTestContract.artifactForPublic).find(f => f.name === functionName)!;
|
|
191
201
|
assert(!!artifact, `Function ${functionName} not found in AvmGadgetsTestContractArtifact`);
|
|
192
202
|
const params = artifact.parameters;
|
|
193
203
|
return FunctionSelector.fromNameAndParameters(artifact.name, params);
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
export function getAvmTestContractArtifact(functionName: string): FunctionArtifact {
|
|
197
|
-
const artifact = getContractFunctionArtifact(functionName,
|
|
207
|
+
const artifact = getContractFunctionArtifact(functionName, AvmTestContract.artifactForPublic) as FunctionArtifact;
|
|
198
208
|
assert(
|
|
199
209
|
!!artifact?.bytecode,
|
|
200
210
|
`No bytecode found for function ${functionName}. Try re-running bootstrap.sh on the repository root.`,
|
|
@@ -203,7 +213,7 @@ export function getAvmTestContractArtifact(functionName: string): FunctionArtifa
|
|
|
203
213
|
}
|
|
204
214
|
|
|
205
215
|
export function getAvmGadgetsTestContractArtifact(functionName: string): FunctionArtifact {
|
|
206
|
-
const artifact =
|
|
216
|
+
const artifact = AvmGadgetsTestContract.artifactForPublic.functions.find(f => f.name === functionName)!;
|
|
207
217
|
assert(
|
|
208
218
|
!!artifact?.bytecode,
|
|
209
219
|
`No bytecode found for function ${functionName}. Try re-running bootstrap.sh on the repository root.`,
|
|
@@ -226,7 +236,7 @@ export function resolveAvmTestContractAssertionMessage(
|
|
|
226
236
|
revertReason: AvmRevertReason,
|
|
227
237
|
output: Fr[],
|
|
228
238
|
): string | undefined {
|
|
229
|
-
return resolveContractAssertionMessage(functionName, revertReason, output,
|
|
239
|
+
return resolveContractAssertionMessage(functionName, revertReason, output, AvmTestContract.artifactForPublic);
|
|
230
240
|
}
|
|
231
241
|
|
|
232
242
|
export function resolveAvmGadgetsTestContractAssertionMessage(
|
|
@@ -238,7 +248,7 @@ export function resolveAvmGadgetsTestContractAssertionMessage(
|
|
|
238
248
|
revertReason = cause as AvmRevertReason;
|
|
239
249
|
});
|
|
240
250
|
|
|
241
|
-
const functionArtifact =
|
|
251
|
+
const functionArtifact = AvmGadgetsTestContract.artifactForPublic.functions.find(f => f.name === functionName);
|
|
242
252
|
if (!functionArtifact || !revertReason.noirCallStack || !isNoirCallStackUnresolved(revertReason.noirCallStack)) {
|
|
243
253
|
return undefined;
|
|
244
254
|
}
|
|
@@ -267,24 +277,28 @@ export async function createContractClassAndInstance(
|
|
|
267
277
|
contractInstance: ContractInstanceWithAddress;
|
|
268
278
|
contractAddressNullifier: Fr;
|
|
269
279
|
}> {
|
|
270
|
-
const bytecode = getContractFunctionArtifact(PUBLIC_DISPATCH_FN_NAME, contractArtifact)
|
|
280
|
+
const bytecode = (getContractFunctionArtifact(PUBLIC_DISPATCH_FN_NAME, contractArtifact) as FunctionArtifact)!
|
|
281
|
+
.bytecode;
|
|
271
282
|
const contractClass = await makeContractClassPublic(
|
|
272
283
|
seed,
|
|
273
284
|
/*publicDispatchFunction=*/ { bytecode, selector: new FunctionSelector(PUBLIC_DISPATCH_SELECTOR) },
|
|
274
285
|
);
|
|
275
286
|
|
|
276
287
|
const constructorAbi = getContractFunctionArtifact('constructor', contractArtifact);
|
|
288
|
+
const { publicKeys } = await deriveKeys(Fr.random());
|
|
277
289
|
const initializationHash = await computeInitializationHash(constructorAbi, constructorArgs);
|
|
278
290
|
const contractInstance =
|
|
279
291
|
originalContractClassId === undefined
|
|
280
292
|
? await makeContractInstanceFromClassId(contractClass.id, seed, {
|
|
281
293
|
deployer,
|
|
282
294
|
initializationHash,
|
|
295
|
+
publicKeys,
|
|
283
296
|
})
|
|
284
297
|
: await makeContractInstanceFromClassId(originalContractClassId, seed, {
|
|
285
298
|
deployer,
|
|
286
299
|
initializationHash,
|
|
287
300
|
currentClassId: contractClass.id,
|
|
301
|
+
publicKeys,
|
|
288
302
|
});
|
|
289
303
|
|
|
290
304
|
const contractAddressNullifier = await siloNullifier(
|
|
@@ -2,12 +2,7 @@ import type { Fr } from '@aztec/foundation/fields';
|
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { type ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import type {
|
|
6
|
-
ContractClassPublic,
|
|
7
|
-
ContractDataSource,
|
|
8
|
-
ContractInstanceWithAddress,
|
|
9
|
-
PublicFunction,
|
|
10
|
-
} from '@aztec/stdlib/contract';
|
|
5
|
+
import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
11
6
|
|
|
12
7
|
import { PUBLIC_DISPATCH_FN_NAME } from './index.js';
|
|
13
8
|
|
|
@@ -50,10 +45,6 @@ export class SimpleContractDataSource implements ContractDataSource {
|
|
|
50
45
|
|
|
51
46
|
/////////////////////////////////////////////////////////////
|
|
52
47
|
// ContractDataSource function implementations
|
|
53
|
-
getPublicFunction(_address: AztecAddress, _selector: FunctionSelector): Promise<PublicFunction> {
|
|
54
|
-
throw new Error('Method not implemented.');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
48
|
getBlockNumber(): Promise<number> {
|
|
58
49
|
throw new Error('Method not implemented.');
|
|
59
50
|
}
|