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