@aztec/txe 0.0.1-commit.3fd054f6 → 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 +288 -98
- 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 -636
- 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 +24 -14
- 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 -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 +319 -73
- 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 +364 -121
- 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 +880 -902
- package/src/state_machine/archiver.ts +37 -16
- 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 -32
- package/src/state_machine/mock_epoch_cache.ts +0 -4
- package/src/state_machine/synchronizer.ts +9 -3
- package/src/txe_session.ts +554 -89
- 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
|
-
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,
|
|
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,25 +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) {
|
|
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.';
|
|
123
146
|
throw new Error(
|
|
124
|
-
`Incompatible
|
|
147
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
125
148
|
);
|
|
126
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;
|
|
127
156
|
}
|
|
128
157
|
|
|
129
158
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
@@ -133,7 +162,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
133
162
|
}
|
|
134
163
|
|
|
135
164
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
136
|
-
log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
165
|
+
log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
137
166
|
if (!LogLevels[level]) {
|
|
138
167
|
throw new Error(`Invalid log level: ${level}`);
|
|
139
168
|
}
|
|
@@ -156,12 +185,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
156
185
|
}
|
|
157
186
|
|
|
158
187
|
async getLastBlockTimestamp() {
|
|
159
|
-
return (await this.stateMachine.node.
|
|
188
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
160
189
|
}
|
|
161
190
|
|
|
162
|
-
async getLastTxEffects() {
|
|
191
|
+
async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
|
|
163
192
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
164
|
-
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
193
|
+
const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
|
|
165
194
|
|
|
166
195
|
if (block!.body.txEffects.length != 1) {
|
|
167
196
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -170,7 +199,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
170
199
|
|
|
171
200
|
const txEffects = block!.body.txEffects[0];
|
|
172
201
|
|
|
173
|
-
|
|
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
|
+
};
|
|
174
213
|
}
|
|
175
214
|
|
|
176
215
|
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
@@ -179,21 +218,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
179
218
|
return;
|
|
180
219
|
}
|
|
181
220
|
|
|
182
|
-
const
|
|
183
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
184
|
-
contractAddress,
|
|
185
|
-
null,
|
|
186
|
-
async (call, execScopes) => {
|
|
187
|
-
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 });
|
|
188
227
|
},
|
|
189
|
-
|
|
228
|
+
anchorBlockHeader,
|
|
190
229
|
jobId,
|
|
191
|
-
[scope],
|
|
192
|
-
|
|
230
|
+
scopes: [scope],
|
|
231
|
+
triggeredBy: undefined,
|
|
232
|
+
});
|
|
193
233
|
}
|
|
194
234
|
|
|
195
235
|
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
196
|
-
|
|
236
|
+
const events = (
|
|
197
237
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
198
238
|
contractAddress,
|
|
199
239
|
scopes: [scope],
|
|
@@ -201,6 +241,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
201
241
|
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
202
242
|
})
|
|
203
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;
|
|
204
253
|
}
|
|
205
254
|
|
|
206
255
|
async advanceBlocksBy(blocks: number) {
|
|
@@ -216,34 +265,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
216
265
|
this.nextBlockTimestamp += duration;
|
|
217
266
|
}
|
|
218
267
|
|
|
219
|
-
|
|
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
|
+
|
|
220
291
|
// Emit deployment nullifier
|
|
221
292
|
await this.mineBlock({
|
|
222
|
-
nullifiers: [
|
|
223
|
-
await siloNullifier(
|
|
224
|
-
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
225
|
-
instance.address.toField(),
|
|
226
|
-
),
|
|
227
|
-
],
|
|
293
|
+
nullifiers: [await this.deploymentNullifier(instance.address)],
|
|
228
294
|
});
|
|
229
295
|
|
|
230
296
|
if (!secret.equals(Fr.ZERO)) {
|
|
231
|
-
await this.
|
|
297
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
232
298
|
} else {
|
|
233
299
|
await this.contractStore.addContractInstance(instance);
|
|
234
300
|
await this.contractStore.addContractArtifact(artifact);
|
|
235
301
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
236
302
|
}
|
|
303
|
+
|
|
304
|
+
return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
|
|
237
305
|
}
|
|
238
306
|
|
|
239
|
-
|
|
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
|
+
) {
|
|
240
326
|
const partialAddress = await computePartialAddress(instance);
|
|
241
327
|
|
|
242
328
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
243
329
|
await this.contractStore.addContractInstance(instance);
|
|
244
330
|
await this.contractStore.addContractArtifact(artifact);
|
|
245
331
|
|
|
246
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
332
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
247
333
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
248
334
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
249
335
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -251,9 +337,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
251
337
|
return completeAddress;
|
|
252
338
|
}
|
|
253
339
|
|
|
254
|
-
async createAccount(secret: Fr) {
|
|
255
|
-
|
|
256
|
-
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);
|
|
257
342
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
258
343
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
259
344
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -263,17 +348,57 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
263
348
|
|
|
264
349
|
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
265
350
|
const account = await this.accountStore.getAccount(address);
|
|
266
|
-
const
|
|
351
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
352
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
267
353
|
|
|
268
354
|
const schnorr = new Schnorr();
|
|
269
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
355
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
270
356
|
|
|
271
|
-
const authWitness = new AuthWitness(messageHash,
|
|
357
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
272
358
|
|
|
273
359
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
274
360
|
}
|
|
275
361
|
|
|
276
|
-
|
|
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[] } = {}) {
|
|
277
402
|
const blockNumber = await this.getNextBlockNumber();
|
|
278
403
|
|
|
279
404
|
const txEffect = TxEffect.empty();
|
|
@@ -281,7 +406,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
281
406
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
282
407
|
|
|
283
408
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
284
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
409
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
285
410
|
|
|
286
411
|
const globals = makeGlobalVariables(undefined, {
|
|
287
412
|
blockNumber,
|
|
@@ -295,23 +420,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
295
420
|
|
|
296
421
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
297
422
|
|
|
298
|
-
await this.stateMachine.handleL2Block(block);
|
|
423
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
299
424
|
}
|
|
300
425
|
|
|
301
426
|
async privateCallNewFlow(
|
|
302
|
-
from: AztecAddress,
|
|
427
|
+
from: AztecAddress | undefined,
|
|
303
428
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
304
429
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
305
430
|
args: Fr[],
|
|
306
431
|
argsHash: Fr = Fr.zero(),
|
|
307
432
|
isStaticCall: boolean = false,
|
|
433
|
+
additionalScopes: AztecAddress[] = [],
|
|
308
434
|
jobId: string,
|
|
435
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
436
|
+
gasSettings: GasSettings,
|
|
309
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
|
+
|
|
310
445
|
this.logger.verbose(
|
|
311
|
-
`Executing external function ${await
|
|
446
|
+
`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
312
447
|
);
|
|
313
448
|
|
|
314
|
-
const artifact = await
|
|
449
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
315
450
|
if (!artifact) {
|
|
316
451
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
317
452
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -319,32 +454,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
319
454
|
throw new Error(message);
|
|
320
455
|
}
|
|
321
456
|
|
|
322
|
-
|
|
323
|
-
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
324
|
-
const effectiveScopes = from.isZero() ? [] : [from];
|
|
457
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
325
458
|
|
|
326
459
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
327
|
-
const utilityExecutor = async (call: FunctionCall, execScopes:
|
|
328
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
460
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
461
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
329
462
|
};
|
|
330
463
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
functionSelector,
|
|
464
|
+
await this.stateMachine.contractSyncService.ensureContractSynced({
|
|
465
|
+
contract: targetContractAddress,
|
|
466
|
+
functionToInvokeAfterSync: functionSelector,
|
|
335
467
|
utilityExecutor,
|
|
336
|
-
blockHeader,
|
|
468
|
+
anchorBlockHeader: blockHeader,
|
|
337
469
|
jobId,
|
|
338
|
-
|
|
339
|
-
|
|
470
|
+
scopes,
|
|
471
|
+
triggeredBy: undefined,
|
|
472
|
+
});
|
|
340
473
|
|
|
341
474
|
const blockNumber = await this.getNextBlockNumber();
|
|
342
475
|
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
346
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
347
|
-
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);
|
|
348
478
|
|
|
349
479
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
350
480
|
|
|
@@ -359,9 +489,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
359
489
|
|
|
360
490
|
const simulator = new WASMSimulator();
|
|
361
491
|
|
|
492
|
+
const transientArrayService = new TransientArrayService();
|
|
362
493
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
363
494
|
argsHash,
|
|
364
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,
|
|
365
498
|
callContext,
|
|
366
499
|
anchorBlockHeader: blockHeader,
|
|
367
500
|
utilityExecutor,
|
|
@@ -370,26 +503,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
370
503
|
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
371
504
|
noteCache,
|
|
372
505
|
taggingIndexCache,
|
|
373
|
-
|
|
506
|
+
anchoredContractData,
|
|
374
507
|
noteStore: this.noteStore,
|
|
375
508
|
keyStore: this.keyStore,
|
|
376
509
|
addressStore: this.addressStore,
|
|
377
510
|
aztecNode: this.stateMachine.node,
|
|
378
511
|
senderTaggingStore: this.senderTaggingStore,
|
|
379
512
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
380
|
-
|
|
381
|
-
|
|
513
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
514
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
515
|
+
factService: new FactService(this.factStore, scopes),
|
|
382
516
|
privateEventStore: this.privateEventStore,
|
|
383
517
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
384
518
|
jobId,
|
|
385
519
|
totalPublicCalldataCount: 0,
|
|
386
520
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
387
|
-
scopes
|
|
521
|
+
scopes,
|
|
388
522
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
389
523
|
// contract would perform, including setting senderForTags.
|
|
390
524
|
senderForTags: from,
|
|
391
525
|
simulator,
|
|
392
|
-
|
|
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,
|
|
393
536
|
});
|
|
394
537
|
|
|
395
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.
|
|
@@ -412,12 +555,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
412
555
|
);
|
|
413
556
|
const publicFunctionsCalldata = await Promise.all(
|
|
414
557
|
publicCallRequests.map(async r => {
|
|
415
|
-
const calldata = await privateExecutionOracle.
|
|
558
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
416
559
|
return new HashedValues(calldata, r.calldataHash);
|
|
417
560
|
}),
|
|
418
561
|
);
|
|
419
562
|
|
|
420
|
-
noteCache.finish();
|
|
421
563
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
422
564
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
423
565
|
} catch (err) {
|
|
@@ -429,7 +571,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
429
571
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
430
572
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
431
573
|
result,
|
|
432
|
-
(addr, sel) =>
|
|
574
|
+
(addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
|
|
433
575
|
this.stateMachine.node,
|
|
434
576
|
minRevertibleSideEffectCounter,
|
|
435
577
|
);
|
|
@@ -488,7 +630,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
488
630
|
} else if (!processedTx.revertCode.isOK()) {
|
|
489
631
|
if (processedTx.revertReason) {
|
|
490
632
|
try {
|
|
491
|
-
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
|
+
);
|
|
492
640
|
// eslint-disable-next-line no-empty
|
|
493
641
|
} catch {}
|
|
494
642
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -497,11 +645,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
497
645
|
}
|
|
498
646
|
}
|
|
499
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
|
+
|
|
500
654
|
if (isStaticCall) {
|
|
501
655
|
await checkpoint!.revert();
|
|
502
656
|
|
|
503
657
|
await forkedWorldTrees.close();
|
|
504
|
-
return executionResult.returnValues ?? [];
|
|
658
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
505
659
|
}
|
|
506
660
|
|
|
507
661
|
const txEffect = TxEffect.empty();
|
|
@@ -523,31 +677,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
523
677
|
|
|
524
678
|
await forkedWorldTrees.close();
|
|
525
679
|
|
|
526
|
-
return executionResult.returnValues ?? [];
|
|
680
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
527
681
|
}
|
|
528
682
|
|
|
529
683
|
async publicCallNewFlow(
|
|
530
|
-
from: AztecAddress,
|
|
684
|
+
from: AztecAddress | undefined,
|
|
531
685
|
targetContractAddress: AztecAddress,
|
|
532
686
|
calldata: Fr[],
|
|
533
687
|
isStaticCall: boolean,
|
|
688
|
+
gasSettings: GasSettings,
|
|
534
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
|
+
|
|
535
697
|
this.logger.verbose(
|
|
536
|
-
`Executing public function ${await
|
|
698
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
537
699
|
);
|
|
538
700
|
|
|
539
701
|
const blockNumber = await this.getNextBlockNumber();
|
|
540
702
|
|
|
541
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
542
|
-
|
|
543
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
544
|
-
|
|
545
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
546
|
-
|
|
547
703
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
548
704
|
|
|
549
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
550
|
-
|
|
551
705
|
const calldataHash = await computeCalldataHash(calldata);
|
|
552
706
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
553
707
|
|
|
@@ -595,7 +749,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
595
749
|
// may require producing reverts.
|
|
596
750
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
597
751
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
598
|
-
from,
|
|
752
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
599
753
|
targetContractAddress,
|
|
600
754
|
isStaticCall,
|
|
601
755
|
calldataHash,
|
|
@@ -640,7 +794,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
640
794
|
} else if (!processedTx.revertCode.isOK()) {
|
|
641
795
|
if (processedTx.revertReason) {
|
|
642
796
|
try {
|
|
643
|
-
await enrichPublicSimulationError(
|
|
797
|
+
await enrichPublicSimulationError(
|
|
798
|
+
processedTx.revertReason,
|
|
799
|
+
this.contractStore,
|
|
800
|
+
this.stateMachine.contractClassService,
|
|
801
|
+
anchorBlockHeader,
|
|
802
|
+
this.logger,
|
|
803
|
+
);
|
|
644
804
|
// eslint-disable-next-line no-empty
|
|
645
805
|
} catch {}
|
|
646
806
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -682,28 +842,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
682
842
|
}
|
|
683
843
|
|
|
684
844
|
async executeUtilityFunction(
|
|
845
|
+
from: AztecAddress | undefined,
|
|
685
846
|
targetContractAddress: AztecAddress,
|
|
686
847
|
functionSelector: FunctionSelector,
|
|
687
848
|
args: Fr[],
|
|
688
849
|
jobId: string,
|
|
850
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
689
851
|
) {
|
|
690
|
-
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);
|
|
691
860
|
if (!artifact) {
|
|
692
861
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
693
862
|
}
|
|
694
863
|
|
|
695
864
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
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 });
|
|
702
870
|
},
|
|
703
|
-
blockHeader,
|
|
871
|
+
anchorBlockHeader: blockHeader,
|
|
704
872
|
jobId,
|
|
705
|
-
|
|
706
|
-
|
|
873
|
+
scopes: await this.keyStore.getAccounts(),
|
|
874
|
+
triggeredBy: undefined,
|
|
875
|
+
});
|
|
707
876
|
|
|
708
877
|
const call = FunctionCall.from({
|
|
709
878
|
name: artifact.name,
|
|
@@ -716,11 +885,34 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
716
885
|
returnTypes: [],
|
|
717
886
|
});
|
|
718
887
|
|
|
719
|
-
return this.executeUtilityCall(call,
|
|
888
|
+
return this.executeUtilityCall(call, {
|
|
889
|
+
from,
|
|
890
|
+
scopes: await this.keyStore.getAccounts(),
|
|
891
|
+
jobId,
|
|
892
|
+
authorizedUtilityCallTargets,
|
|
893
|
+
});
|
|
720
894
|
}
|
|
721
895
|
|
|
722
|
-
private async executeUtilityCall(
|
|
723
|
-
|
|
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
|
+
}
|
|
724
916
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
725
917
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
726
918
|
}
|
|
@@ -731,28 +923,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
731
923
|
});
|
|
732
924
|
|
|
733
925
|
try {
|
|
734
|
-
const
|
|
926
|
+
const simulator = new WASMSimulator();
|
|
927
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
928
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId, authorizedUtilityCallTargets });
|
|
929
|
+
};
|
|
735
930
|
const oracle = new UtilityExecutionOracle({
|
|
736
|
-
|
|
931
|
+
callContext: CallContext.from({
|
|
932
|
+
msgSender: from,
|
|
933
|
+
contractAddress: call.to,
|
|
934
|
+
functionSelector: call.selector,
|
|
935
|
+
isStaticCall: true,
|
|
936
|
+
}),
|
|
737
937
|
authWitnesses: [],
|
|
738
938
|
capsules: [],
|
|
739
939
|
anchorBlockHeader,
|
|
740
|
-
|
|
940
|
+
anchoredContractData,
|
|
741
941
|
noteStore: this.noteStore,
|
|
742
942
|
keyStore: this.keyStore,
|
|
743
943
|
addressStore: this.addressStore,
|
|
744
944
|
aztecNode: this.stateMachine.node,
|
|
745
945
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
746
|
-
|
|
747
|
-
|
|
946
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
947
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
948
|
+
factService: new FactService(this.factStore, scopes),
|
|
748
949
|
privateEventStore: this.privateEventStore,
|
|
749
|
-
|
|
750
|
-
contractSyncService: this.contractSyncService,
|
|
950
|
+
txResolver: this.stateMachine.txResolver,
|
|
951
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
952
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
751
953
|
jobId,
|
|
752
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(),
|
|
753
962
|
});
|
|
754
|
-
const acirExecutionResult = await
|
|
755
|
-
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact,
|
|
963
|
+
const acirExecutionResult = await simulator
|
|
964
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
756
965
|
.catch((err: Error) => {
|
|
757
966
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
758
967
|
throw new ExecutionError(
|
|
@@ -773,13 +982,47 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
773
982
|
}
|
|
774
983
|
}
|
|
775
984
|
|
|
776
|
-
close():
|
|
985
|
+
close(): {
|
|
986
|
+
nextBlockTimestamp: bigint;
|
|
987
|
+
authwits: Map<string, AuthWitness>;
|
|
988
|
+
taggingSecretStrategies: TXETaggingSecretStrategies;
|
|
989
|
+
authorizeAllUtilityCallTargets: boolean;
|
|
990
|
+
} {
|
|
777
991
|
this.logger.debug('Exiting Top Level Context');
|
|
778
|
-
return
|
|
992
|
+
return {
|
|
993
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
994
|
+
authwits: this.authwits,
|
|
995
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
996
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
|
|
997
|
+
};
|
|
779
998
|
}
|
|
780
999
|
|
|
781
1000
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
782
|
-
const
|
|
783
|
-
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
|
+
});
|
|
784
1019
|
}
|
|
785
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 });
|