@aztec/simulator 0.82.0 → 0.82.1
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/debug_fn_name.js +5 -2
- package/dest/private/acvm/oracle/oracle.d.ts +3 -3
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +9 -15
- package/dest/private/acvm/oracle/typed_oracle.d.ts +3 -3
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/typed_oracle.js +6 -6
- package/dest/private/hashed_values_cache.d.ts +2 -2
- package/dest/private/hashed_values_cache.d.ts.map +1 -1
- package/dest/private/hashed_values_cache.js +5 -15
- package/dest/private/private_execution.d.ts.map +1 -1
- package/dest/private/private_execution.js +1 -3
- package/dest/private/private_execution_oracle.d.ts +9 -37
- package/dest/private/private_execution_oracle.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.js +32 -92
- package/dest/private/simulator.d.ts.map +1 -1
- package/dest/private/simulator.js +12 -2
- package/dest/public/avm/fixtures/avm_simulation_tester.js +2 -2
- package/dest/public/avm/fixtures/index.d.ts +2 -1
- package/dest/public/avm/fixtures/index.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.js +7 -12
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +2 -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 +1 -1
- package/dest/public/avm/journal/journal.d.ts +2 -2
- package/dest/public/avm/journal/journal.d.ts.map +1 -1
- package/dest/public/avm/journal/journal.js +3 -3
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +2 -2
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +27 -47
- package/dest/public/fixtures/utils.d.ts +2 -2
- package/dest/public/fixtures/utils.d.ts.map +1 -1
- package/dest/public/fixtures/utils.js +18 -22
- package/dest/public/index.d.ts +1 -2
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -1
- package/dest/public/public_db_sources.js +1 -1
- package/dest/public/public_processor/public_processor.js +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +3 -10
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +4 -22
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +2 -3
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +20 -24
- package/dest/public/utils.d.ts +2 -4
- package/dest/public/utils.d.ts.map +1 -1
- package/dest/public/utils.js +4 -21
- package/package.json +14 -14
- package/src/common/debug_fn_name.ts +5 -5
- package/src/private/acvm/oracle/oracle.ts +13 -17
- package/src/private/acvm/oracle/typed_oracle.ts +10 -12
- package/src/private/hashed_values_cache.ts +6 -14
- package/src/private/private_execution.ts +0 -4
- package/src/private/private_execution_oracle.ts +39 -138
- package/src/private/simulator.ts +14 -2
- package/src/public/avm/fixtures/avm_simulation_tester.ts +2 -2
- package/src/public/avm/fixtures/index.ts +15 -17
- package/src/public/avm/fixtures/simple_contract_data_source.ts +2 -2
- package/src/public/avm/journal/journal.ts +6 -6
- package/src/public/fixtures/public_tx_simulation_tester.ts +31 -88
- package/src/public/fixtures/utils.ts +28 -26
- package/src/public/index.ts +1 -2
- package/src/public/public_db_sources.ts +1 -1
- package/src/public/public_processor/public_processor.ts +1 -1
- package/src/public/public_tx_simulator/public_tx_context.ts +12 -32
- package/src/public/public_tx_simulator/public_tx_simulator.ts +24 -30
- package/src/public/utils.ts +5 -21
- package/dest/public/execution.d.ts +0 -108
- package/dest/public/execution.d.ts.map +0 -1
- package/dest/public/execution.js +0 -9
- package/src/public/execution.ts +0 -140
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MAX_FR_ARGS_TO_ALL_ENQUEUED_CALLS,
|
|
3
|
-
PRIVATE_CONTEXT_INPUTS_LENGTH,
|
|
4
|
-
PUBLIC_DISPATCH_SELECTOR,
|
|
5
|
-
} from '@aztec/constants';
|
|
1
|
+
import { MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS, PRIVATE_CONTEXT_INPUTS_LENGTH } from '@aztec/constants';
|
|
6
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
7
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
4
|
import {
|
|
@@ -23,10 +19,8 @@ import {
|
|
|
23
19
|
CallContext,
|
|
24
20
|
Capsule,
|
|
25
21
|
CountedContractClassLog,
|
|
26
|
-
CountedPublicExecutionRequest,
|
|
27
22
|
NoteAndSlot,
|
|
28
23
|
PrivateCallExecutionResult,
|
|
29
|
-
PublicExecutionRequest,
|
|
30
24
|
type TxContext,
|
|
31
25
|
} from '@aztec/stdlib/tx';
|
|
32
26
|
|
|
@@ -64,8 +58,6 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
64
58
|
private noteHashNullifierCounterMap: Map<number, number> = new Map();
|
|
65
59
|
private contractClassLogs: CountedContractClassLog[] = [];
|
|
66
60
|
private nestedExecutions: PrivateCallExecutionResult[] = [];
|
|
67
|
-
private enqueuedPublicFunctionCalls: CountedPublicExecutionRequest[] = [];
|
|
68
|
-
private publicTeardownFunctionCall: PublicExecutionRequest = PublicExecutionRequest.empty();
|
|
69
61
|
|
|
70
62
|
constructor(
|
|
71
63
|
private readonly argsHash: Fr,
|
|
@@ -80,7 +72,7 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
80
72
|
private readonly noteCache: ExecutionNoteCache,
|
|
81
73
|
executionDataProvider: ExecutionDataProvider,
|
|
82
74
|
private provider: SimulationProvider,
|
|
83
|
-
private
|
|
75
|
+
private totalPublicCalldataCount: number,
|
|
84
76
|
protected sideEffectCounter: number = 0,
|
|
85
77
|
log = createLogger('simulator:client_execution_context'),
|
|
86
78
|
scopes?: AztecAddress[],
|
|
@@ -100,8 +92,8 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
100
92
|
|
|
101
93
|
const args = this.executionCache.getPreimage(this.argsHash);
|
|
102
94
|
|
|
103
|
-
if (args
|
|
104
|
-
throw new Error(`Invalid arguments size: expected ${argumentsSize}, got ${args
|
|
95
|
+
if (args?.length !== argumentsSize) {
|
|
96
|
+
throw new Error(`Invalid arguments size: expected ${argumentsSize}, got ${args?.length}`);
|
|
105
97
|
}
|
|
106
98
|
|
|
107
99
|
const privateContextInputs = new PrivateContextInputs(
|
|
@@ -152,27 +144,13 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
152
144
|
return this.nestedExecutions;
|
|
153
145
|
}
|
|
154
146
|
|
|
155
|
-
/**
|
|
156
|
-
* Return the enqueued public function calls during this execution.
|
|
157
|
-
*/
|
|
158
|
-
public getEnqueuedPublicFunctionCalls() {
|
|
159
|
-
return this.enqueuedPublicFunctionCalls;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Return the public teardown function call set during this execution.
|
|
164
|
-
*/
|
|
165
|
-
public getPublicTeardownFunctionCall() {
|
|
166
|
-
return this.publicTeardownFunctionCall;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
147
|
/**
|
|
170
148
|
* Store values in the execution cache.
|
|
171
149
|
* @param values - Values to store.
|
|
172
150
|
* @returns The hash of the values.
|
|
173
151
|
*/
|
|
174
|
-
public override storeInExecutionCache(values: Fr[]
|
|
175
|
-
return this.executionCache.store(values);
|
|
152
|
+
public override storeInExecutionCache(values: Fr[], hash: Fr) {
|
|
153
|
+
return this.executionCache.store(values, hash);
|
|
176
154
|
}
|
|
177
155
|
|
|
178
156
|
/**
|
|
@@ -181,7 +159,11 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
181
159
|
* @returns The values.
|
|
182
160
|
*/
|
|
183
161
|
public override loadFromExecutionCache(hash: Fr): Promise<Fr[]> {
|
|
184
|
-
|
|
162
|
+
const preimage = this.executionCache.getPreimage(hash);
|
|
163
|
+
if (!preimage) {
|
|
164
|
+
throw new Error(`Preimage for hash ${hash.toString()} not found in cache`);
|
|
165
|
+
}
|
|
166
|
+
return Promise.resolve(preimage);
|
|
185
167
|
}
|
|
186
168
|
|
|
187
169
|
/**
|
|
@@ -413,7 +395,7 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
413
395
|
this.noteCache,
|
|
414
396
|
this.executionDataProvider,
|
|
415
397
|
this.provider,
|
|
416
|
-
this.
|
|
398
|
+
this.totalPublicCalldataCount,
|
|
417
399
|
sideEffectCounter,
|
|
418
400
|
this.log,
|
|
419
401
|
this.scopes,
|
|
@@ -440,131 +422,50 @@ export class PrivateExecutionOracle extends UnconstrainedExecutionOracle {
|
|
|
440
422
|
};
|
|
441
423
|
}
|
|
442
424
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
449
|
-
* @param isStaticCall - Whether the call is a static call.
|
|
450
|
-
* @returns The public call stack item with the request information.
|
|
451
|
-
*/
|
|
452
|
-
protected async createPublicExecutionRequest(
|
|
453
|
-
callType: 'enqueued' | 'teardown',
|
|
454
|
-
targetContractAddress: AztecAddress,
|
|
455
|
-
functionSelector: FunctionSelector,
|
|
456
|
-
argsHash: Fr,
|
|
457
|
-
sideEffectCounter: number,
|
|
458
|
-
isStaticCall: boolean,
|
|
459
|
-
) {
|
|
460
|
-
const targetArtifact = await this.executionDataProvider.getFunctionArtifact(
|
|
461
|
-
targetContractAddress,
|
|
462
|
-
functionSelector,
|
|
463
|
-
);
|
|
464
|
-
const derivedCallContext = await this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall);
|
|
465
|
-
const args = this.executionCache.getPreimage(argsHash);
|
|
466
|
-
|
|
467
|
-
this.log.verbose(
|
|
468
|
-
`Created ${callType} public execution request to ${targetArtifact.name}@${targetContractAddress}`,
|
|
469
|
-
{
|
|
470
|
-
sideEffectCounter,
|
|
471
|
-
isStaticCall,
|
|
472
|
-
functionSelector,
|
|
473
|
-
targetContractAddress,
|
|
474
|
-
callType,
|
|
475
|
-
},
|
|
476
|
-
);
|
|
477
|
-
|
|
478
|
-
const request = PublicExecutionRequest.from({
|
|
479
|
-
args,
|
|
480
|
-
callContext: derivedCallContext,
|
|
481
|
-
});
|
|
425
|
+
#onNewPublicFunctionCall(calldataHash: Fr) {
|
|
426
|
+
const calldata = this.executionCache.getPreimage(calldataHash);
|
|
427
|
+
if (!calldata) {
|
|
428
|
+
throw new Error('Calldata for public call not found in cache');
|
|
429
|
+
}
|
|
482
430
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
this.publicTeardownFunctionCall = request;
|
|
431
|
+
this.totalPublicCalldataCount += calldata.length;
|
|
432
|
+
if (this.totalPublicCalldataCount > MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS) {
|
|
433
|
+
throw new Error(`Too many total args to all enqueued public calls! (> ${MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS})`);
|
|
487
434
|
}
|
|
488
435
|
}
|
|
489
436
|
|
|
490
437
|
/**
|
|
491
|
-
*
|
|
492
|
-
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
493
|
-
* of the execution are empty.
|
|
438
|
+
* Verify relevant information when a public function is enqueued.
|
|
494
439
|
* @param targetContractAddress - The address of the contract to call.
|
|
495
|
-
* @param
|
|
496
|
-
* @param argsHash - The arguments hash to pass to the function.
|
|
440
|
+
* @param calldataHash - The hash of the function selector and arguments.
|
|
497
441
|
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
498
442
|
* @param isStaticCall - Whether the call is a static call.
|
|
499
|
-
* @returns The public call stack item with the request information.
|
|
500
443
|
*/
|
|
501
|
-
public override
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
// WARNING: This is insecure and should be temporary!
|
|
510
|
-
// The oracle re-hashes the arguments and returns a new args_hash.
|
|
511
|
-
// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
|
|
512
|
-
// We don't validate or compute it in the circuit because a) it's harder to do with slices, and
|
|
513
|
-
// b) this is only temporary.
|
|
514
|
-
const newArgs = [functionSelector.toField(), ...this.executionCache.getPreimage(argsHash)];
|
|
515
|
-
const newArgsHash = await this.executionCache.store(newArgs);
|
|
516
|
-
await this.createPublicExecutionRequest(
|
|
517
|
-
'enqueued',
|
|
518
|
-
targetContractAddress,
|
|
519
|
-
FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
|
|
520
|
-
newArgsHash,
|
|
521
|
-
sideEffectCounter,
|
|
522
|
-
isStaticCall,
|
|
523
|
-
);
|
|
524
|
-
this.totalPublicArgsCount += newArgs.length;
|
|
525
|
-
if (this.totalPublicArgsCount > MAX_FR_ARGS_TO_ALL_ENQUEUED_CALLS) {
|
|
526
|
-
throw new Error(`Too many total args to all enqueued public calls! (> ${MAX_FR_ARGS_TO_ALL_ENQUEUED_CALLS})`);
|
|
527
|
-
}
|
|
528
|
-
return newArgsHash;
|
|
444
|
+
public override notifyEnqueuedPublicFunctionCall(
|
|
445
|
+
_targetContractAddress: AztecAddress,
|
|
446
|
+
calldataHash: Fr,
|
|
447
|
+
_sideEffectCounter: number,
|
|
448
|
+
_isStaticCall: boolean,
|
|
449
|
+
) {
|
|
450
|
+
this.#onNewPublicFunctionCall(calldataHash);
|
|
451
|
+
return Promise.resolve();
|
|
529
452
|
}
|
|
530
453
|
|
|
531
454
|
/**
|
|
532
|
-
*
|
|
533
|
-
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
534
|
-
* of the execution are empty.
|
|
455
|
+
* Verify relevant information when a public teardown function is set.
|
|
535
456
|
* @param targetContractAddress - The address of the contract to call.
|
|
536
|
-
* @param functionSelector - The function selector of the function to call.
|
|
537
457
|
* @param argsHash - The arguments hash to pass to the function.
|
|
538
458
|
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
539
459
|
* @param isStaticCall - Whether the call is a static call.
|
|
540
|
-
* @returns The public call stack item with the request information.
|
|
541
460
|
*/
|
|
542
|
-
public override
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
// WARNING: This is insecure and should be temporary!
|
|
551
|
-
// The oracle rehashes the arguments and returns a new args_hash.
|
|
552
|
-
// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
|
|
553
|
-
// We don't validate or compute it in the circuit because a) it's harder to do with slices, and
|
|
554
|
-
// b) this is only temporary.
|
|
555
|
-
const newArgsHash = await this.executionCache.store([
|
|
556
|
-
functionSelector.toField(),
|
|
557
|
-
...this.executionCache.getPreimage(argsHash),
|
|
558
|
-
]);
|
|
559
|
-
await this.createPublicExecutionRequest(
|
|
560
|
-
'teardown',
|
|
561
|
-
targetContractAddress,
|
|
562
|
-
FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
|
|
563
|
-
newArgsHash,
|
|
564
|
-
sideEffectCounter,
|
|
565
|
-
isStaticCall,
|
|
566
|
-
);
|
|
567
|
-
return newArgsHash;
|
|
461
|
+
public override notifySetPublicTeardownFunctionCall(
|
|
462
|
+
_targetContractAddress: AztecAddress,
|
|
463
|
+
calldataHash: Fr,
|
|
464
|
+
_sideEffectCounter: number,
|
|
465
|
+
_isStaticCall: boolean,
|
|
466
|
+
) {
|
|
467
|
+
this.#onNewPublicFunctionCall(calldataHash);
|
|
468
|
+
return Promise.resolve();
|
|
568
469
|
}
|
|
569
470
|
|
|
570
471
|
public override notifySetMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter: number): Promise<void> {
|
package/src/private/simulator.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { AbiDecoded, FunctionCall } from '@aztec/stdlib/abi';
|
|
|
4
4
|
import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
5
5
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
6
6
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
-
import { CallContext, PrivateExecutionResult, TxExecutionRequest } from '@aztec/stdlib/tx';
|
|
7
|
+
import { CallContext, HashedValues, PrivateExecutionResult, TxExecutionRequest, collectNested } from '@aztec/stdlib/tx';
|
|
8
8
|
|
|
9
9
|
import { createSimulationError } from '../common/errors.js';
|
|
10
10
|
import type { ExecutionDataProvider } from './execution_data_provider.js';
|
|
@@ -97,7 +97,19 @@ export class AcirSimulator {
|
|
|
97
97
|
);
|
|
98
98
|
const { usedTxRequestHashForNonces } = noteCache.finish();
|
|
99
99
|
const firstNullifierHint = usedTxRequestHashForNonces ? Fr.ZERO : noteCache.getAllNullifiers()[0];
|
|
100
|
-
|
|
100
|
+
|
|
101
|
+
const publicCallRequests = collectNested([executionResult], r => [
|
|
102
|
+
...r.publicInputs.publicCallRequests.map(r => r.inner),
|
|
103
|
+
r.publicInputs.publicTeardownCallRequest,
|
|
104
|
+
]).filter(r => !r.isEmpty());
|
|
105
|
+
const publicFunctionsCalldata = await Promise.all(
|
|
106
|
+
publicCallRequests.map(async r => {
|
|
107
|
+
const calldata = await context.loadFromExecutionCache(r.calldataHash);
|
|
108
|
+
return new HashedValues(calldata, r.calldataHash);
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
return new PrivateExecutionResult(executionResult, firstNullifierHint, publicFunctionsCalldata);
|
|
101
113
|
} catch (err) {
|
|
102
114
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
103
115
|
}
|
|
@@ -9,7 +9,7 @@ import { NativeWorldStateService } from '@aztec/world-state';
|
|
|
9
9
|
import { SideEffectTrace } from '../../../public/side_effect_trace.js';
|
|
10
10
|
import type { AvmContractCallResult } from '../../avm/avm_contract_call_result.js';
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
getContractFunctionAbi,
|
|
13
13
|
getFunctionSelector,
|
|
14
14
|
initContext,
|
|
15
15
|
initExecutionEnvironment,
|
|
@@ -73,7 +73,7 @@ export class AvmSimulationTester extends BaseAvmSimulationTester {
|
|
|
73
73
|
throw new Error(`Contract not found at address: ${address}`);
|
|
74
74
|
}
|
|
75
75
|
const fnSelector = await getFunctionSelector(fnName, contractArtifact);
|
|
76
|
-
const fnAbi =
|
|
76
|
+
const fnAbi = getContractFunctionAbi(fnName, contractArtifact);
|
|
77
77
|
const encodedArgs = encodeArguments(fnAbi!, args);
|
|
78
78
|
const calldata = [fnSelector.toField(), ...encodedArgs];
|
|
79
79
|
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEPLOYER_CONTRACT_ADDRESS,
|
|
3
|
-
MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
|
|
4
|
-
PUBLIC_DISPATCH_SELECTOR,
|
|
5
|
-
} from '@aztec/constants';
|
|
1
|
+
import { DEPLOYER_CONTRACT_ADDRESS, MAX_L2_GAS_PER_TX_PUBLIC_PORTION } from '@aztec/constants';
|
|
6
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
8
4
|
import { AvmGadgetsTestContract } from '@aztec/noir-contracts.js/AvmGadgetsTest';
|
|
@@ -165,13 +161,18 @@ export function getFunctionSelector(
|
|
|
165
161
|
export function getContractFunctionArtifact(
|
|
166
162
|
functionName: string,
|
|
167
163
|
contractArtifact: ContractArtifact,
|
|
168
|
-
): FunctionArtifact |
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
164
|
+
): FunctionArtifact | undefined {
|
|
165
|
+
return contractArtifact.functions.find(f => f.name === functionName);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function getContractFunctionAbi(
|
|
169
|
+
functionName: string,
|
|
170
|
+
contractArtifact: ContractArtifact,
|
|
171
|
+
): FunctionAbi | undefined {
|
|
172
|
+
return (
|
|
173
|
+
contractArtifact.functions.find(f => f.name === functionName) ??
|
|
174
|
+
contractArtifact.nonDispatchPublicFunctions.find(f => f.name === functionName)
|
|
175
|
+
);
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
export function resolveContractAssertionMessage(
|
|
@@ -279,12 +280,9 @@ export async function createContractClassAndInstance(
|
|
|
279
280
|
}> {
|
|
280
281
|
const bytecode = (getContractFunctionArtifact(PUBLIC_DISPATCH_FN_NAME, contractArtifact) as FunctionArtifact)!
|
|
281
282
|
.bytecode;
|
|
282
|
-
const contractClass = await makeContractClassPublic(
|
|
283
|
-
seed,
|
|
284
|
-
/*publicDispatchFunction=*/ { bytecode, selector: new FunctionSelector(PUBLIC_DISPATCH_SELECTOR) },
|
|
285
|
-
);
|
|
283
|
+
const contractClass = await makeContractClassPublic(seed, bytecode);
|
|
286
284
|
|
|
287
|
-
const constructorAbi =
|
|
285
|
+
const constructorAbi = getContractFunctionAbi('constructor', contractArtifact);
|
|
288
286
|
const { publicKeys } = await deriveKeys(Fr.random());
|
|
289
287
|
const initializationHash = await computeInitializationHash(constructorAbi, constructorArgs);
|
|
290
288
|
const contractInstance =
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import {
|
|
3
|
+
import type { ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
6
6
|
|
|
@@ -76,7 +76,7 @@ export class SimpleContractDataSource implements ContractDataSource {
|
|
|
76
76
|
return Promise.resolve(this.contractArtifacts.get(contractInstance!.currentContractClassId.toString()));
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
getDebugFunctionName(_address: AztecAddress, _selector: FunctionSelector): Promise<string> {
|
|
80
80
|
return Promise.resolve(PUBLIC_DISPATCH_FN_NAME);
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -13,8 +13,8 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
13
13
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
14
14
|
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
15
15
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
16
|
+
import type { ContractClassPublicWithCommitment, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
16
17
|
import { SerializableContractInstance } from '@aztec/stdlib/contract';
|
|
17
|
-
import type { ContractClassWithCommitment, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
18
18
|
import {
|
|
19
19
|
computeNoteHashNonce,
|
|
20
20
|
computePublicDataTreeLeafSlot,
|
|
@@ -439,11 +439,11 @@ export class AvmPersistableStateManager {
|
|
|
439
439
|
* @param classId - class id to retrieve.
|
|
440
440
|
* @returns the contract class or undefined if it does not exist.
|
|
441
441
|
*/
|
|
442
|
-
public async getContractClass(classId: Fr): Promise<
|
|
442
|
+
public async getContractClass(classId: Fr): Promise<ContractClassPublicWithCommitment | undefined> {
|
|
443
443
|
this.log.trace(`Getting contract class for id ${classId}`);
|
|
444
|
-
const
|
|
445
|
-
const exists =
|
|
446
|
-
let extendedClass:
|
|
444
|
+
const contractClass = await this.contractsDB.getContractClass(classId);
|
|
445
|
+
const exists = contractClass !== undefined;
|
|
446
|
+
let extendedClass: ContractClassPublicWithCommitment | undefined = undefined;
|
|
447
447
|
|
|
448
448
|
// Note: We currently do not generate info to check the nullifier tree, because
|
|
449
449
|
// this is not needed for our use cases.
|
|
@@ -456,7 +456,7 @@ export class AvmPersistableStateManager {
|
|
|
456
456
|
`Bytecode commitment was not found in DB for contract class (${classId}). This should not happen!`,
|
|
457
457
|
);
|
|
458
458
|
extendedClass = {
|
|
459
|
-
...
|
|
459
|
+
...contractClass,
|
|
460
460
|
publicBytecodeCommitment: bytecodeCommitment,
|
|
461
461
|
};
|
|
462
462
|
} else {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { asyncMap } from '@aztec/foundation/async-map';
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { type ContractArtifact,
|
|
3
|
+
import { type ContractArtifact, encodeArguments } from '@aztec/stdlib/abi';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
6
6
|
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { PublicCallRequest } from '@aztec/stdlib/kernel';
|
|
8
|
+
import { GlobalVariables, PublicCallRequestWithCalldata, type Tx } from '@aztec/stdlib/tx';
|
|
9
9
|
import { NativeWorldStateService } from '@aztec/world-state';
|
|
10
10
|
|
|
11
11
|
import { BaseAvmSimulationTester } from '../avm/fixtures/base_avm_simulation_tester.js';
|
|
12
|
-
import {
|
|
12
|
+
import { getContractFunctionAbi, getFunctionSelector } from '../avm/fixtures/index.js';
|
|
13
13
|
import { SimpleContractDataSource } from '../avm/fixtures/simple_contract_data_source.js';
|
|
14
14
|
import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
|
|
15
15
|
import { type PublicTxResult, PublicTxSimulator } from '../public_tx_simulator/public_tx_simulator.js';
|
|
16
|
-
import { createTxForPublicCalls } from './
|
|
16
|
+
import { createTxForPublicCalls } from './utils.js';
|
|
17
17
|
|
|
18
18
|
const TIMESTAMP = new Fr(99833);
|
|
19
19
|
const DEFAULT_GAS_FEES = new GasFees(2, 3);
|
|
@@ -54,68 +54,13 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
|
54
54
|
/* need some unique first nullifier for note-nonce computations */
|
|
55
55
|
firstNullifier = new Fr(420000 + this.txCount++),
|
|
56
56
|
): Promise<Tx> {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (!contractArtifact) {
|
|
63
|
-
throw new Error(`Contract artifact not found for address: ${address}`);
|
|
64
|
-
}
|
|
65
|
-
const req = await executionRequestForCall(
|
|
66
|
-
contractArtifact,
|
|
67
|
-
sender,
|
|
68
|
-
address,
|
|
69
|
-
setupCalls[i].fnName,
|
|
70
|
-
setupCalls[i].args,
|
|
71
|
-
setupCalls[i].isStaticCall,
|
|
72
|
-
);
|
|
73
|
-
setupExecutionRequests.push(req);
|
|
74
|
-
}
|
|
75
|
-
const appExecutionRequests: PublicExecutionRequest[] = [];
|
|
76
|
-
for (let i = 0; i < appCalls.length; i++) {
|
|
77
|
-
const address = appCalls[i].address;
|
|
78
|
-
const contractArtifact =
|
|
79
|
-
appCalls[i].contractArtifact || (await this.contractDataSource.getContractArtifact(address));
|
|
80
|
-
if (!contractArtifact) {
|
|
81
|
-
throw new Error(`Contract artifact not found for address: ${address}`);
|
|
82
|
-
}
|
|
83
|
-
const req = await executionRequestForCall(
|
|
84
|
-
contractArtifact,
|
|
85
|
-
sender,
|
|
86
|
-
address,
|
|
87
|
-
appCalls[i].fnName,
|
|
88
|
-
appCalls[i].args,
|
|
89
|
-
appCalls[i].isStaticCall,
|
|
90
|
-
);
|
|
91
|
-
appExecutionRequests.push(req);
|
|
92
|
-
}
|
|
57
|
+
const setupCallRequests = await asyncMap(setupCalls, call => this.#createPubicCallRequestForCall(call, sender));
|
|
58
|
+
const appCallRequests = await asyncMap(appCalls, call => this.#createPubicCallRequestForCall(call, sender));
|
|
59
|
+
const teardownCallRequest = teardownCall
|
|
60
|
+
? await this.#createPubicCallRequestForCall(teardownCall, sender)
|
|
61
|
+
: undefined;
|
|
93
62
|
|
|
94
|
-
|
|
95
|
-
if (teardownCall) {
|
|
96
|
-
const address = teardownCall.address;
|
|
97
|
-
const contractArtifact =
|
|
98
|
-
teardownCall.contractArtifact || (await this.contractDataSource.getContractArtifact(address));
|
|
99
|
-
if (!contractArtifact) {
|
|
100
|
-
throw new Error(`Contract artifact not found for address: ${address}`);
|
|
101
|
-
}
|
|
102
|
-
teardownExecutionRequest = await executionRequestForCall(
|
|
103
|
-
contractArtifact,
|
|
104
|
-
sender,
|
|
105
|
-
address,
|
|
106
|
-
teardownCall.fnName,
|
|
107
|
-
teardownCall.args,
|
|
108
|
-
teardownCall.isStaticCall,
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return await createTxForPublicCalls(
|
|
113
|
-
firstNullifier,
|
|
114
|
-
setupExecutionRequests,
|
|
115
|
-
appExecutionRequests,
|
|
116
|
-
teardownExecutionRequest,
|
|
117
|
-
feePayer,
|
|
118
|
-
);
|
|
63
|
+
return createTxForPublicCalls(firstNullifier, setupCallRequests, appCallRequests, teardownCallRequest, feePayer);
|
|
119
64
|
}
|
|
120
65
|
|
|
121
66
|
public async simulateTx(
|
|
@@ -143,28 +88,26 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
|
143
88
|
|
|
144
89
|
return avmResult;
|
|
145
90
|
}
|
|
146
|
-
}
|
|
147
91
|
|
|
148
|
-
async
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
address,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return new PublicExecutionRequest(callContext, calldata);
|
|
92
|
+
async #createPubicCallRequestForCall(
|
|
93
|
+
call: TestEnqueuedCall,
|
|
94
|
+
sender: AztecAddress,
|
|
95
|
+
): Promise<PublicCallRequestWithCalldata> {
|
|
96
|
+
const address = call.address;
|
|
97
|
+
const contractArtifact = call.contractArtifact || (await this.contractDataSource.getContractArtifact(address));
|
|
98
|
+
if (!contractArtifact) {
|
|
99
|
+
throw new Error(`Contract artifact not found for address: ${address}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const fnSelector = await getFunctionSelector(call.fnName, contractArtifact);
|
|
103
|
+
const fnAbi = getContractFunctionAbi(call.fnName, contractArtifact)!;
|
|
104
|
+
const encodedArgs = encodeArguments(fnAbi, call.args);
|
|
105
|
+
const calldata = [fnSelector.toField(), ...encodedArgs];
|
|
106
|
+
const isStaticCall = call.isStaticCall ?? false;
|
|
107
|
+
const request = await PublicCallRequest.fromCalldata(sender, address, isStaticCall, calldata);
|
|
108
|
+
|
|
109
|
+
return new PublicCallRequestWithCalldata(request, calldata);
|
|
110
|
+
}
|
|
168
111
|
}
|
|
169
112
|
|
|
170
113
|
export function defaultGlobals() {
|
|
@@ -24,28 +24,33 @@ import {
|
|
|
24
24
|
countAccumulatedItems,
|
|
25
25
|
} from '@aztec/stdlib/kernel';
|
|
26
26
|
import { ContractClassLog, PrivateLog } from '@aztec/stdlib/logs';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
27
|
+
import { ClientIvcProof } from '@aztec/stdlib/proofs';
|
|
28
|
+
import {
|
|
29
|
+
BlockHeader,
|
|
30
|
+
HashedValues,
|
|
31
|
+
PublicCallRequestWithCalldata,
|
|
32
|
+
Tx,
|
|
33
|
+
TxConstantData,
|
|
34
|
+
TxContext,
|
|
35
|
+
} from '@aztec/stdlib/tx';
|
|
29
36
|
|
|
30
37
|
import { strict as assert } from 'assert';
|
|
31
38
|
|
|
32
39
|
/**
|
|
33
40
|
* Craft a carrier transaction for some public calls for simulation by PublicTxSimulator.
|
|
34
41
|
*/
|
|
35
|
-
export
|
|
42
|
+
export function createTxForPublicCalls(
|
|
36
43
|
firstNullifier: Fr,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
setupCallRequests: PublicCallRequestWithCalldata[],
|
|
45
|
+
appCallRequests: PublicCallRequestWithCalldata[],
|
|
46
|
+
teardownCallRequest?: PublicCallRequestWithCalldata,
|
|
40
47
|
feePayer = AztecAddress.zero(),
|
|
41
48
|
gasUsedByPrivate: Gas = Gas.empty(),
|
|
42
|
-
):
|
|
49
|
+
): Tx {
|
|
43
50
|
assert(
|
|
44
|
-
|
|
51
|
+
setupCallRequests.length > 0 || appCallRequests.length > 0 || teardownCallRequest !== undefined,
|
|
45
52
|
"Can't create public tx with no enqueued calls",
|
|
46
53
|
);
|
|
47
|
-
const setupCallRequests = await Promise.all(setupExecutionRequests.map(er => er.toCallRequest()));
|
|
48
|
-
const appCallRequests = await Promise.all(appExecutionRequests.map(er => er.toCallRequest()));
|
|
49
54
|
// use max limits
|
|
50
55
|
const gasLimits = new Gas(DEFAULT_GAS_LIMIT, MAX_L2_GAS_PER_TX_PUBLIC_PORTION);
|
|
51
56
|
|
|
@@ -55,17 +60,18 @@ export async function createTxForPublicCalls(
|
|
|
55
60
|
|
|
56
61
|
// We reverse order because the simulator expects it to be like a "stack" of calls to pop from
|
|
57
62
|
for (let i = setupCallRequests.length - 1; i >= 0; i--) {
|
|
58
|
-
forPublic.nonRevertibleAccumulatedData.publicCallRequests[i] =
|
|
63
|
+
forPublic.nonRevertibleAccumulatedData.publicCallRequests[setupCallRequests.length - i - 1] =
|
|
64
|
+
setupCallRequests[i].request;
|
|
59
65
|
}
|
|
60
66
|
for (let i = appCallRequests.length - 1; i >= 0; i--) {
|
|
61
|
-
forPublic.revertibleAccumulatedData.publicCallRequests[i] = appCallRequests[i];
|
|
67
|
+
forPublic.revertibleAccumulatedData.publicCallRequests[appCallRequests.length - i - 1] = appCallRequests[i].request;
|
|
62
68
|
}
|
|
63
|
-
if (
|
|
64
|
-
forPublic.publicTeardownCallRequest =
|
|
69
|
+
if (teardownCallRequest) {
|
|
70
|
+
forPublic.publicTeardownCallRequest = teardownCallRequest.request;
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
const maxFeesPerGas = feePayer.isZero() ? GasFees.empty() : new GasFees(10, 10);
|
|
68
|
-
const teardownGasLimits =
|
|
74
|
+
const teardownGasLimits = teardownCallRequest ? gasLimits : Gas.empty();
|
|
69
75
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, maxFeesPerGas, GasFees.empty());
|
|
70
76
|
const txContext = new TxContext(Fr.zero(), Fr.zero(), gasSettings);
|
|
71
77
|
const constantData = new TxConstantData(BlockHeader.empty(), txContext, Fr.zero(), Fr.zero());
|
|
@@ -77,18 +83,14 @@ export async function createTxForPublicCalls(
|
|
|
77
83
|
feePayer,
|
|
78
84
|
forPublic,
|
|
79
85
|
);
|
|
80
|
-
const tx = Tx.newWithTxData(txData, teardownExecutionRequest);
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
for (let i = setupExecutionRequests.length - 1; i >= 0; i--) {
|
|
88
|
-
tx.enqueuedPublicFunctionCalls.push(setupExecutionRequests[i]);
|
|
89
|
-
}
|
|
87
|
+
const calldata = [
|
|
88
|
+
...setupCallRequests,
|
|
89
|
+
...appCallRequests,
|
|
90
|
+
...(teardownCallRequest ? [teardownCallRequest] : []),
|
|
91
|
+
].map(r => new HashedValues(r.calldata, r.request.calldataHash));
|
|
90
92
|
|
|
91
|
-
return
|
|
93
|
+
return new Tx(txData, ClientIvcProof.empty(), [], calldata);
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
export function createTxForPrivateOnly(feePayer = AztecAddress.zero(), gasUsedByPrivate: Gas = new Gas(10, 10)): Tx {
|
|
@@ -110,7 +112,7 @@ export function createTxForPrivateOnly(feePayer = AztecAddress.zero(), gasUsedBy
|
|
|
110
112
|
/*forPublic=*/ undefined,
|
|
111
113
|
forRollup,
|
|
112
114
|
);
|
|
113
|
-
return Tx.
|
|
115
|
+
return new Tx(txData, ClientIvcProof.empty(), [], []);
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
export async function addNewContractClassToTx(
|