@aztec/pxe 0.0.1-commit.6230efd → 0.0.1-commit.64b6bbb
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/bin/check_oracle_version.js +1 -1
- package/dest/block_synchronizer/block_synchronizer.d.ts +13 -5
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +74 -20
- package/dest/config/index.d.ts +3 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +17 -0
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/benchmarked_node.d.ts +9 -0
- package/dest/contract_function_simulator/benchmarked_node.d.ts.map +1 -0
- package/dest/contract_function_simulator/benchmarked_node.js +77 -0
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +54 -33
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +96 -51
- package/dest/contract_function_simulator/execution_note_cache.d.ts +18 -9
- package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_note_cache.js +45 -28
- package/dest/contract_function_simulator/index.d.ts +2 -2
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +4 -3
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +6 -3
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +4 -10
- package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/utility_context.js +7 -18
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +17 -13
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +3 -1
- package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +6 -6
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.js +8 -8
- package/dest/contract_function_simulator/oracle/oracle.d.ts +12 -10
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +67 -44
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +2 -26
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.js +1 -37
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +43 -50
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +83 -54
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +66 -33
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +127 -108
- package/dest/contract_sync/contract_sync_service.d.ts +41 -0
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -0
- package/dest/contract_sync/contract_sync_service.js +82 -0
- package/dest/contract_sync/helpers.d.ts +28 -0
- package/dest/contract_sync/helpers.d.ts.map +1 -0
- package/dest/contract_sync/helpers.js +55 -0
- package/dest/debug/pxe_debug_utils.d.ts +22 -9
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +28 -17
- package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +31 -8
- package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +32 -9
- package/dest/entrypoints/pxe_creation_options.d.ts +5 -3
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/index.d.ts +3 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +2 -0
- package/dest/entrypoints/server/utils.d.ts +1 -1
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +39 -16
- package/dest/events/event_service.d.ts +6 -6
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +19 -22
- package/dest/events/private_event_filter_validator.d.ts +5 -5
- package/dest/events/private_event_filter_validator.d.ts.map +1 -1
- package/dest/events/private_event_filter_validator.js +5 -6
- package/dest/job_coordinator/job_coordinator.d.ts +75 -0
- package/dest/job_coordinator/job_coordinator.d.ts.map +1 -0
- package/dest/job_coordinator/job_coordinator.js +94 -0
- package/dest/logs/log_service.d.ts +7 -5
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +23 -20
- package/dest/notes/note_service.d.ts +7 -7
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +31 -36
- package/dest/oracle_version.d.ts +3 -3
- package/dest/oracle_version.d.ts.map +1 -1
- package/dest/oracle_version.js +4 -3
- package/dest/private_kernel/hints/index.d.ts +2 -2
- package/dest/private_kernel/hints/index.d.ts.map +1 -1
- package/dest/private_kernel/hints/index.js +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +28 -0
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -0
- package/dest/private_kernel/hints/{build_private_kernel_reset_private_inputs.js → private_kernel_reset_private_inputs_builder.js} +13 -7
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +3 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +6 -7
- package/dest/private_kernel/private_kernel_oracle.d.ts +24 -28
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +90 -2
- package/dest/pxe.d.ts +71 -57
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +123 -119
- package/dest/storage/address_store/address_store.d.ts +1 -1
- package/dest/storage/address_store/address_store.d.ts.map +1 -1
- package/dest/storage/address_store/address_store.js +12 -11
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
- package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
- package/dest/storage/capsule_store/capsule_store.d.ts +24 -9
- package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
- package/dest/storage/capsule_store/capsule_store.js +130 -23
- package/dest/storage/contract_store/contract_store.d.ts +1 -2
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +27 -30
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/note_store/note_store.d.ts +51 -52
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +285 -263
- package/dest/storage/note_store/stored_note.d.ts +16 -0
- package/dest/storage/note_store/stored_note.d.ts.map +1 -0
- package/dest/storage/note_store/stored_note.js +43 -0
- package/dest/storage/private_event_store/private_event_store.d.ts +47 -7
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +231 -73
- package/dest/storage/private_event_store/stored_private_event.d.ts +23 -0
- package/dest/storage/private_event_store/stored_private_event.d.ts.map +1 -0
- package/dest/storage/private_event_store/stored_private_event.js +56 -0
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +15 -8
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.js +88 -19
- package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +19 -9
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +253 -101
- package/dest/tagging/constants.d.ts +2 -0
- package/dest/tagging/constants.d.ts.map +1 -0
- package/dest/tagging/constants.js +10 -0
- package/dest/tagging/get_all_logs_by_tags.d.ts +24 -0
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -0
- package/dest/tagging/get_all_logs_by_tags.js +46 -0
- package/dest/tagging/index.d.ts +3 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +2 -10
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +3 -2
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +8 -8
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +3 -2
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +5 -2
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +3 -2
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +8 -8
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +5 -8
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -2
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +10 -5
- package/package.json +27 -18
- package/src/bin/check_oracle_version.ts +1 -0
- package/src/block_synchronizer/block_synchronizer.ts +93 -32
- package/src/config/index.ts +14 -0
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/benchmarked_node.ts +103 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +148 -99
- package/src/contract_function_simulator/execution_note_cache.ts +44 -25
- package/src/contract_function_simulator/index.ts +1 -1
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +5 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/utility_context.ts +6 -25
- package/src/contract_function_simulator/oracle/interfaces.ts +22 -12
- package/src/contract_function_simulator/oracle/note_packing_utils.ts +10 -10
- package/src/contract_function_simulator/oracle/oracle.ts +79 -47
- package/src/contract_function_simulator/oracle/private_execution.ts +1 -69
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +117 -137
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +191 -115
- package/src/contract_sync/contract_sync_service.ts +129 -0
- package/src/contract_sync/helpers.ts +93 -0
- package/src/debug/pxe_debug_utils.ts +60 -17
- package/src/entrypoints/client/bundle/utils.ts +23 -16
- package/src/entrypoints/client/lazy/utils.ts +24 -17
- package/src/entrypoints/pxe_creation_options.ts +4 -2
- package/src/entrypoints/server/index.ts +2 -0
- package/src/entrypoints/server/utils.ts +33 -41
- package/src/events/event_service.ts +19 -25
- package/src/events/private_event_filter_validator.ts +3 -5
- package/src/job_coordinator/job_coordinator.ts +150 -0
- package/src/logs/log_service.ts +34 -16
- package/src/notes/note_service.ts +38 -43
- package/src/oracle_version.ts +4 -3
- package/src/private_kernel/hints/index.ts +1 -1
- package/src/private_kernel/hints/{build_private_kernel_reset_private_inputs.ts → private_kernel_reset_private_inputs_builder.ts} +33 -22
- package/src/private_kernel/private_kernel_execution_prover.ts +9 -8
- package/src/private_kernel/private_kernel_oracle.ts +116 -36
- package/src/pxe.ts +246 -184
- package/src/storage/address_store/address_store.ts +15 -15
- package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
- package/src/storage/capsule_store/capsule_store.ts +159 -23
- package/src/storage/contract_store/contract_store.ts +26 -35
- package/src/storage/metadata.ts +1 -1
- package/src/storage/note_store/note_store.ts +321 -318
- package/src/storage/note_store/stored_note.ts +48 -0
- package/src/storage/private_event_store/private_event_store.ts +301 -79
- package/src/storage/private_event_store/stored_private_event.ts +73 -0
- package/src/storage/tagging_store/recipient_tagging_store.ts +106 -20
- package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
- package/src/storage/tagging_store/sender_tagging_store.ts +294 -109
- package/src/tagging/constants.ts +10 -0
- package/src/tagging/get_all_logs_by_tags.ts +68 -0
- package/src/tagging/index.ts +2 -11
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +21 -7
- package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +7 -1
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +10 -7
- package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +5 -13
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +16 -4
- package/dest/contract_function_simulator/proxied_node.d.ts +0 -9
- package/dest/contract_function_simulator/proxied_node.d.ts.map +0 -1
- package/dest/contract_function_simulator/proxied_node.js +0 -27
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +0 -28
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts +0 -46
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +0 -1
- package/dest/private_kernel/private_kernel_oracle_impl.js +0 -86
- package/dest/public_storage/public_storage_service.d.ts +0 -24
- package/dest/public_storage/public_storage_service.d.ts.map +0 -1
- package/dest/public_storage/public_storage_service.js +0 -26
- package/dest/tree_membership/tree_membership_service.d.ts +0 -52
- package/dest/tree_membership/tree_membership_service.d.ts.map +0 -1
- package/dest/tree_membership/tree_membership_service.js +0 -84
- package/src/contract_function_simulator/proxied_node.ts +0 -33
- package/src/private_kernel/private_kernel_oracle_impl.ts +0 -133
- package/src/public_storage/public_storage_service.ts +0 -33
- package/src/tree_membership/tree_membership_service.ts +0 -112
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
2
|
+
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
3
|
+
import type { NodeStats, RoundTripStats } from '@aztec/stdlib/tx';
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* Proxy generator for an AztecNode that tracks the time taken for each RPC call and the number of round trips (actual
|
|
7
|
+
* blocking waits for node responses).
|
|
8
|
+
*
|
|
9
|
+
* A round trip is counted when we transition from 0 to 1 in-flight calls, and ends when all concurrent calls complete.
|
|
10
|
+
* This means parallel calls in Promise.all count as a single round trip.
|
|
11
|
+
*
|
|
12
|
+
* Note that batching of RPC calls in `safe_json_rpc_client.ts` could affect the round trip counts but in places we
|
|
13
|
+
* currently use this information we do not even use HTTP as we have direct access to the Aztec Node instance in TS
|
|
14
|
+
* (i.e. not running against external node) so this is not a problem for now.
|
|
15
|
+
*
|
|
16
|
+
* If you want to use this against external node and the info gets skewed by batching you can set the `maxBatchSize`
|
|
17
|
+
* value in `safe_json_rpc_client.ts` to 1 (the main motivation for batching was to get around parallel http requests
|
|
18
|
+
* limits in web browsers which is not a problem when debugging in node.js).
|
|
19
|
+
*/
|
|
20
|
+
export type BenchmarkedNode = AztecNode & { getStats(): NodeStats };
|
|
21
|
+
|
|
22
|
+
export class BenchmarkedNodeFactory {
|
|
23
|
+
static create(node: AztecNode): BenchmarkedNode {
|
|
24
|
+
// Per-method call stats
|
|
25
|
+
const perMethod: Partial<Record<keyof AztecNode, { times: number[] }>> = {};
|
|
26
|
+
|
|
27
|
+
// Round trip tracking
|
|
28
|
+
let inFlightCount = 0;
|
|
29
|
+
let currentRoundTripTimer: Timer | null = null;
|
|
30
|
+
let currentRoundTripMethods: string[] = [];
|
|
31
|
+
const roundTrips: RoundTripStats = {
|
|
32
|
+
roundTrips: 0,
|
|
33
|
+
totalBlockingTime: 0,
|
|
34
|
+
roundTripDurations: [],
|
|
35
|
+
roundTripMethods: [],
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return new Proxy(node, {
|
|
39
|
+
get(target, prop: keyof BenchmarkedNode) {
|
|
40
|
+
if (prop === 'getStats') {
|
|
41
|
+
return (): NodeStats => {
|
|
42
|
+
return { perMethod, roundTrips };
|
|
43
|
+
};
|
|
44
|
+
} else {
|
|
45
|
+
return function (...args: any[]) {
|
|
46
|
+
// Track per-method stats
|
|
47
|
+
if (!perMethod[prop]) {
|
|
48
|
+
perMethod[prop] = { times: [] };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Start of a new round trip batch?
|
|
52
|
+
if (inFlightCount === 0) {
|
|
53
|
+
roundTrips.roundTrips++;
|
|
54
|
+
currentRoundTripTimer = new Timer();
|
|
55
|
+
currentRoundTripMethods = [];
|
|
56
|
+
}
|
|
57
|
+
inFlightCount++;
|
|
58
|
+
currentRoundTripMethods.push(prop);
|
|
59
|
+
|
|
60
|
+
const callTimer = new Timer();
|
|
61
|
+
const result = (target[prop] as any).apply(target, args);
|
|
62
|
+
|
|
63
|
+
// Handle completion - called when the call finishes (after Promise resolves)
|
|
64
|
+
const handleCompletion = () => {
|
|
65
|
+
const callTime = callTimer.ms();
|
|
66
|
+
perMethod[prop]!.times.push(callTime);
|
|
67
|
+
|
|
68
|
+
inFlightCount--;
|
|
69
|
+
|
|
70
|
+
// End of round trip batch - all concurrent calls completed
|
|
71
|
+
if (inFlightCount === 0 && currentRoundTripTimer) {
|
|
72
|
+
const roundTripTime = currentRoundTripTimer.ms();
|
|
73
|
+
roundTrips.totalBlockingTime += roundTripTime;
|
|
74
|
+
roundTrips.roundTripDurations.push(roundTripTime);
|
|
75
|
+
roundTrips.roundTripMethods.push(currentRoundTripMethods);
|
|
76
|
+
currentRoundTripTimer = null;
|
|
77
|
+
currentRoundTripMethods = [];
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// If the result is a Promise, chain the completion handler
|
|
82
|
+
if (result && typeof result.then === 'function') {
|
|
83
|
+
return result.then(
|
|
84
|
+
(value: any) => {
|
|
85
|
+
handleCompletion();
|
|
86
|
+
return value;
|
|
87
|
+
},
|
|
88
|
+
(error: any) => {
|
|
89
|
+
handleCompletion();
|
|
90
|
+
throw error;
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
} else {
|
|
94
|
+
// Synchronous method - handle completion immediately
|
|
95
|
+
handleCompletion();
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
}) as BenchmarkedNode;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
FIXED_AVM_STARTUP_L2_GAS,
|
|
8
8
|
FIXED_DA_GAS,
|
|
9
9
|
FIXED_L2_GAS,
|
|
10
|
+
GeneratorIndex,
|
|
10
11
|
L2_GAS_PER_CONTRACT_CLASS_LOG,
|
|
11
12
|
L2_GAS_PER_PRIVATE_LOG,
|
|
12
13
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
MAX_PRIVATE_LOGS_PER_TX,
|
|
18
19
|
} from '@aztec/constants';
|
|
19
20
|
import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection';
|
|
20
|
-
import {
|
|
21
|
+
import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
|
|
21
22
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
22
23
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
23
24
|
import { Timer } from '@aztec/foundation/timer';
|
|
@@ -71,8 +72,8 @@ import {
|
|
|
71
72
|
getFinalMinRevertibleSideEffectCounter,
|
|
72
73
|
} from '@aztec/stdlib/tx';
|
|
73
74
|
|
|
75
|
+
import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
|
|
74
76
|
import type { AddressStore } from '../storage/address_store/address_store.js';
|
|
75
|
-
import type { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_store.js';
|
|
76
77
|
import type { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
|
|
77
78
|
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
78
79
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
@@ -80,68 +81,101 @@ import type { PrivateEventStore } from '../storage/private_event_store/private_e
|
|
|
80
81
|
import type { RecipientTaggingStore } from '../storage/tagging_store/recipient_tagging_store.js';
|
|
81
82
|
import type { SenderAddressBookStore } from '../storage/tagging_store/sender_address_book_store.js';
|
|
82
83
|
import type { SenderTaggingStore } from '../storage/tagging_store/sender_tagging_store.js';
|
|
84
|
+
import type { BenchmarkedNode } from './benchmarked_node.js';
|
|
83
85
|
import { ExecutionNoteCache } from './execution_note_cache.js';
|
|
84
86
|
import { ExecutionTaggingIndexCache } from './execution_tagging_index_cache.js';
|
|
85
87
|
import { HashedValuesCache } from './hashed_values_cache.js';
|
|
86
88
|
import { Oracle } from './oracle/oracle.js';
|
|
87
|
-
import { executePrivateFunction
|
|
89
|
+
import { executePrivateFunction } from './oracle/private_execution.js';
|
|
88
90
|
import { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
|
|
89
91
|
import { UtilityExecutionOracle } from './oracle/utility_execution_oracle.js';
|
|
90
|
-
|
|
92
|
+
|
|
93
|
+
/** Options for ContractFunctionSimulator.run. */
|
|
94
|
+
export type ContractSimulatorRunOpts = {
|
|
95
|
+
/** The address of the contract (should match request.origin). */
|
|
96
|
+
contractAddress: AztecAddress;
|
|
97
|
+
/** The function selector of the entry point. */
|
|
98
|
+
selector: FunctionSelector;
|
|
99
|
+
/** The address calling the function. Can be replaced to simulate a call from another contract or account. */
|
|
100
|
+
msgSender?: AztecAddress;
|
|
101
|
+
/** The block header to use as base state for this run. */
|
|
102
|
+
anchorBlockHeader: BlockHeader;
|
|
103
|
+
/** The address used as a tagging sender when emitting private logs. */
|
|
104
|
+
senderForTags?: AztecAddress;
|
|
105
|
+
/** The accounts whose notes we can access in this call. Defaults to all. */
|
|
106
|
+
scopes?: AztecAddress[];
|
|
107
|
+
/** The job ID for staged writes. */
|
|
108
|
+
jobId: string;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** Args for ContractFunctionSimulator constructor. */
|
|
112
|
+
export type ContractFunctionSimulatorArgs = {
|
|
113
|
+
contractStore: ContractStore;
|
|
114
|
+
noteStore: NoteStore;
|
|
115
|
+
keyStore: KeyStore;
|
|
116
|
+
addressStore: AddressStore;
|
|
117
|
+
aztecNode: AztecNode;
|
|
118
|
+
senderTaggingStore: SenderTaggingStore;
|
|
119
|
+
recipientTaggingStore: RecipientTaggingStore;
|
|
120
|
+
senderAddressBookStore: SenderAddressBookStore;
|
|
121
|
+
capsuleStore: CapsuleStore;
|
|
122
|
+
privateEventStore: PrivateEventStore;
|
|
123
|
+
simulator: CircuitSimulator;
|
|
124
|
+
contractSyncService: ContractSyncService;
|
|
125
|
+
};
|
|
91
126
|
|
|
92
127
|
/**
|
|
93
128
|
* The contract function simulator.
|
|
94
129
|
*/
|
|
95
130
|
export class ContractFunctionSimulator {
|
|
96
|
-
private log: Logger;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
131
|
+
private readonly log: Logger;
|
|
132
|
+
private readonly contractStore: ContractStore;
|
|
133
|
+
private readonly noteStore: NoteStore;
|
|
134
|
+
private readonly keyStore: KeyStore;
|
|
135
|
+
private readonly addressStore: AddressStore;
|
|
136
|
+
private readonly aztecNode: AztecNode;
|
|
137
|
+
private readonly senderTaggingStore: SenderTaggingStore;
|
|
138
|
+
private readonly recipientTaggingStore: RecipientTaggingStore;
|
|
139
|
+
private readonly senderAddressBookStore: SenderAddressBookStore;
|
|
140
|
+
private readonly capsuleStore: CapsuleStore;
|
|
141
|
+
private readonly privateEventStore: PrivateEventStore;
|
|
142
|
+
private readonly simulator: CircuitSimulator;
|
|
143
|
+
private readonly contractSyncService: ContractSyncService;
|
|
144
|
+
|
|
145
|
+
constructor(args: ContractFunctionSimulatorArgs) {
|
|
146
|
+
this.contractStore = args.contractStore;
|
|
147
|
+
this.noteStore = args.noteStore;
|
|
148
|
+
this.keyStore = args.keyStore;
|
|
149
|
+
this.addressStore = args.addressStore;
|
|
150
|
+
this.aztecNode = args.aztecNode;
|
|
151
|
+
this.senderTaggingStore = args.senderTaggingStore;
|
|
152
|
+
this.recipientTaggingStore = args.recipientTaggingStore;
|
|
153
|
+
this.senderAddressBookStore = args.senderAddressBookStore;
|
|
154
|
+
this.capsuleStore = args.capsuleStore;
|
|
155
|
+
this.privateEventStore = args.privateEventStore;
|
|
156
|
+
this.simulator = args.simulator;
|
|
157
|
+
this.contractSyncService = args.contractSyncService;
|
|
112
158
|
this.log = createLogger('simulator');
|
|
113
159
|
}
|
|
114
160
|
|
|
115
161
|
/**
|
|
116
162
|
* Runs a private function.
|
|
117
163
|
* @param request - The transaction request.
|
|
118
|
-
* @param entryPointArtifact - The artifact of the entry point function.
|
|
119
|
-
* @param contractAddress - The address of the contract (should match request.origin)
|
|
120
|
-
* @param msgSender - The address calling the function. This can be replaced to simulate a call from another contract
|
|
121
|
-
* or a specific account.
|
|
122
|
-
* @param anchorBlockHeader - The block header to use as base state for this run.
|
|
123
|
-
* @param senderForTags - The address that is used as a tagging sender when emitting private logs. Returned from
|
|
124
|
-
* the `privateGetSenderForTags` oracle.
|
|
125
|
-
* @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
|
|
126
|
-
* @returns The result of the execution.
|
|
127
164
|
*/
|
|
128
165
|
public async run(
|
|
129
166
|
request: TxExecutionRequest,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
167
|
+
{
|
|
168
|
+
contractAddress,
|
|
169
|
+
selector,
|
|
170
|
+
msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE),
|
|
171
|
+
anchorBlockHeader,
|
|
172
|
+
senderForTags,
|
|
173
|
+
scopes,
|
|
174
|
+
jobId,
|
|
175
|
+
}: ContractSimulatorRunOpts,
|
|
136
176
|
): Promise<PrivateExecutionResult> {
|
|
137
177
|
const simulatorSetupTimer = new Timer();
|
|
138
178
|
|
|
139
|
-
await this.contractStore.syncPrivateState(contractAddress, selector, privateSyncCall =>
|
|
140
|
-
this.runUtility(privateSyncCall, [], anchorBlockHeader, scopes),
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
await verifyCurrentClassId(contractAddress, this.aztecNode, this.contractStore, anchorBlockHeader);
|
|
144
|
-
|
|
145
179
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(contractAddress, selector);
|
|
146
180
|
|
|
147
181
|
if (entryPointArtifact.functionType !== FunctionType.PRIVATE) {
|
|
@@ -168,37 +202,37 @@ export class ContractFunctionSimulator {
|
|
|
168
202
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
169
203
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
170
204
|
|
|
171
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
172
|
-
request.firstCallArgsHash,
|
|
173
|
-
request.txContext,
|
|
205
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
206
|
+
argsHash: request.firstCallArgsHash,
|
|
207
|
+
txContext: request.txContext,
|
|
174
208
|
callContext,
|
|
175
209
|
anchorBlockHeader,
|
|
176
|
-
async call => {
|
|
177
|
-
await this.runUtility(call, [], anchorBlockHeader, scopes);
|
|
210
|
+
utilityExecutor: async call => {
|
|
211
|
+
await this.runUtility(call, [], anchorBlockHeader, scopes, jobId);
|
|
178
212
|
},
|
|
179
|
-
request.authWitnesses,
|
|
180
|
-
request.capsules,
|
|
181
|
-
HashedValuesCache.create(request.argsOfCalls),
|
|
213
|
+
authWitnesses: request.authWitnesses,
|
|
214
|
+
capsules: request.capsules,
|
|
215
|
+
executionCache: HashedValuesCache.create(request.argsOfCalls),
|
|
182
216
|
noteCache,
|
|
183
217
|
taggingIndexCache,
|
|
184
|
-
this.contractStore,
|
|
185
|
-
this.noteStore,
|
|
186
|
-
this.keyStore,
|
|
187
|
-
this.addressStore,
|
|
188
|
-
this.aztecNode,
|
|
189
|
-
this.
|
|
190
|
-
this.
|
|
191
|
-
this.
|
|
192
|
-
this.
|
|
193
|
-
this.
|
|
194
|
-
this.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
218
|
+
contractStore: this.contractStore,
|
|
219
|
+
noteStore: this.noteStore,
|
|
220
|
+
keyStore: this.keyStore,
|
|
221
|
+
addressStore: this.addressStore,
|
|
222
|
+
aztecNode: this.aztecNode,
|
|
223
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
224
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
225
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
226
|
+
capsuleStore: this.capsuleStore,
|
|
227
|
+
privateEventStore: this.privateEventStore,
|
|
228
|
+
contractSyncService: this.contractSyncService,
|
|
229
|
+
jobId,
|
|
230
|
+
totalPublicCalldataCount: 0,
|
|
231
|
+
sideEffectCounter: startSideEffectCounter,
|
|
198
232
|
scopes,
|
|
199
233
|
senderForTags,
|
|
200
|
-
this.simulator,
|
|
201
|
-
);
|
|
234
|
+
simulator: this.simulator,
|
|
235
|
+
});
|
|
202
236
|
|
|
203
237
|
const setupTime = simulatorSetupTimer.ms();
|
|
204
238
|
|
|
@@ -215,8 +249,9 @@ export class ContractFunctionSimulator {
|
|
|
215
249
|
request.functionSelector,
|
|
216
250
|
);
|
|
217
251
|
const simulatorTeardownTimer = new Timer();
|
|
218
|
-
|
|
219
|
-
|
|
252
|
+
|
|
253
|
+
noteCache.finish();
|
|
254
|
+
const firstNullifierHint = noteCache.getNonceGenerator();
|
|
220
255
|
|
|
221
256
|
const publicCallRequests = collectNested([executionResult], r =>
|
|
222
257
|
r.publicInputs.publicCallRequests
|
|
@@ -261,34 +296,32 @@ export class ContractFunctionSimulator {
|
|
|
261
296
|
call: FunctionCall,
|
|
262
297
|
authwits: AuthWitness[],
|
|
263
298
|
anchorBlockHeader: BlockHeader,
|
|
264
|
-
scopes
|
|
299
|
+
scopes: AztecAddress[] | undefined,
|
|
300
|
+
jobId: string,
|
|
265
301
|
): Promise<Fr[]> {
|
|
266
|
-
await verifyCurrentClassId(call.to, this.aztecNode, this.contractStore, anchorBlockHeader);
|
|
267
|
-
|
|
268
302
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
269
303
|
|
|
270
304
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
271
305
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
272
306
|
}
|
|
273
307
|
|
|
274
|
-
const oracle = new UtilityExecutionOracle(
|
|
275
|
-
call.to,
|
|
276
|
-
authwits,
|
|
277
|
-
[],
|
|
308
|
+
const oracle = new UtilityExecutionOracle({
|
|
309
|
+
contractAddress: call.to,
|
|
310
|
+
authWitnesses: authwits,
|
|
311
|
+
capsules: [],
|
|
278
312
|
anchorBlockHeader,
|
|
279
|
-
this.contractStore,
|
|
280
|
-
this.noteStore,
|
|
281
|
-
this.keyStore,
|
|
282
|
-
this.addressStore,
|
|
283
|
-
this.aztecNode,
|
|
284
|
-
this.
|
|
285
|
-
this.
|
|
286
|
-
this.
|
|
287
|
-
this.
|
|
288
|
-
|
|
289
|
-
undefined,
|
|
313
|
+
contractStore: this.contractStore,
|
|
314
|
+
noteStore: this.noteStore,
|
|
315
|
+
keyStore: this.keyStore,
|
|
316
|
+
addressStore: this.addressStore,
|
|
317
|
+
aztecNode: this.aztecNode,
|
|
318
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
319
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
320
|
+
capsuleStore: this.capsuleStore,
|
|
321
|
+
privateEventStore: this.privateEventStore,
|
|
322
|
+
jobId,
|
|
290
323
|
scopes,
|
|
291
|
-
);
|
|
324
|
+
});
|
|
292
325
|
|
|
293
326
|
try {
|
|
294
327
|
this.log.verbose(`Executing utility function ${entryPointArtifact.name}`, {
|
|
@@ -326,7 +359,12 @@ export class ContractFunctionSimulator {
|
|
|
326
359
|
*/
|
|
327
360
|
getStats() {
|
|
328
361
|
const nodeRPCCalls =
|
|
329
|
-
typeof (this.aztecNode as
|
|
362
|
+
typeof (this.aztecNode as BenchmarkedNode).getStats === 'function'
|
|
363
|
+
? (this.aztecNode as BenchmarkedNode).getStats()
|
|
364
|
+
: {
|
|
365
|
+
perMethod: {},
|
|
366
|
+
roundTrips: { roundTrips: 0, totalBlockingTime: 0, roundTripDurations: [], roundTripMethods: [] },
|
|
367
|
+
};
|
|
330
368
|
|
|
331
369
|
return { nodeRPCCalls };
|
|
332
370
|
}
|
|
@@ -349,15 +387,15 @@ class OrderedSideEffect<T> {
|
|
|
349
387
|
* (allowing state overrides) and is much faster, while still generating a valid
|
|
350
388
|
* output that can be sent to the node for public simulation
|
|
351
389
|
* @param privateExecutionResult - The result of the private execution.
|
|
352
|
-
* @param nonceGenerator - A nonce generator for note hashes. According to the protocol rules,
|
|
353
|
-
* it can either be the first nullifier in the tx or the hash of the initial tx request if there are none.
|
|
354
390
|
* @param contractStore - A provider for contract data in order to get function names and debug info.
|
|
391
|
+
* @param minRevertibleSideEffectCounterOverride - Optional override for the min revertible side effect counter.
|
|
392
|
+
* Used by TXE to simulate account contract behavior (setting the counter before app execution).
|
|
355
393
|
* @returns The simulated proving result.
|
|
356
394
|
*/
|
|
357
395
|
export async function generateSimulatedProvingResult(
|
|
358
396
|
privateExecutionResult: PrivateExecutionResult,
|
|
359
|
-
|
|
360
|
-
|
|
397
|
+
debugFunctionNameGetter: (contractAddress: AztecAddress, functionSelector: FunctionSelector) => Promise<string>,
|
|
398
|
+
minRevertibleSideEffectCounterOverride?: number,
|
|
361
399
|
): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
362
400
|
const siloedNoteHashes: OrderedSideEffect<Fr>[] = [];
|
|
363
401
|
const nullifiers: OrderedSideEffect<Fr>[] = [];
|
|
@@ -398,7 +436,10 @@ export async function generateSimulatedProvingResult(
|
|
|
398
436
|
|
|
399
437
|
const privateLogsFromExecution = await Promise.all(
|
|
400
438
|
execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
|
|
401
|
-
metadata.log.fields[0] = await
|
|
439
|
+
metadata.log.fields[0] = await poseidon2HashWithSeparator(
|
|
440
|
+
[contractAddress, metadata.log.fields[0]],
|
|
441
|
+
GeneratorIndex.PRIVATE_LOG_FIRST_FIELD,
|
|
442
|
+
);
|
|
402
443
|
return new OrderedSideEffect(metadata.log, metadata.counter);
|
|
403
444
|
}),
|
|
404
445
|
);
|
|
@@ -434,7 +475,7 @@ export async function generateSimulatedProvingResult(
|
|
|
434
475
|
: execution.publicInputs.publicTeardownCallRequest;
|
|
435
476
|
|
|
436
477
|
executionSteps.push({
|
|
437
|
-
functionName: await
|
|
478
|
+
functionName: await debugFunctionNameGetter(
|
|
438
479
|
execution.publicInputs.callContext.contractAddress,
|
|
439
480
|
execution.publicInputs.callContext.functionSelector,
|
|
440
481
|
),
|
|
@@ -461,16 +502,18 @@ export async function generateSimulatedProvingResult(
|
|
|
461
502
|
const getEffect = <T>(orderedSideEffect: OrderedSideEffect<T>) => orderedSideEffect.sideEffect;
|
|
462
503
|
|
|
463
504
|
const isPrivateOnlyTx = privateExecutionResult.publicFunctionCalldata.length === 0;
|
|
464
|
-
const minRevertibleSideEffectCounter =
|
|
505
|
+
const minRevertibleSideEffectCounter =
|
|
506
|
+
minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
|
|
465
507
|
|
|
466
508
|
const [nonRevertibleNullifiers, revertibleNullifiers] = splitOrderedSideEffects(
|
|
467
509
|
nullifiers.sort(sortByCounter),
|
|
468
510
|
minRevertibleSideEffectCounter,
|
|
469
511
|
);
|
|
470
|
-
|
|
512
|
+
const nonceGenerator = privateExecutionResult.firstNullifier;
|
|
513
|
+
if (nonRevertibleNullifiers.length === 0) {
|
|
514
|
+
nonRevertibleNullifiers.push(nonceGenerator);
|
|
515
|
+
} else if (!nonRevertibleNullifiers[0].equals(nonceGenerator)) {
|
|
471
516
|
throw new Error('The first non revertible nullifier should be equal to the nonce generator. This is a bug!');
|
|
472
|
-
} else {
|
|
473
|
-
nonRevertibleNullifiers.unshift(nonceGenerator);
|
|
474
517
|
}
|
|
475
518
|
|
|
476
519
|
if (isPrivateOnlyTx) {
|
|
@@ -506,6 +549,12 @@ export async function generateSimulatedProvingResult(
|
|
|
506
549
|
siloedNoteHashes.sort(sortByCounter),
|
|
507
550
|
minRevertibleSideEffectCounter,
|
|
508
551
|
);
|
|
552
|
+
const nonRevertibleUniqueNoteHashes = await Promise.all(
|
|
553
|
+
nonRevertibleNoteHashes.map(async (noteHash, i) => {
|
|
554
|
+
const nonce = await computeNoteHashNonce(nonceGenerator, i);
|
|
555
|
+
return await computeUniqueNoteHash(nonce, noteHash);
|
|
556
|
+
}),
|
|
557
|
+
);
|
|
509
558
|
const [nonRevertibleL2ToL1Messages, revertibleL2ToL1Messages] = splitOrderedSideEffects(
|
|
510
559
|
l2ToL1Messages.sort(sortByCounter),
|
|
511
560
|
minRevertibleSideEffectCounter,
|
|
@@ -524,7 +573,7 @@ export async function generateSimulatedProvingResult(
|
|
|
524
573
|
);
|
|
525
574
|
|
|
526
575
|
const nonRevertibleData = new PrivateToPublicAccumulatedData(
|
|
527
|
-
padArrayEnd(
|
|
576
|
+
padArrayEnd(nonRevertibleUniqueNoteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
|
|
528
577
|
padArrayEnd(nonRevertibleNullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX),
|
|
529
578
|
padArrayEnd(nonRevertibleL2ToL1Messages, ScopedL2ToL1Message.empty(), MAX_L2_TO_L1_MSGS_PER_TX),
|
|
530
579
|
padArrayEnd(nonRevertibleTaggedPrivateLogs, PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
|
|
@@ -572,7 +621,7 @@ function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertib
|
|
|
572
621
|
const revertibleSideEffects: T[] = [];
|
|
573
622
|
const nonRevertibleSideEffects: T[] = [];
|
|
574
623
|
effects.forEach(effect => {
|
|
575
|
-
if (effect.counter < minRevertibleSideEffectCounter) {
|
|
624
|
+
if (minRevertibleSideEffectCounter === 0 || effect.counter < minRevertibleSideEffectCounter) {
|
|
576
625
|
nonRevertibleSideEffects.push(effect.sideEffect);
|
|
577
626
|
} else {
|
|
578
627
|
revertibleSideEffects.push(effect.sideEffect);
|
|
@@ -32,19 +32,22 @@ export class ExecutionNoteCache {
|
|
|
32
32
|
private nullifierMap: Map<bigint, Set<bigint>> = new Map();
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* Nullifiers emitted by private calls in this transaction.
|
|
36
36
|
*/
|
|
37
|
-
private
|
|
37
|
+
private emittedNullifiers: Set<bigint> = new Set();
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* The counter that separates non-revertible side effects (which persist even if the tx reverts) from revertible ones.
|
|
41
|
+
*/
|
|
39
42
|
private minRevertibleSideEffectCounter = 0;
|
|
40
43
|
|
|
41
44
|
private inRevertiblePhase = false;
|
|
42
45
|
|
|
43
46
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
47
|
+
* Whether the protocol nullifier was used for nonce generation.
|
|
48
|
+
* We don't need to use the protocol nullifier if a non-revertible nullifier is emitted.
|
|
46
49
|
*/
|
|
47
|
-
private usedProtocolNullifierForNonces
|
|
50
|
+
private usedProtocolNullifierForNonces: boolean | undefined;
|
|
48
51
|
|
|
49
52
|
constructor(private readonly protocolNullifier: Fr) {}
|
|
50
53
|
|
|
@@ -60,17 +63,18 @@ export class ExecutionNoteCache {
|
|
|
60
63
|
}
|
|
61
64
|
this.inRevertiblePhase = true;
|
|
62
65
|
this.minRevertibleSideEffectCounter = minRevertibleSideEffectCounter;
|
|
63
|
-
|
|
64
|
-
const nullifiers = this.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
|
|
67
|
+
const nullifiers = this.getEmittedNullifiers();
|
|
68
|
+
// If there are no nullifiers emitted by private calls so far, we use the protocol nullifier as the nonce generator.
|
|
69
|
+
// Note: There could still be nullifiers emitted after the counter is set, but those nullifiers are revertible, so
|
|
70
|
+
// we don't want to use them as the nonce generator.
|
|
71
|
+
this.usedProtocolNullifierForNonces = nullifiers.length === 0;
|
|
72
|
+
const nonceGenerator = this.usedProtocolNullifierForNonces ? this.protocolNullifier : new Fr(nullifiers[0]);
|
|
69
73
|
|
|
70
74
|
// The existing pending notes are all non-revertible.
|
|
71
75
|
// They cannot be squashed by nullifiers emitted after minRevertibleSideEffectCounter is set.
|
|
72
76
|
// Their indexes in the tx are known at this point and won't change. So we can assign a nonce to each one of them.
|
|
73
|
-
// The nonces will be used to create the "
|
|
77
|
+
// The nonces will be used to create the "unique" note hashes.
|
|
74
78
|
const updatedNotes = await Promise.all(
|
|
75
79
|
this.notes.map(async ({ note, counter }, i) => {
|
|
76
80
|
const noteNonce = await computeNoteHashNonce(nonceGenerator, i);
|
|
@@ -99,15 +103,11 @@ export class ExecutionNoteCache {
|
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
public finish() {
|
|
102
|
-
// If we never entered the revertible phase,
|
|
103
|
-
//
|
|
106
|
+
// If we never entered the revertible phase, and there are no nullifiers emitted, we need to use the protocol
|
|
107
|
+
// nullifier as the nonce generator.
|
|
104
108
|
if (!this.inRevertiblePhase) {
|
|
105
|
-
this.usedProtocolNullifierForNonces = this.
|
|
109
|
+
this.usedProtocolNullifierForNonces = this.getEmittedNullifiers().length === 0;
|
|
106
110
|
}
|
|
107
|
-
// If we entered the revertible phase, the nonce generator was decided based on wether or not a nullifier was emitted before entering.
|
|
108
|
-
return {
|
|
109
|
-
usedProtocolNullifierForNonces: this.usedProtocolNullifierForNonces,
|
|
110
|
-
};
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
@@ -150,11 +150,11 @@ export class ExecutionNoteCache {
|
|
|
150
150
|
|
|
151
151
|
// If the note is non revertible and the nullifier was emitted in the revertible phase, both the note hash and the nullifier will be emitted
|
|
152
152
|
if (this.inRevertiblePhase && note.counter < this.minRevertibleSideEffectCounter) {
|
|
153
|
-
this
|
|
153
|
+
this.#recordNullifier(contractAddress, siloedNullifier);
|
|
154
154
|
}
|
|
155
155
|
} else {
|
|
156
156
|
// If the note being nullified comes from a previous tx the nullifier will be emitted.
|
|
157
|
-
this
|
|
157
|
+
this.#recordNullifier(contractAddress, siloedNullifier);
|
|
158
158
|
}
|
|
159
159
|
return nullifiedNoteHashCounter;
|
|
160
160
|
}
|
|
@@ -166,7 +166,7 @@ export class ExecutionNoteCache {
|
|
|
166
166
|
*/
|
|
167
167
|
public async nullifierCreated(contractAddress: AztecAddress, innerNullifier: Fr) {
|
|
168
168
|
const siloedNullifier = (await siloNullifier(contractAddress, innerNullifier)).toBigInt();
|
|
169
|
-
this
|
|
169
|
+
this.#recordNullifier(contractAddress, siloedNullifier);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
/**
|
|
@@ -215,11 +215,30 @@ export class ExecutionNoteCache {
|
|
|
215
215
|
return this.notes;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
/**
|
|
219
|
+
* @returns All nullifiers emitted by private calls in this transaction.
|
|
220
|
+
*/
|
|
221
|
+
getEmittedNullifiers(): Fr[] {
|
|
222
|
+
return [...this.emittedNullifiers].map(n => new Fr(n));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @returns All nullifiers emitted by private calls in this transaction. If the protocol nullifier was used as the
|
|
227
|
+
* nonce generator, it is injected as the first nullifier.
|
|
228
|
+
*/
|
|
218
229
|
getAllNullifiers(): Fr[] {
|
|
219
|
-
|
|
230
|
+
if (this.usedProtocolNullifierForNonces === undefined) {
|
|
231
|
+
throw new Error('usedProtocolNullifierForNonces is not set yet. Call finish() to complete the transaction.');
|
|
232
|
+
}
|
|
233
|
+
const allNullifiers = this.getEmittedNullifiers();
|
|
234
|
+
return [...(this.usedProtocolNullifierForNonces ? [this.protocolNullifier] : []), ...allNullifiers];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
getNonceGenerator(): Fr {
|
|
238
|
+
return this.getAllNullifiers()[0];
|
|
220
239
|
}
|
|
221
240
|
|
|
222
|
-
recordNullifier(contractAddress: AztecAddress, siloedNullifier: bigint) {
|
|
241
|
+
#recordNullifier(contractAddress: AztecAddress, siloedNullifier: bigint) {
|
|
223
242
|
const nullifiers = this.getNullifiers(contractAddress);
|
|
224
243
|
|
|
225
244
|
if (nullifiers.has(siloedNullifier)) {
|
|
@@ -228,6 +247,6 @@ export class ExecutionNoteCache {
|
|
|
228
247
|
|
|
229
248
|
nullifiers.add(siloedNullifier);
|
|
230
249
|
this.nullifierMap.set(contractAddress.toBigInt(), nullifiers);
|
|
231
|
-
this.
|
|
250
|
+
this.emittedNullifiers.add(siloedNullifier);
|
|
232
251
|
}
|
|
233
252
|
}
|
|
@@ -9,5 +9,5 @@ export { PrivateExecutionOracle } from './oracle/private_execution_oracle.js';
|
|
|
9
9
|
export { Oracle } from './oracle/oracle.js';
|
|
10
10
|
export { executePrivateFunction, extractPrivateCircuitPublicInputs } from './oracle/private_execution.js';
|
|
11
11
|
export { generateSimulatedProvingResult } from './contract_function_simulator.js';
|
|
12
|
-
export {
|
|
12
|
+
export { packAsHintedNote } from './oracle/note_packing_utils.js';
|
|
13
13
|
export { UtilityContext } from './noir-structs/utility_context.js';
|