@aztec/txe 0.0.1-commit.96dac018d → 0.0.1-commit.9a89641
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/AuthRegistry-QVGDDH5X.js +3 -0
- package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
- package/dest/ContractClassRegistry-PVNCKGG7.js +3 -0
- package/dest/ContractClassRegistry-PVNCKGG7.js.map +7 -0
- package/dest/ContractInstanceRegistry-WLOZKTR6.js +3 -0
- package/dest/ContractInstanceRegistry-WLOZKTR6.js.map +7 -0
- package/dest/FeeJuice-MAQJU53K.js +3 -0
- package/dest/FeeJuice-MAQJU53K.js.map +7 -0
- package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
- package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
- package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
- package/dest/MultiCallEntrypoint-QG5H33ZZ.js.map +7 -0
- package/dest/SchnorrAccount-ADD65DYA.js +3 -0
- package/dest/SchnorrAccount-ADD65DYA.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js +3 -0
- package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js.map +7 -0
- package/dest/bin/check_txe_oracle_version.d.ts +2 -0
- package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
- package/dest/bin/check_txe_oracle_version.js +22 -0
- package/dest/bin/index.js +3 -30
- package/dest/bin/index.js.map +7 -0
- package/dest/bin/oracle_test_server.d.ts +3 -0
- package/dest/bin/oracle_test_server.d.ts.map +1 -0
- package/dest/bin/oracle_test_server.js +41 -0
- package/dest/chunk-32UHX7YY.js +3 -0
- package/dest/chunk-32UHX7YY.js.map +7 -0
- package/dest/chunk-RVEPNDEP.js +304 -0
- package/dest/chunk-RVEPNDEP.js.map +7 -0
- package/dest/chunk-XWIMXLKD.js +258 -0
- package/dest/chunk-XWIMXLKD.js.map +7 -0
- package/dest/constants.d.ts +5 -1
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +9 -1
- package/dest/dispatcher_pool.d.ts +67 -0
- package/dest/dispatcher_pool.d.ts.map +1 -0
- package/dest/dispatcher_pool.js +286 -0
- package/dest/index.d.ts +51 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +72 -188
- package/dest/metafile.json +38833 -0
- package/dest/msgpackr_fr_extension.d.ts +2 -0
- package/dest/msgpackr_fr_extension.d.ts.map +1 -0
- package/dest/msgpackr_fr_extension.js +21 -0
- package/dest/oracle/interfaces.d.ts +68 -30
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
- package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
- package/dest/oracle/tagging_secret_strategy.js +12 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/default_fixtures.js +200 -0
- package/dest/oracle/test-resolver/index.d.ts +9 -0
- package/dest/oracle/test-resolver/index.d.ts.map +1 -0
- package/dest/oracle/test-resolver/index.js +32 -0
- package/dest/oracle/test-resolver/resolver.d.ts +48 -0
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
- package/dest/oracle/test-resolver/resolver.js +181 -0
- package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +61 -13
- package/dest/oracle/txe_oracle_registry.d.ts +172 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +767 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +68 -27
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +571 -312
- package/dest/oracle/txe_oracle_version.d.ts +17 -0
- package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_version.js +14 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
- package/dest/oracle/txe_private_execution_oracle.js +15 -0
- package/dest/rpc_server.d.ts +14 -0
- package/dest/rpc_server.d.ts.map +1 -0
- package/dest/rpc_server.js +78 -0
- package/dest/rpc_translator.d.ts +116 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +909 -636
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +28 -20
- package/dest/state_machine/dummy_p2p_client.d.ts +16 -7
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +25 -4
- package/dest/state_machine/global_variable_builder.d.ts +10 -6
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +8 -5
- package/dest/state_machine/index.d.ts +11 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +50 -10
- package/dest/state_machine/mock_epoch_cache.d.ts +17 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +32 -2
- package/dest/state_machine/synchronizer.d.ts +14 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +22 -9
- package/dest/txe_session.d.ts +92 -19
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +325 -61
- package/dest/utils/block_creation.d.ts +2 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +2 -2
- package/dest/utils/encoding.d.ts +194 -0
- package/dest/utils/encoding.d.ts.map +1 -0
- package/dest/{util → utils}/encoding.js +7 -2
- package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
- package/dest/utils/expected_failure_error.d.ts.map +1 -0
- package/dest/utils/tx_effect_creation.d.ts +1 -1
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +0 -1
- package/dest/{util → utils}/txe_account_store.d.ts +1 -1
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.d.ts +37 -0
- package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.js +161 -0
- package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/{util → utils}/txe_public_contract_data_source.js +8 -7
- package/dest/worker.bundle.js +3 -0
- package/dest/worker.bundle.js.map +7 -0
- package/dest/worker.d.ts +2 -0
- package/dest/worker.d.ts.map +1 -0
- package/dest/worker.js +92 -0
- package/package.json +38 -21
- package/src/bin/check_txe_oracle_version.ts +31 -0
- package/src/bin/index.ts +11 -2
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +11 -1
- package/src/dispatcher_pool.ts +317 -0
- package/src/index.ts +99 -224
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +70 -35
- package/src/oracle/tagging_secret_strategy.ts +25 -0
- package/src/oracle/test-resolver/default_fixtures.ts +271 -0
- package/src/oracle/test-resolver/index.ts +44 -0
- package/src/oracle/test-resolver/resolver.ts +245 -0
- package/src/oracle/txe_oracle_public_context.ts +74 -12
- package/src/oracle/txe_oracle_registry.ts +556 -0
- package/src/oracle/txe_oracle_top_level_context.ts +380 -128
- package/src/oracle/txe_oracle_version.ts +17 -0
- package/src/oracle/txe_private_execution_oracle.ts +30 -0
- package/src/rpc_server.ts +87 -0
- package/src/rpc_translator.ts +1126 -1021
- package/src/state_machine/archiver.ts +41 -20
- package/src/state_machine/dummy_p2p_client.ts +44 -11
- package/src/state_machine/global_variable_builder.ts +12 -11
- package/src/state_machine/index.ts +63 -28
- package/src/state_machine/mock_epoch_cache.ts +42 -3
- package/src/state_machine/synchronizer.ts +31 -10
- package/src/txe_session.ts +564 -75
- package/src/utils/block_creation.ts +2 -1
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/tx_effect_creation.ts +0 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/{util → utils}/txe_public_contract_data_source.ts +6 -6
- package/src/worker.ts +98 -0
- package/dest/util/encoding.d.ts +0 -720
- package/dest/util/encoding.d.ts.map +0 -1
- package/dest/util/expected_failure_error.d.ts.map +0 -1
- package/dest/util/txe_account_store.d.ts.map +0 -1
- package/dest/util/txe_public_contract_data_source.d.ts +0 -20
- package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
- /package/dest/{util → utils}/expected_failure_error.js +0 -0
- /package/dest/{util → utils}/txe_account_store.js +0 -0
- /package/src/{util → utils}/expected_failure_error.ts +0 -0
- /package/src/{util → utils}/txe_account_store.ts +0 -0
|
@@ -1,38 +1,45 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
|
|
3
|
-
|
|
4
|
-
DEFAULT_L2_GAS_LIMIT,
|
|
5
|
-
DEFAULT_TEARDOWN_DA_GAS_LIMIT,
|
|
6
|
-
DEFAULT_TEARDOWN_L2_GAS_LIMIT,
|
|
3
|
+
MAX_PRIVATE_LOGS_PER_TX,
|
|
7
4
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
8
5
|
} from '@aztec/constants';
|
|
9
6
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
10
7
|
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
11
8
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
9
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
12
10
|
import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
13
11
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
14
12
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
|
-
import type { AccessScopes } from '@aztec/pxe/client/lazy';
|
|
16
13
|
import {
|
|
17
14
|
AddressStore,
|
|
15
|
+
AnchoredContractData,
|
|
16
|
+
CapsuleService,
|
|
18
17
|
CapsuleStore,
|
|
19
18
|
type ContractStore,
|
|
19
|
+
type ExecutionHooks,
|
|
20
|
+
FactService,
|
|
21
|
+
FactStore,
|
|
20
22
|
NoteStore,
|
|
21
|
-
|
|
23
|
+
ORACLE_VERSION_MAJOR,
|
|
22
24
|
PrivateEventStore,
|
|
23
25
|
RecipientTaggingStore,
|
|
24
|
-
SenderAddressBookStore,
|
|
25
26
|
SenderTaggingStore,
|
|
27
|
+
TaggingSecretSourcesStore,
|
|
28
|
+
type TaggingSecretStrategy,
|
|
29
|
+
composeHooks,
|
|
26
30
|
enrichPublicSimulationError,
|
|
27
31
|
} from '@aztec/pxe/server';
|
|
28
32
|
import {
|
|
33
|
+
CONTRACT_INSTANCE,
|
|
29
34
|
ExecutionNoteCache,
|
|
30
35
|
ExecutionTaggingIndexCache,
|
|
31
36
|
HashedValuesCache,
|
|
32
37
|
type IMiscOracle,
|
|
33
|
-
|
|
38
|
+
type Option,
|
|
34
39
|
PrivateExecutionOracle,
|
|
40
|
+
TransientArrayService,
|
|
35
41
|
UtilityExecutionOracle,
|
|
42
|
+
buildACIRCallback,
|
|
36
43
|
executePrivateFunction,
|
|
37
44
|
generateSimulatedProvingResult,
|
|
38
45
|
} from '@aztec/pxe/simulator';
|
|
@@ -46,10 +53,10 @@ import {
|
|
|
46
53
|
witnessMapToFields,
|
|
47
54
|
} from '@aztec/simulator/client';
|
|
48
55
|
import {
|
|
49
|
-
CppPublicTxSimulator,
|
|
50
56
|
GuardedMerkleTreeOperations,
|
|
51
57
|
PublicContractsDB,
|
|
52
58
|
PublicProcessor,
|
|
59
|
+
PublicTxSimulator,
|
|
53
60
|
} from '@aztec/simulator/server';
|
|
54
61
|
import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
55
62
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
@@ -64,6 +71,10 @@ import {
|
|
|
64
71
|
PrivateToPublicAccumulatedData,
|
|
65
72
|
PublicCallRequest,
|
|
66
73
|
} from '@aztec/stdlib/kernel';
|
|
74
|
+
import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
|
|
75
|
+
import type { PrivateLog } from '@aztec/stdlib/logs';
|
|
76
|
+
import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
|
|
77
|
+
import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
67
78
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
68
79
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
69
80
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -80,14 +91,16 @@ import {
|
|
|
80
91
|
collectNested,
|
|
81
92
|
} from '@aztec/stdlib/tx';
|
|
82
93
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
83
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
94
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
84
95
|
|
|
85
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
96
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
86
97
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
87
|
-
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
88
|
-
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
89
98
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
99
|
+
import type { TXEAccountStore } from '../utils/txe_account_store.js';
|
|
100
|
+
import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
|
|
101
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
90
102
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
103
|
+
import { type TXETaggingSecretStrategies, makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
|
|
91
104
|
|
|
92
105
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
93
106
|
isMisc = true as const;
|
|
@@ -104,34 +117,52 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
104
117
|
private accountStore: TXEAccountStore,
|
|
105
118
|
private senderTaggingStore: SenderTaggingStore,
|
|
106
119
|
private recipientTaggingStore: RecipientTaggingStore,
|
|
107
|
-
private
|
|
120
|
+
private taggingSecretSourcesStore: TaggingSecretSourcesStore,
|
|
108
121
|
private capsuleStore: CapsuleStore,
|
|
122
|
+
private factStore: FactStore,
|
|
109
123
|
private privateEventStore: PrivateEventStore,
|
|
110
124
|
private nextBlockTimestamp: bigint,
|
|
111
125
|
private version: Fr,
|
|
112
126
|
private chainId: Fr,
|
|
113
127
|
private authwits: Map<string, AuthWitness>,
|
|
128
|
+
private taggingSecretStrategies: TXETaggingSecretStrategies,
|
|
129
|
+
private authorizeAllUtilityCallTargets: boolean,
|
|
130
|
+
private readonly artifactResolver: TXEArtifactResolver,
|
|
131
|
+
private readonly rootPath: string,
|
|
132
|
+
private readonly packageName: string,
|
|
114
133
|
) {
|
|
115
134
|
this.logger = createLogger('txe:top_level_context');
|
|
116
135
|
this.logger.debug('Entering Top Level Context');
|
|
117
136
|
}
|
|
118
137
|
|
|
119
|
-
|
|
120
|
-
|
|
138
|
+
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
139
|
+
|
|
140
|
+
assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
141
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
142
|
+
const hint =
|
|
143
|
+
major > ORACLE_VERSION_MAJOR
|
|
144
|
+
? 'The contract was compiled with a newer version of Aztec.nr than this aztec cli version supports. Upgrade your aztec cli version to a compatible version.'
|
|
145
|
+
: 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
|
|
121
146
|
throw new Error(
|
|
122
|
-
`Incompatible
|
|
147
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
123
148
|
);
|
|
124
149
|
}
|
|
150
|
+
this.contractOracleVersion = { major, minor };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
154
|
+
nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
|
|
155
|
+
return this.contractOracleVersion;
|
|
125
156
|
}
|
|
126
157
|
|
|
127
158
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
128
159
|
// setup.
|
|
129
|
-
|
|
160
|
+
getRandomField(): Fr {
|
|
130
161
|
return Fr.random();
|
|
131
162
|
}
|
|
132
163
|
|
|
133
164
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
134
|
-
|
|
165
|
+
log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
135
166
|
if (!LogLevels[level]) {
|
|
136
167
|
throw new Error(`Invalid log level: ${level}`);
|
|
137
168
|
}
|
|
@@ -141,25 +172,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
141
172
|
return Promise.resolve();
|
|
142
173
|
}
|
|
143
174
|
|
|
144
|
-
|
|
175
|
+
getDefaultAddress(): AztecAddress {
|
|
145
176
|
return DEFAULT_ADDRESS;
|
|
146
177
|
}
|
|
147
178
|
|
|
148
|
-
async
|
|
179
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
149
180
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
150
181
|
}
|
|
151
182
|
|
|
152
|
-
|
|
183
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
153
184
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
154
185
|
}
|
|
155
186
|
|
|
156
|
-
async
|
|
157
|
-
return (await this.stateMachine.node.
|
|
187
|
+
async getLastBlockTimestamp() {
|
|
188
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
158
189
|
}
|
|
159
190
|
|
|
160
|
-
async
|
|
191
|
+
async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
|
|
161
192
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
-
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
193
|
+
const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
|
|
163
194
|
|
|
164
195
|
if (block!.body.txEffects.length != 1) {
|
|
165
196
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,12 +199,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
199
|
|
|
169
200
|
const txEffects = block!.body.txEffects[0];
|
|
170
201
|
|
|
171
|
-
|
|
202
|
+
const privateLogs = txEffects.privateLogs;
|
|
203
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
204
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
txHash: txEffects.txHash,
|
|
209
|
+
noteHashes: txEffects.noteHashes,
|
|
210
|
+
nullifiers: txEffects.nullifiers,
|
|
211
|
+
privateLogs,
|
|
212
|
+
};
|
|
172
213
|
}
|
|
173
214
|
|
|
174
215
|
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
175
216
|
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
176
|
-
this.logger.debug(`Skipping sync in
|
|
217
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
177
218
|
return;
|
|
178
219
|
}
|
|
179
220
|
|
|
@@ -182,7 +223,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
182
223
|
contractAddress,
|
|
183
224
|
null,
|
|
184
225
|
async (call, execScopes) => {
|
|
185
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
226
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
186
227
|
},
|
|
187
228
|
blockHeader,
|
|
188
229
|
jobId,
|
|
@@ -190,8 +231,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
190
231
|
);
|
|
191
232
|
}
|
|
192
233
|
|
|
193
|
-
async
|
|
194
|
-
|
|
234
|
+
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
235
|
+
const events = (
|
|
195
236
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
196
237
|
contractAddress,
|
|
197
238
|
scopes: [scope],
|
|
@@ -199,9 +240,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
199
240
|
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
200
241
|
})
|
|
201
242
|
).map(e => e.packedEvent);
|
|
243
|
+
|
|
244
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
245
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
246
|
+
}
|
|
247
|
+
if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
248
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return events;
|
|
202
252
|
}
|
|
203
253
|
|
|
204
|
-
async
|
|
254
|
+
async advanceBlocksBy(blocks: number) {
|
|
205
255
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
206
256
|
|
|
207
257
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -209,39 +259,76 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
209
259
|
}
|
|
210
260
|
}
|
|
211
261
|
|
|
212
|
-
|
|
262
|
+
advanceTimestampBy(duration: UInt64) {
|
|
213
263
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
214
264
|
this.nextBlockTimestamp += duration;
|
|
215
265
|
}
|
|
216
266
|
|
|
217
|
-
|
|
267
|
+
private deploymentNullifier(address: AztecAddress): Promise<Fr> {
|
|
268
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async deploy(
|
|
272
|
+
contractPath: string,
|
|
273
|
+
initializer: string,
|
|
274
|
+
args: Fr[],
|
|
275
|
+
secret: Fr,
|
|
276
|
+
salt: Fr,
|
|
277
|
+
deployer: AztecAddress,
|
|
278
|
+
): Promise<Fr[]> {
|
|
279
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
280
|
+
rootPath: this.rootPath,
|
|
281
|
+
packageName: this.packageName,
|
|
282
|
+
contractPath,
|
|
283
|
+
initializer,
|
|
284
|
+
args,
|
|
285
|
+
secret,
|
|
286
|
+
salt,
|
|
287
|
+
deployer,
|
|
288
|
+
});
|
|
289
|
+
|
|
218
290
|
// Emit deployment nullifier
|
|
219
291
|
await this.mineBlock({
|
|
220
|
-
nullifiers: [
|
|
221
|
-
await siloNullifier(
|
|
222
|
-
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
223
|
-
instance.address.toField(),
|
|
224
|
-
),
|
|
225
|
-
],
|
|
292
|
+
nullifiers: [await this.deploymentNullifier(instance.address)],
|
|
226
293
|
});
|
|
227
294
|
|
|
228
295
|
if (!secret.equals(Fr.ZERO)) {
|
|
229
|
-
await this.
|
|
296
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
230
297
|
} else {
|
|
231
298
|
await this.contractStore.addContractInstance(instance);
|
|
232
299
|
await this.contractStore.addContractArtifact(artifact);
|
|
233
300
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
234
301
|
}
|
|
302
|
+
|
|
303
|
+
return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
308
|
+
*/
|
|
309
|
+
async mineDeploymentNullifiers(addresses: AztecAddress[]) {
|
|
310
|
+
await this.mineBlock({
|
|
311
|
+
nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async addAccount(secret: Fr) {
|
|
316
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
317
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
235
318
|
}
|
|
236
319
|
|
|
237
|
-
async
|
|
320
|
+
private async registerContractAndAddAccount(
|
|
321
|
+
artifact: ContractArtifact,
|
|
322
|
+
instance: ContractInstanceWithAddress,
|
|
323
|
+
secret: Fr,
|
|
324
|
+
) {
|
|
238
325
|
const partialAddress = await computePartialAddress(instance);
|
|
239
326
|
|
|
240
327
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
241
328
|
await this.contractStore.addContractInstance(instance);
|
|
242
329
|
await this.contractStore.addContractArtifact(artifact);
|
|
243
330
|
|
|
244
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
331
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
245
332
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
246
333
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
247
334
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -249,9 +336,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
249
336
|
return completeAddress;
|
|
250
337
|
}
|
|
251
338
|
|
|
252
|
-
async
|
|
253
|
-
|
|
254
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
339
|
+
async createAccount(secret: Fr, partialAddress: Fr) {
|
|
340
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
255
341
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
256
342
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
257
343
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -259,27 +345,67 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
259
345
|
return completeAddress;
|
|
260
346
|
}
|
|
261
347
|
|
|
262
|
-
async
|
|
348
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
263
349
|
const account = await this.accountStore.getAccount(address);
|
|
264
|
-
const
|
|
350
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
351
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
265
352
|
|
|
266
353
|
const schnorr = new Schnorr();
|
|
267
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
354
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
268
355
|
|
|
269
|
-
const authWitness = new AuthWitness(messageHash,
|
|
356
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
270
357
|
|
|
271
358
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
272
359
|
}
|
|
273
360
|
|
|
274
|
-
|
|
275
|
-
|
|
361
|
+
setTaggingSecretStrategies(
|
|
362
|
+
unconstrainedStrategy: Option<TaggingSecretStrategy>,
|
|
363
|
+
constrainedStrategy: Option<TaggingSecretStrategy>,
|
|
364
|
+
): void {
|
|
365
|
+
const apply = (mode: AppTaggingSecretKind, strategy: Option<TaggingSecretStrategy>) => {
|
|
366
|
+
if (strategy.isSome()) {
|
|
367
|
+
this.taggingSecretStrategies.set(mode, strategy.value);
|
|
368
|
+
} else {
|
|
369
|
+
this.taggingSecretStrategies.delete(mode);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
|
|
373
|
+
apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
setAuthorizeAllUtilityCallTargets(authorizeAll: boolean): void {
|
|
377
|
+
this.authorizeAllUtilityCallTargets = authorizeAll;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
|
|
381
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
382
|
+
const { size } = await this.stateMachine.synchronizer
|
|
383
|
+
.getCommitted()
|
|
384
|
+
.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
385
|
+
const leafIndex = new Fr(size);
|
|
386
|
+
|
|
387
|
+
const message = new L1ToL2Message(
|
|
388
|
+
new L1Actor(sender, this.chainId.toNumber()),
|
|
389
|
+
new L2Actor(recipient, this.version.toNumber()),
|
|
390
|
+
content,
|
|
391
|
+
secretHash,
|
|
392
|
+
leafIndex,
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
await this.mineBlock({ l1ToL2Messages: [message.hash()] });
|
|
396
|
+
|
|
397
|
+
return leafIndex;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
|
|
401
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
276
402
|
|
|
277
403
|
const txEffect = TxEffect.empty();
|
|
278
404
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
279
405
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
280
406
|
|
|
281
407
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
282
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
408
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
283
409
|
|
|
284
410
|
const globals = makeGlobalVariables(undefined, {
|
|
285
411
|
blockNumber,
|
|
@@ -293,23 +419,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
293
419
|
|
|
294
420
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
295
421
|
|
|
296
|
-
await this.stateMachine.handleL2Block(block);
|
|
422
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
297
423
|
}
|
|
298
424
|
|
|
299
|
-
async
|
|
300
|
-
from: AztecAddress,
|
|
425
|
+
async privateCallNewFlow(
|
|
426
|
+
from: AztecAddress | undefined,
|
|
301
427
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
302
428
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
303
429
|
args: Fr[],
|
|
304
430
|
argsHash: Fr = Fr.zero(),
|
|
305
431
|
isStaticCall: boolean = false,
|
|
432
|
+
additionalScopes: AztecAddress[] = [],
|
|
306
433
|
jobId: string,
|
|
434
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
435
|
+
gasSettings: GasSettings,
|
|
307
436
|
) {
|
|
437
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
438
|
+
const anchoredContractData = new AnchoredContractData(
|
|
439
|
+
this.contractStore,
|
|
440
|
+
this.stateMachine.contractClassService,
|
|
441
|
+
blockHeader,
|
|
442
|
+
);
|
|
443
|
+
|
|
308
444
|
this.logger.verbose(
|
|
309
|
-
`Executing external function ${await
|
|
445
|
+
`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
310
446
|
);
|
|
311
447
|
|
|
312
|
-
const artifact = await
|
|
448
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
313
449
|
if (!artifact) {
|
|
314
450
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
315
451
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -317,32 +453,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
317
453
|
throw new Error(message);
|
|
318
454
|
}
|
|
319
455
|
|
|
320
|
-
|
|
321
|
-
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
322
|
-
const effectiveScopes = from.isZero() ? [] : [from];
|
|
456
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
323
457
|
|
|
324
458
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
325
|
-
const utilityExecutor = async (call: FunctionCall, execScopes:
|
|
326
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
459
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
460
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
327
461
|
};
|
|
328
462
|
|
|
329
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
330
463
|
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
331
464
|
targetContractAddress,
|
|
332
465
|
functionSelector,
|
|
333
466
|
utilityExecutor,
|
|
334
467
|
blockHeader,
|
|
335
468
|
jobId,
|
|
336
|
-
|
|
469
|
+
scopes,
|
|
337
470
|
);
|
|
338
471
|
|
|
339
|
-
const blockNumber = await this.
|
|
340
|
-
|
|
341
|
-
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
472
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
342
473
|
|
|
343
|
-
const
|
|
344
|
-
const
|
|
345
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
474
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
475
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
346
476
|
|
|
347
477
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
348
478
|
|
|
@@ -357,9 +487,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
357
487
|
|
|
358
488
|
const simulator = new WASMSimulator();
|
|
359
489
|
|
|
490
|
+
const transientArrayService = new TransientArrayService();
|
|
360
491
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
361
492
|
argsHash,
|
|
362
493
|
txContext,
|
|
494
|
+
txRequestSalt: Fr.ZERO,
|
|
363
495
|
callContext,
|
|
364
496
|
anchorBlockHeader: blockHeader,
|
|
365
497
|
utilityExecutor,
|
|
@@ -368,25 +500,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
368
500
|
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
369
501
|
noteCache,
|
|
370
502
|
taggingIndexCache,
|
|
371
|
-
|
|
503
|
+
anchoredContractData,
|
|
372
504
|
noteStore: this.noteStore,
|
|
373
505
|
keyStore: this.keyStore,
|
|
374
506
|
addressStore: this.addressStore,
|
|
375
507
|
aztecNode: this.stateMachine.node,
|
|
376
508
|
senderTaggingStore: this.senderTaggingStore,
|
|
377
509
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
378
|
-
|
|
379
|
-
|
|
510
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
511
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
512
|
+
factService: new FactService(this.factStore, scopes),
|
|
380
513
|
privateEventStore: this.privateEventStore,
|
|
381
514
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
382
515
|
jobId,
|
|
383
516
|
totalPublicCalldataCount: 0,
|
|
384
517
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
385
|
-
scopes
|
|
518
|
+
scopes,
|
|
386
519
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
387
520
|
// contract would perform, including setting senderForTags.
|
|
388
521
|
senderForTags: from,
|
|
389
522
|
simulator,
|
|
523
|
+
txResolver: this.stateMachine.txResolver,
|
|
524
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
525
|
+
hooks: composeHooks({
|
|
526
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
|
|
527
|
+
isStaticCall ? 'private view' : 'private',
|
|
528
|
+
authorizedUtilityCallTargets,
|
|
529
|
+
),
|
|
530
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
|
|
531
|
+
}),
|
|
532
|
+
transientArrayService,
|
|
390
533
|
});
|
|
391
534
|
|
|
392
535
|
// Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
|
|
@@ -409,12 +552,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
409
552
|
);
|
|
410
553
|
const publicFunctionsCalldata = await Promise.all(
|
|
411
554
|
publicCallRequests.map(async r => {
|
|
412
|
-
const calldata = await privateExecutionOracle.
|
|
555
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
413
556
|
return new HashedValues(calldata, r.calldataHash);
|
|
414
557
|
}),
|
|
415
558
|
);
|
|
416
559
|
|
|
417
|
-
noteCache.finish();
|
|
418
560
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
419
561
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
420
562
|
} catch (err) {
|
|
@@ -426,7 +568,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
426
568
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
427
569
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
428
570
|
result,
|
|
429
|
-
(addr, sel) =>
|
|
571
|
+
(addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
|
|
430
572
|
this.stateMachine.node,
|
|
431
573
|
minRevertibleSideEffectCounter,
|
|
432
574
|
);
|
|
@@ -438,7 +580,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
438
580
|
globals.version = this.version;
|
|
439
581
|
globals.gasFees = GasFees.empty();
|
|
440
582
|
|
|
441
|
-
|
|
583
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
442
584
|
|
|
443
585
|
const bindings = this.logger.getBindings();
|
|
444
586
|
const contractsDB = new PublicContractsDB(
|
|
@@ -453,11 +595,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
453
595
|
collectStatistics: false,
|
|
454
596
|
collectCallMetadata: true,
|
|
455
597
|
});
|
|
598
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
599
|
+
const forkId = forkedWorldTrees.getRevision().forkId;
|
|
456
600
|
const processor = new PublicProcessor(
|
|
457
601
|
globals,
|
|
458
602
|
guardedMerkleTrees,
|
|
459
603
|
contractsDB,
|
|
460
|
-
new
|
|
604
|
+
new PublicTxSimulator(
|
|
605
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
606
|
+
globals,
|
|
607
|
+
contractsDB,
|
|
608
|
+
forkId,
|
|
609
|
+
config,
|
|
610
|
+
bindings,
|
|
611
|
+
),
|
|
461
612
|
new TestDateProvider(),
|
|
462
613
|
undefined,
|
|
463
614
|
createLogger('simulator:public-processor', bindings),
|
|
@@ -485,7 +636,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
485
636
|
} else if (!processedTx.revertCode.isOK()) {
|
|
486
637
|
if (processedTx.revertReason) {
|
|
487
638
|
try {
|
|
488
|
-
await enrichPublicSimulationError(
|
|
639
|
+
await enrichPublicSimulationError(
|
|
640
|
+
processedTx.revertReason,
|
|
641
|
+
this.contractStore,
|
|
642
|
+
this.stateMachine.contractClassService,
|
|
643
|
+
await this.stateMachine.anchorBlockStore.getBlockHeader(),
|
|
644
|
+
this.logger,
|
|
645
|
+
);
|
|
489
646
|
// eslint-disable-next-line no-empty
|
|
490
647
|
} catch {}
|
|
491
648
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -494,11 +651,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
494
651
|
}
|
|
495
652
|
}
|
|
496
653
|
|
|
654
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
655
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
656
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
657
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
658
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
659
|
+
|
|
497
660
|
if (isStaticCall) {
|
|
498
661
|
await checkpoint!.revert();
|
|
499
|
-
|
|
500
|
-
await forkedWorldTrees.close();
|
|
501
|
-
return executionResult.returnValues ?? [];
|
|
662
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
502
663
|
}
|
|
503
664
|
|
|
504
665
|
const txEffect = TxEffect.empty();
|
|
@@ -518,33 +679,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
518
679
|
|
|
519
680
|
await this.stateMachine.handleL2Block(l2Block);
|
|
520
681
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
return executionResult.returnValues ?? [];
|
|
682
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
524
683
|
}
|
|
525
684
|
|
|
526
|
-
async
|
|
527
|
-
from: AztecAddress,
|
|
685
|
+
async publicCallNewFlow(
|
|
686
|
+
from: AztecAddress | undefined,
|
|
528
687
|
targetContractAddress: AztecAddress,
|
|
529
688
|
calldata: Fr[],
|
|
530
689
|
isStaticCall: boolean,
|
|
690
|
+
gasSettings: GasSettings,
|
|
531
691
|
) {
|
|
532
|
-
this.
|
|
533
|
-
|
|
692
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
693
|
+
const anchoredContractData = new AnchoredContractData(
|
|
694
|
+
this.contractStore,
|
|
695
|
+
this.stateMachine.contractClassService,
|
|
696
|
+
anchorBlockHeader,
|
|
534
697
|
);
|
|
535
698
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
699
|
+
this.logger.verbose(
|
|
700
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
701
|
+
);
|
|
541
702
|
|
|
542
|
-
const
|
|
703
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
543
704
|
|
|
544
705
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
545
706
|
|
|
546
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
547
|
-
|
|
548
707
|
const calldataHash = await computeCalldataHash(calldata);
|
|
549
708
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
550
709
|
|
|
@@ -555,7 +714,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
555
714
|
globals.version = this.version;
|
|
556
715
|
globals.gasFees = GasFees.empty();
|
|
557
716
|
|
|
558
|
-
|
|
717
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
559
718
|
|
|
560
719
|
const bindings2 = this.logger.getBindings();
|
|
561
720
|
const contractsDB = new PublicContractsDB(
|
|
@@ -570,7 +729,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
570
729
|
collectStatistics: false,
|
|
571
730
|
collectCallMetadata: true,
|
|
572
731
|
});
|
|
573
|
-
|
|
732
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
733
|
+
const forkId2 = forkedWorldTrees.getRevision().forkId;
|
|
734
|
+
const simulator = new PublicTxSimulator(
|
|
735
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
736
|
+
globals,
|
|
737
|
+
contractsDB,
|
|
738
|
+
forkId2,
|
|
739
|
+
config,
|
|
740
|
+
bindings2,
|
|
741
|
+
);
|
|
574
742
|
const processor = new PublicProcessor(
|
|
575
743
|
globals,
|
|
576
744
|
guardedMerkleTrees,
|
|
@@ -592,7 +760,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
592
760
|
// may require producing reverts.
|
|
593
761
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
594
762
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
595
|
-
from,
|
|
763
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
596
764
|
targetContractAddress,
|
|
597
765
|
isStaticCall,
|
|
598
766
|
calldataHash,
|
|
@@ -637,7 +805,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
637
805
|
} else if (!processedTx.revertCode.isOK()) {
|
|
638
806
|
if (processedTx.revertReason) {
|
|
639
807
|
try {
|
|
640
|
-
await enrichPublicSimulationError(
|
|
808
|
+
await enrichPublicSimulationError(
|
|
809
|
+
processedTx.revertReason,
|
|
810
|
+
this.contractStore,
|
|
811
|
+
this.stateMachine.contractClassService,
|
|
812
|
+
anchorBlockHeader,
|
|
813
|
+
this.logger,
|
|
814
|
+
);
|
|
641
815
|
// eslint-disable-next-line no-empty
|
|
642
816
|
} catch {}
|
|
643
817
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -650,9 +824,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
650
824
|
|
|
651
825
|
if (isStaticCall) {
|
|
652
826
|
await checkpoint!.revert();
|
|
653
|
-
|
|
654
|
-
await forkedWorldTrees.close();
|
|
655
|
-
|
|
656
827
|
return returnValues ?? [];
|
|
657
828
|
}
|
|
658
829
|
|
|
@@ -673,33 +844,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
673
844
|
|
|
674
845
|
await this.stateMachine.handleL2Block(l2Block);
|
|
675
846
|
|
|
676
|
-
await forkedWorldTrees.close();
|
|
677
|
-
|
|
678
847
|
return returnValues ?? [];
|
|
679
848
|
}
|
|
680
849
|
|
|
681
|
-
async
|
|
850
|
+
async executeUtilityFunction(
|
|
851
|
+
from: AztecAddress | undefined,
|
|
682
852
|
targetContractAddress: AztecAddress,
|
|
683
853
|
functionSelector: FunctionSelector,
|
|
684
854
|
args: Fr[],
|
|
685
855
|
jobId: string,
|
|
856
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
686
857
|
) {
|
|
687
|
-
const
|
|
858
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
859
|
+
const anchoredContractData = new AnchoredContractData(
|
|
860
|
+
this.contractStore,
|
|
861
|
+
this.stateMachine.contractClassService,
|
|
862
|
+
blockHeader,
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
688
866
|
if (!artifact) {
|
|
689
867
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
690
868
|
}
|
|
691
869
|
|
|
692
870
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
693
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
694
871
|
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
695
872
|
targetContractAddress,
|
|
696
873
|
functionSelector,
|
|
697
874
|
async (call, execScopes) => {
|
|
698
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
875
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
699
876
|
},
|
|
700
877
|
blockHeader,
|
|
701
878
|
jobId,
|
|
702
|
-
|
|
879
|
+
await this.keyStore.getAccounts(),
|
|
703
880
|
);
|
|
704
881
|
|
|
705
882
|
const call = FunctionCall.from({
|
|
@@ -710,14 +887,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
710
887
|
hideMsgSender: false,
|
|
711
888
|
isStatic: false,
|
|
712
889
|
args,
|
|
713
|
-
returnTypes: [],
|
|
714
890
|
});
|
|
715
891
|
|
|
716
|
-
return this.executeUtilityCall(call,
|
|
892
|
+
return this.executeUtilityCall(call, {
|
|
893
|
+
from,
|
|
894
|
+
scopes: await this.keyStore.getAccounts(),
|
|
895
|
+
jobId,
|
|
896
|
+
authorizedUtilityCallTargets,
|
|
897
|
+
});
|
|
717
898
|
}
|
|
718
899
|
|
|
719
|
-
private async executeUtilityCall(
|
|
720
|
-
|
|
900
|
+
private async executeUtilityCall(
|
|
901
|
+
call: FunctionCall,
|
|
902
|
+
{
|
|
903
|
+
from = AztecAddress.NULL_MSG_SENDER,
|
|
904
|
+
scopes,
|
|
905
|
+
jobId,
|
|
906
|
+
authorizedUtilityCallTargets = [],
|
|
907
|
+
}: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
|
|
908
|
+
): Promise<Fr[]> {
|
|
909
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
910
|
+
const anchoredContractData = new AnchoredContractData(
|
|
911
|
+
this.contractStore,
|
|
912
|
+
this.stateMachine.contractClassService,
|
|
913
|
+
anchorBlockHeader,
|
|
914
|
+
);
|
|
915
|
+
|
|
916
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
917
|
+
if (!entryPointArtifact) {
|
|
918
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
919
|
+
}
|
|
721
920
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
722
921
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
723
922
|
}
|
|
@@ -728,26 +927,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
728
927
|
});
|
|
729
928
|
|
|
730
929
|
try {
|
|
731
|
-
const
|
|
930
|
+
const simulator = new WASMSimulator();
|
|
931
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
932
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
|
|
933
|
+
};
|
|
732
934
|
const oracle = new UtilityExecutionOracle({
|
|
733
|
-
|
|
935
|
+
callContext: CallContext.from({
|
|
936
|
+
msgSender: from,
|
|
937
|
+
contractAddress: call.to,
|
|
938
|
+
functionSelector: call.selector,
|
|
939
|
+
isStaticCall: true,
|
|
940
|
+
}),
|
|
734
941
|
authWitnesses: [],
|
|
735
942
|
capsules: [],
|
|
736
943
|
anchorBlockHeader,
|
|
737
|
-
|
|
944
|
+
anchoredContractData,
|
|
738
945
|
noteStore: this.noteStore,
|
|
739
946
|
keyStore: this.keyStore,
|
|
740
947
|
addressStore: this.addressStore,
|
|
741
948
|
aztecNode: this.stateMachine.node,
|
|
742
949
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
743
|
-
|
|
744
|
-
|
|
950
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
951
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
952
|
+
factService: new FactService(this.factStore, scopes),
|
|
745
953
|
privateEventStore: this.privateEventStore,
|
|
954
|
+
txResolver: this.stateMachine.txResolver,
|
|
955
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
956
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
746
957
|
jobId,
|
|
747
958
|
scopes,
|
|
959
|
+
simulator,
|
|
960
|
+
hooks: composeHooks({
|
|
961
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
962
|
+
}),
|
|
963
|
+
utilityExecutor,
|
|
964
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
965
|
+
transientArrayService: new TransientArrayService(),
|
|
748
966
|
});
|
|
749
|
-
const acirExecutionResult = await
|
|
750
|
-
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact,
|
|
967
|
+
const acirExecutionResult = await simulator
|
|
968
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
751
969
|
.catch((err: Error) => {
|
|
752
970
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
753
971
|
throw new ExecutionError(
|
|
@@ -768,13 +986,47 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
768
986
|
}
|
|
769
987
|
}
|
|
770
988
|
|
|
771
|
-
close():
|
|
989
|
+
close(): {
|
|
990
|
+
nextBlockTimestamp: bigint;
|
|
991
|
+
authwits: Map<string, AuthWitness>;
|
|
992
|
+
taggingSecretStrategies: TXETaggingSecretStrategies;
|
|
993
|
+
authorizeAllUtilityCallTargets: boolean;
|
|
994
|
+
} {
|
|
772
995
|
this.logger.debug('Exiting Top Level Context');
|
|
773
|
-
return
|
|
996
|
+
return {
|
|
997
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
998
|
+
authwits: this.authwits,
|
|
999
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
1000
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
|
|
1001
|
+
};
|
|
774
1002
|
}
|
|
775
1003
|
|
|
776
1004
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
777
|
-
const
|
|
778
|
-
return
|
|
1005
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
1006
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
private buildAuthorizeUtilityCallHook(
|
|
1010
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
1011
|
+
authorizedTargets: AztecAddress[],
|
|
1012
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
1013
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
1014
|
+
return authorizeAllUtilityCallsHook;
|
|
1015
|
+
}
|
|
1016
|
+
if (authorizedTargets.length === 0) {
|
|
1017
|
+
return undefined;
|
|
1018
|
+
}
|
|
1019
|
+
return req =>
|
|
1020
|
+
Promise.resolve({
|
|
1021
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
1022
|
+
});
|
|
779
1023
|
}
|
|
780
1024
|
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
|
|
1028
|
+
*
|
|
1029
|
+
* Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
|
|
1030
|
+
*/
|
|
1031
|
+
export const authorizeAllUtilityCallsHook: NonNullable<ExecutionHooks['authorizeUtilityCall']> = () =>
|
|
1032
|
+
Promise.resolve({ authorized: true });
|