@aztec/txe 0.0.1-commit.f504929 → 0.0.1-commit.f5a9928
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-C2WBKKGS.js +266 -0
- package/dest/chunk-C2WBKKGS.js.map +7 -0
- package/dest/chunk-OFS2CI6U.js +304 -0
- package/dest/chunk-OFS2CI6U.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 +40416 -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 -17
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +259 -88
- 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 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +791 -607
- 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 +18 -8
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +31 -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 +16 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +29 -2
- package/dest/state_machine/synchronizer.d.ts +9 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +10 -6
- package/dest/txe_session.d.ts +90 -19
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +315 -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 +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 +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 +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 +342 -97
- 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 +882 -870
- package/src/state_machine/archiver.ts +41 -20
- package/src/state_machine/dummy_p2p_client.ts +49 -12
- 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 +38 -3
- package/src/state_machine/synchronizer.ts +13 -7
- package/src/txe_session.ts +552 -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';
|
|
@@ -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,24 +117,42 @@ 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
|
|
@@ -131,7 +162,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
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
|
-
log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
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
|
}
|
|
@@ -154,12 +185,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
154
185
|
}
|
|
155
186
|
|
|
156
187
|
async getLastBlockTimestamp() {
|
|
157
|
-
return (await this.stateMachine.node.
|
|
188
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
158
189
|
}
|
|
159
190
|
|
|
160
|
-
async getLastTxEffects() {
|
|
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,7 +199,17 @@ 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) {
|
|
@@ -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,
|
|
@@ -191,7 +232,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
191
232
|
}
|
|
192
233
|
|
|
193
234
|
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
194
|
-
|
|
235
|
+
const events = (
|
|
195
236
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
196
237
|
contractAddress,
|
|
197
238
|
scopes: [scope],
|
|
@@ -199,6 +240,15 @@ 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
254
|
async advanceBlocksBy(blocks: number) {
|
|
@@ -214,34 +264,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
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
|
+
});
|
|
235
313
|
}
|
|
236
314
|
|
|
237
|
-
async addAccount(
|
|
315
|
+
async addAccount(secret: Fr) {
|
|
316
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
317
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
318
|
+
}
|
|
319
|
+
|
|
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 createAccount(secret: Fr) {
|
|
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}`);
|
|
@@ -261,17 +347,57 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
261
347
|
|
|
262
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
|
-
|
|
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[] } = {}) {
|
|
275
401
|
const blockNumber = await this.getNextBlockNumber();
|
|
276
402
|
|
|
277
403
|
const txEffect = TxEffect.empty();
|
|
@@ -279,7 +405,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
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
425
|
async privateCallNewFlow(
|
|
300
|
-
from: AztecAddress,
|
|
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
472
|
const blockNumber = await this.getNextBlockNumber();
|
|
340
473
|
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
344
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
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,12 @@ 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
|
+
// The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
|
|
495
|
+
txRequestSalt: Fr.ZERO,
|
|
363
496
|
callContext,
|
|
364
497
|
anchorBlockHeader: blockHeader,
|
|
365
498
|
utilityExecutor,
|
|
@@ -368,25 +501,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
368
501
|
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
369
502
|
noteCache,
|
|
370
503
|
taggingIndexCache,
|
|
371
|
-
|
|
504
|
+
anchoredContractData,
|
|
372
505
|
noteStore: this.noteStore,
|
|
373
506
|
keyStore: this.keyStore,
|
|
374
507
|
addressStore: this.addressStore,
|
|
375
508
|
aztecNode: this.stateMachine.node,
|
|
376
509
|
senderTaggingStore: this.senderTaggingStore,
|
|
377
510
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
378
|
-
|
|
379
|
-
|
|
511
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
512
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
513
|
+
factService: new FactService(this.factStore, scopes),
|
|
380
514
|
privateEventStore: this.privateEventStore,
|
|
381
515
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
382
516
|
jobId,
|
|
383
517
|
totalPublicCalldataCount: 0,
|
|
384
518
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
385
|
-
scopes
|
|
519
|
+
scopes,
|
|
386
520
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
387
521
|
// contract would perform, including setting senderForTags.
|
|
388
522
|
senderForTags: from,
|
|
389
523
|
simulator,
|
|
524
|
+
txResolver: this.stateMachine.txResolver,
|
|
525
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
526
|
+
hooks: composeHooks({
|
|
527
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
|
|
528
|
+
isStaticCall ? 'private view' : 'private',
|
|
529
|
+
authorizedUtilityCallTargets,
|
|
530
|
+
),
|
|
531
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
|
|
532
|
+
}),
|
|
533
|
+
transientArrayService,
|
|
390
534
|
});
|
|
391
535
|
|
|
392
536
|
// 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 +553,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
409
553
|
);
|
|
410
554
|
const publicFunctionsCalldata = await Promise.all(
|
|
411
555
|
publicCallRequests.map(async r => {
|
|
412
|
-
const calldata = await privateExecutionOracle.
|
|
556
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
413
557
|
return new HashedValues(calldata, r.calldataHash);
|
|
414
558
|
}),
|
|
415
559
|
);
|
|
416
560
|
|
|
417
|
-
noteCache.finish();
|
|
418
561
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
419
562
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
420
563
|
} catch (err) {
|
|
@@ -426,7 +569,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
426
569
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
427
570
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
428
571
|
result,
|
|
429
|
-
(addr, sel) =>
|
|
572
|
+
(addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
|
|
430
573
|
this.stateMachine.node,
|
|
431
574
|
minRevertibleSideEffectCounter,
|
|
432
575
|
);
|
|
@@ -485,7 +628,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
485
628
|
} else if (!processedTx.revertCode.isOK()) {
|
|
486
629
|
if (processedTx.revertReason) {
|
|
487
630
|
try {
|
|
488
|
-
await enrichPublicSimulationError(
|
|
631
|
+
await enrichPublicSimulationError(
|
|
632
|
+
processedTx.revertReason,
|
|
633
|
+
this.contractStore,
|
|
634
|
+
this.stateMachine.contractClassService,
|
|
635
|
+
await this.stateMachine.anchorBlockStore.getBlockHeader(),
|
|
636
|
+
this.logger,
|
|
637
|
+
);
|
|
489
638
|
// eslint-disable-next-line no-empty
|
|
490
639
|
} catch {}
|
|
491
640
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -494,11 +643,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
494
643
|
}
|
|
495
644
|
}
|
|
496
645
|
|
|
646
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
647
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
648
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
649
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
650
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
651
|
+
|
|
497
652
|
if (isStaticCall) {
|
|
498
653
|
await checkpoint!.revert();
|
|
499
654
|
|
|
500
655
|
await forkedWorldTrees.close();
|
|
501
|
-
return executionResult.returnValues ?? [];
|
|
656
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
502
657
|
}
|
|
503
658
|
|
|
504
659
|
const txEffect = TxEffect.empty();
|
|
@@ -520,31 +675,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
520
675
|
|
|
521
676
|
await forkedWorldTrees.close();
|
|
522
677
|
|
|
523
|
-
return executionResult.returnValues ?? [];
|
|
678
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
524
679
|
}
|
|
525
680
|
|
|
526
681
|
async publicCallNewFlow(
|
|
527
|
-
from: AztecAddress,
|
|
682
|
+
from: AztecAddress | undefined,
|
|
528
683
|
targetContractAddress: AztecAddress,
|
|
529
684
|
calldata: Fr[],
|
|
530
685
|
isStaticCall: boolean,
|
|
686
|
+
gasSettings: GasSettings,
|
|
531
687
|
) {
|
|
688
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
689
|
+
const anchoredContractData = new AnchoredContractData(
|
|
690
|
+
this.contractStore,
|
|
691
|
+
this.stateMachine.contractClassService,
|
|
692
|
+
anchorBlockHeader,
|
|
693
|
+
);
|
|
694
|
+
|
|
532
695
|
this.logger.verbose(
|
|
533
|
-
`Executing public function ${await
|
|
696
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
534
697
|
);
|
|
535
698
|
|
|
536
699
|
const blockNumber = await this.getNextBlockNumber();
|
|
537
700
|
|
|
538
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
539
|
-
|
|
540
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
541
|
-
|
|
542
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
543
|
-
|
|
544
701
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
545
702
|
|
|
546
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
547
|
-
|
|
548
703
|
const calldataHash = await computeCalldataHash(calldata);
|
|
549
704
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
550
705
|
|
|
@@ -592,7 +747,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
592
747
|
// may require producing reverts.
|
|
593
748
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
594
749
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
595
|
-
from,
|
|
750
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
596
751
|
targetContractAddress,
|
|
597
752
|
isStaticCall,
|
|
598
753
|
calldataHash,
|
|
@@ -637,7 +792,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
637
792
|
} else if (!processedTx.revertCode.isOK()) {
|
|
638
793
|
if (processedTx.revertReason) {
|
|
639
794
|
try {
|
|
640
|
-
await enrichPublicSimulationError(
|
|
795
|
+
await enrichPublicSimulationError(
|
|
796
|
+
processedTx.revertReason,
|
|
797
|
+
this.contractStore,
|
|
798
|
+
this.stateMachine.contractClassService,
|
|
799
|
+
anchorBlockHeader,
|
|
800
|
+
this.logger,
|
|
801
|
+
);
|
|
641
802
|
// eslint-disable-next-line no-empty
|
|
642
803
|
} catch {}
|
|
643
804
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -679,27 +840,35 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
679
840
|
}
|
|
680
841
|
|
|
681
842
|
async executeUtilityFunction(
|
|
843
|
+
from: AztecAddress | undefined,
|
|
682
844
|
targetContractAddress: AztecAddress,
|
|
683
845
|
functionSelector: FunctionSelector,
|
|
684
846
|
args: Fr[],
|
|
685
847
|
jobId: string,
|
|
848
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
686
849
|
) {
|
|
687
|
-
const
|
|
850
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
851
|
+
const anchoredContractData = new AnchoredContractData(
|
|
852
|
+
this.contractStore,
|
|
853
|
+
this.stateMachine.contractClassService,
|
|
854
|
+
blockHeader,
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
688
858
|
if (!artifact) {
|
|
689
859
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
690
860
|
}
|
|
691
861
|
|
|
692
862
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
693
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
694
863
|
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
695
864
|
targetContractAddress,
|
|
696
865
|
functionSelector,
|
|
697
866
|
async (call, execScopes) => {
|
|
698
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
867
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
699
868
|
},
|
|
700
869
|
blockHeader,
|
|
701
870
|
jobId,
|
|
702
|
-
|
|
871
|
+
await this.keyStore.getAccounts(),
|
|
703
872
|
);
|
|
704
873
|
|
|
705
874
|
const call = FunctionCall.from({
|
|
@@ -713,11 +882,34 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
713
882
|
returnTypes: [],
|
|
714
883
|
});
|
|
715
884
|
|
|
716
|
-
return this.executeUtilityCall(call,
|
|
885
|
+
return this.executeUtilityCall(call, {
|
|
886
|
+
from,
|
|
887
|
+
scopes: await this.keyStore.getAccounts(),
|
|
888
|
+
jobId,
|
|
889
|
+
authorizedUtilityCallTargets,
|
|
890
|
+
});
|
|
717
891
|
}
|
|
718
892
|
|
|
719
|
-
private async executeUtilityCall(
|
|
720
|
-
|
|
893
|
+
private async executeUtilityCall(
|
|
894
|
+
call: FunctionCall,
|
|
895
|
+
{
|
|
896
|
+
from = AztecAddress.NULL_MSG_SENDER,
|
|
897
|
+
scopes,
|
|
898
|
+
jobId,
|
|
899
|
+
authorizedUtilityCallTargets = [],
|
|
900
|
+
}: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
|
|
901
|
+
): Promise<Fr[]> {
|
|
902
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
903
|
+
const anchoredContractData = new AnchoredContractData(
|
|
904
|
+
this.contractStore,
|
|
905
|
+
this.stateMachine.contractClassService,
|
|
906
|
+
anchorBlockHeader,
|
|
907
|
+
);
|
|
908
|
+
|
|
909
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
910
|
+
if (!entryPointArtifact) {
|
|
911
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
912
|
+
}
|
|
721
913
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
722
914
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
723
915
|
}
|
|
@@ -728,26 +920,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
728
920
|
});
|
|
729
921
|
|
|
730
922
|
try {
|
|
731
|
-
const
|
|
923
|
+
const simulator = new WASMSimulator();
|
|
924
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
925
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId, authorizedUtilityCallTargets });
|
|
926
|
+
};
|
|
732
927
|
const oracle = new UtilityExecutionOracle({
|
|
733
|
-
|
|
928
|
+
callContext: CallContext.from({
|
|
929
|
+
msgSender: from,
|
|
930
|
+
contractAddress: call.to,
|
|
931
|
+
functionSelector: call.selector,
|
|
932
|
+
isStaticCall: true,
|
|
933
|
+
}),
|
|
734
934
|
authWitnesses: [],
|
|
735
935
|
capsules: [],
|
|
736
936
|
anchorBlockHeader,
|
|
737
|
-
|
|
937
|
+
anchoredContractData,
|
|
738
938
|
noteStore: this.noteStore,
|
|
739
939
|
keyStore: this.keyStore,
|
|
740
940
|
addressStore: this.addressStore,
|
|
741
941
|
aztecNode: this.stateMachine.node,
|
|
742
942
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
743
|
-
|
|
744
|
-
|
|
943
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
944
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
945
|
+
factService: new FactService(this.factStore, scopes),
|
|
745
946
|
privateEventStore: this.privateEventStore,
|
|
947
|
+
txResolver: this.stateMachine.txResolver,
|
|
948
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
949
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
746
950
|
jobId,
|
|
747
951
|
scopes,
|
|
952
|
+
simulator,
|
|
953
|
+
utilityExecutor,
|
|
954
|
+
hooks: composeHooks({
|
|
955
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
956
|
+
}),
|
|
957
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
958
|
+
transientArrayService: new TransientArrayService(),
|
|
748
959
|
});
|
|
749
|
-
const acirExecutionResult = await
|
|
750
|
-
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact,
|
|
960
|
+
const acirExecutionResult = await simulator
|
|
961
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
751
962
|
.catch((err: Error) => {
|
|
752
963
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
753
964
|
throw new ExecutionError(
|
|
@@ -768,13 +979,47 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
768
979
|
}
|
|
769
980
|
}
|
|
770
981
|
|
|
771
|
-
close():
|
|
982
|
+
close(): {
|
|
983
|
+
nextBlockTimestamp: bigint;
|
|
984
|
+
authwits: Map<string, AuthWitness>;
|
|
985
|
+
taggingSecretStrategies: TXETaggingSecretStrategies;
|
|
986
|
+
authorizeAllUtilityCallTargets: boolean;
|
|
987
|
+
} {
|
|
772
988
|
this.logger.debug('Exiting Top Level Context');
|
|
773
|
-
return
|
|
989
|
+
return {
|
|
990
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
991
|
+
authwits: this.authwits,
|
|
992
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
993
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
|
|
994
|
+
};
|
|
774
995
|
}
|
|
775
996
|
|
|
776
997
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
777
|
-
const
|
|
778
|
-
return
|
|
998
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
999
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
private buildAuthorizeUtilityCallHook(
|
|
1003
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
1004
|
+
authorizedTargets: AztecAddress[],
|
|
1005
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
1006
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
1007
|
+
return authorizeAllUtilityCallsHook;
|
|
1008
|
+
}
|
|
1009
|
+
if (authorizedTargets.length === 0) {
|
|
1010
|
+
return undefined;
|
|
1011
|
+
}
|
|
1012
|
+
return req =>
|
|
1013
|
+
Promise.resolve({
|
|
1014
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
1015
|
+
});
|
|
779
1016
|
}
|
|
780
1017
|
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
|
|
1021
|
+
*
|
|
1022
|
+
* Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
|
|
1023
|
+
*/
|
|
1024
|
+
export const authorizeAllUtilityCallsHook: NonNullable<ExecutionHooks['authorizeUtilityCall']> = () =>
|
|
1025
|
+
Promise.resolve({ authorized: true });
|