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