@aztec/txe 0.0.1-commit.b6e433891 → 0.0.1-commit.b8a057fa
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-HMC7WEOJ.js +3 -0
- package/dest/AuthRegistry-HMC7WEOJ.js.map +7 -0
- package/dest/ContractClassRegistry-TXCDCFNC.js +3 -0
- package/dest/ContractClassRegistry-TXCDCFNC.js.map +7 -0
- package/dest/ContractInstanceRegistry-2TZHWOTT.js +3 -0
- package/dest/ContractInstanceRegistry-2TZHWOTT.js.map +7 -0
- package/dest/FeeJuice-FDF3J2Q5.js +3 -0
- package/dest/FeeJuice-FDF3J2Q5.js.map +7 -0
- package/dest/HandshakeRegistry-C7JF4R54.js +3 -0
- package/dest/HandshakeRegistry-C7JF4R54.js.map +7 -0
- package/dest/MultiCallEntrypoint-IGLO227K.js +3 -0
- package/dest/MultiCallEntrypoint-IGLO227K.js.map +7 -0
- package/dest/SchnorrAccount-KCIHUCXS.js +3 -0
- package/dest/SchnorrAccount-KCIHUCXS.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-PVR6XUSN.js +3 -0
- package/dest/SchnorrInitializerlessAccount-PVR6XUSN.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 +61 -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-FRF5YZEO.js +304 -0
- package/dest/chunk-FRF5YZEO.js.map +7 -0
- package/dest/chunk-O57S6W5S.js +260 -0
- package/dest/chunk-O57S6W5S.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 +38497 -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 +38 -8
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/default_fixtures.js +207 -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 +169 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +745 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +43 -17
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +530 -297
- 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 +112 -233
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +767 -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 +16 -7
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +25 -4
- package/dest/state_machine/global_variable_builder.d.ts +10 -6
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +8 -5
- package/dest/state_machine/index.d.ts +11 -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 +89 -20
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +315 -68
- package/dest/utils/block_creation.d.ts +2 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +2 -2
- package/dest/utils/encoding.d.ts +192 -0
- package/dest/utils/encoding.d.ts.map +1 -0
- package/dest/{util → utils}/encoding.js +7 -2
- package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
- package/dest/utils/expected_failure_error.d.ts.map +1 -0
- package/dest/utils/tx_effect_creation.d.ts +1 -1
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +0 -1
- package/dest/{util → utils}/txe_account_store.d.ts +1 -1
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.d.ts +37 -0
- package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.js +161 -0
- package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/{util → utils}/txe_public_contract_data_source.js +8 -7
- package/dest/worker.bundle.js +3 -0
- package/dest/worker.bundle.js.map +7 -0
- package/dest/worker.d.ts +2 -0
- package/dest/worker.d.ts.map +1 -0
- package/dest/worker.js +92 -0
- package/package.json +38 -21
- package/src/bin/check_txe_oracle_version.ts +70 -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 +35 -7
- package/src/oracle/test-resolver/default_fixtures.ts +282 -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 +536 -0
- package/src/oracle/txe_oracle_top_level_context.ts +327 -114
- 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 +854 -905
- package/src/state_machine/archiver.ts +37 -16
- package/src/state_machine/dummy_p2p_client.ts +44 -11
- package/src/state_machine/global_variable_builder.ts +12 -11
- package/src/state_machine/index.ts +62 -31
- package/src/state_machine/mock_epoch_cache.ts +0 -4
- package/src/state_machine/synchronizer.ts +27 -6
- package/src/txe_session.ts +544 -84
- package/src/utils/block_creation.ts +2 -1
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/tx_effect_creation.ts +0 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/{util → utils}/txe_public_contract_data_source.ts +6 -6
- package/src/worker.ts +98 -0
- package/dest/util/encoding.d.ts +0 -720
- package/dest/util/encoding.d.ts.map +0 -1
- package/dest/util/expected_failure_error.d.ts.map +0 -1
- package/dest/util/txe_account_store.d.ts.map +0 -1
- package/dest/util/txe_public_contract_data_source.d.ts +0 -20
- package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
- /package/dest/{util → utils}/expected_failure_error.js +0 -0
- /package/dest/{util → utils}/txe_account_store.js +0 -0
- /package/src/{util → utils}/expected_failure_error.ts +0 -0
- /package/src/{util → utils}/txe_account_store.ts +0 -0
|
@@ -1,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';
|
|
@@ -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,9 @@ 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 { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
68
77
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
69
78
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
70
79
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -81,13 +90,14 @@ import {
|
|
|
81
90
|
collectNested,
|
|
82
91
|
} from '@aztec/stdlib/tx';
|
|
83
92
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
84
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
93
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
85
94
|
|
|
86
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
95
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
87
96
|
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
97
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
98
|
+
import type { TXEAccountStore } from '../utils/txe_account_store.js';
|
|
99
|
+
import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
|
|
100
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
91
101
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
92
102
|
|
|
93
103
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -105,25 +115,41 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
105
115
|
private accountStore: TXEAccountStore,
|
|
106
116
|
private senderTaggingStore: SenderTaggingStore,
|
|
107
117
|
private recipientTaggingStore: RecipientTaggingStore,
|
|
108
|
-
private
|
|
118
|
+
private taggingSecretSourcesStore: TaggingSecretSourcesStore,
|
|
109
119
|
private capsuleStore: CapsuleStore,
|
|
120
|
+
private factStore: FactStore,
|
|
110
121
|
private privateEventStore: PrivateEventStore,
|
|
111
122
|
private nextBlockTimestamp: bigint,
|
|
112
123
|
private version: Fr,
|
|
113
124
|
private chainId: Fr,
|
|
114
125
|
private authwits: Map<string, AuthWitness>,
|
|
115
|
-
private
|
|
126
|
+
private taggingSecretStrategy: TaggingSecretStrategy | undefined,
|
|
127
|
+
private readonly artifactResolver: TXEArtifactResolver,
|
|
128
|
+
private readonly rootPath: string,
|
|
129
|
+
private readonly packageName: string,
|
|
116
130
|
) {
|
|
117
131
|
this.logger = createLogger('txe:top_level_context');
|
|
118
132
|
this.logger.debug('Entering Top Level Context');
|
|
119
133
|
}
|
|
120
134
|
|
|
121
|
-
|
|
122
|
-
|
|
135
|
+
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
136
|
+
|
|
137
|
+
assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
138
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
139
|
+
const hint =
|
|
140
|
+
major > ORACLE_VERSION_MAJOR
|
|
141
|
+
? '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.'
|
|
142
|
+
: '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
143
|
throw new Error(
|
|
124
|
-
`Incompatible
|
|
144
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
125
145
|
);
|
|
126
146
|
}
|
|
147
|
+
this.contractOracleVersion = { major, minor };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
151
|
+
nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
|
|
152
|
+
return this.contractOracleVersion;
|
|
127
153
|
}
|
|
128
154
|
|
|
129
155
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
@@ -133,7 +159,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
133
159
|
}
|
|
134
160
|
|
|
135
161
|
// 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> {
|
|
162
|
+
log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
137
163
|
if (!LogLevels[level]) {
|
|
138
164
|
throw new Error(`Invalid log level: ${level}`);
|
|
139
165
|
}
|
|
@@ -156,12 +182,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
156
182
|
}
|
|
157
183
|
|
|
158
184
|
async getLastBlockTimestamp() {
|
|
159
|
-
return (await this.stateMachine.node.
|
|
185
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
160
186
|
}
|
|
161
187
|
|
|
162
|
-
async getLastTxEffects() {
|
|
188
|
+
async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
|
|
163
189
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
164
|
-
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
190
|
+
const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
|
|
165
191
|
|
|
166
192
|
if (block!.body.txEffects.length != 1) {
|
|
167
193
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -170,7 +196,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
170
196
|
|
|
171
197
|
const txEffects = block!.body.txEffects[0];
|
|
172
198
|
|
|
173
|
-
|
|
199
|
+
const privateLogs = txEffects.privateLogs;
|
|
200
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
201
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
txHash: txEffects.txHash,
|
|
206
|
+
noteHashes: txEffects.noteHashes,
|
|
207
|
+
nullifiers: txEffects.nullifiers,
|
|
208
|
+
privateLogs,
|
|
209
|
+
};
|
|
174
210
|
}
|
|
175
211
|
|
|
176
212
|
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
@@ -184,7 +220,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
184
220
|
contractAddress,
|
|
185
221
|
null,
|
|
186
222
|
async (call, execScopes) => {
|
|
187
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
223
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
188
224
|
},
|
|
189
225
|
blockHeader,
|
|
190
226
|
jobId,
|
|
@@ -193,7 +229,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
193
229
|
}
|
|
194
230
|
|
|
195
231
|
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
196
|
-
|
|
232
|
+
const events = (
|
|
197
233
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
198
234
|
contractAddress,
|
|
199
235
|
scopes: [scope],
|
|
@@ -201,6 +237,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
201
237
|
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
202
238
|
})
|
|
203
239
|
).map(e => e.packedEvent);
|
|
240
|
+
|
|
241
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
242
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
243
|
+
}
|
|
244
|
+
if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
245
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return events;
|
|
204
249
|
}
|
|
205
250
|
|
|
206
251
|
async advanceBlocksBy(blocks: number) {
|
|
@@ -216,34 +261,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
216
261
|
this.nextBlockTimestamp += duration;
|
|
217
262
|
}
|
|
218
263
|
|
|
219
|
-
|
|
264
|
+
private deploymentNullifier(address: AztecAddress): Promise<Fr> {
|
|
265
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async deploy(
|
|
269
|
+
contractPath: string,
|
|
270
|
+
initializer: string,
|
|
271
|
+
args: Fr[],
|
|
272
|
+
secret: Fr,
|
|
273
|
+
salt: Fr,
|
|
274
|
+
deployer: AztecAddress,
|
|
275
|
+
): Promise<Fr[]> {
|
|
276
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
277
|
+
rootPath: this.rootPath,
|
|
278
|
+
packageName: this.packageName,
|
|
279
|
+
contractPath,
|
|
280
|
+
initializer,
|
|
281
|
+
args,
|
|
282
|
+
secret,
|
|
283
|
+
salt,
|
|
284
|
+
deployer,
|
|
285
|
+
});
|
|
286
|
+
|
|
220
287
|
// Emit deployment nullifier
|
|
221
288
|
await this.mineBlock({
|
|
222
|
-
nullifiers: [
|
|
223
|
-
await siloNullifier(
|
|
224
|
-
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
225
|
-
instance.address.toField(),
|
|
226
|
-
),
|
|
227
|
-
],
|
|
289
|
+
nullifiers: [await this.deploymentNullifier(instance.address)],
|
|
228
290
|
});
|
|
229
291
|
|
|
230
292
|
if (!secret.equals(Fr.ZERO)) {
|
|
231
|
-
await this.
|
|
293
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
232
294
|
} else {
|
|
233
295
|
await this.contractStore.addContractInstance(instance);
|
|
234
296
|
await this.contractStore.addContractArtifact(artifact);
|
|
235
297
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
236
298
|
}
|
|
299
|
+
|
|
300
|
+
return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
305
|
+
*/
|
|
306
|
+
async mineDeploymentNullifiers(addresses: AztecAddress[]) {
|
|
307
|
+
await this.mineBlock({
|
|
308
|
+
nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async addAccount(secret: Fr) {
|
|
313
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
314
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
237
315
|
}
|
|
238
316
|
|
|
239
|
-
async
|
|
317
|
+
private async registerContractAndAddAccount(
|
|
318
|
+
artifact: ContractArtifact,
|
|
319
|
+
instance: ContractInstanceWithAddress,
|
|
320
|
+
secret: Fr,
|
|
321
|
+
) {
|
|
240
322
|
const partialAddress = await computePartialAddress(instance);
|
|
241
323
|
|
|
242
324
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
243
325
|
await this.contractStore.addContractInstance(instance);
|
|
244
326
|
await this.contractStore.addContractArtifact(artifact);
|
|
245
327
|
|
|
246
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
328
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
247
329
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
248
330
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
249
331
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -253,7 +335,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
253
335
|
|
|
254
336
|
async createAccount(secret: Fr) {
|
|
255
337
|
// This is a foot gun !
|
|
256
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
338
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
|
|
257
339
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
258
340
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
259
341
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -263,17 +345,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
263
345
|
|
|
264
346
|
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
265
347
|
const account = await this.accountStore.getAccount(address);
|
|
266
|
-
const
|
|
348
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
349
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
267
350
|
|
|
268
351
|
const schnorr = new Schnorr();
|
|
269
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
352
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
270
353
|
|
|
271
|
-
const authWitness = new AuthWitness(messageHash,
|
|
354
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
272
355
|
|
|
273
356
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
274
357
|
}
|
|
275
358
|
|
|
276
|
-
|
|
359
|
+
setTaggingSecretStrategy(strategy: Option<TaggingSecretStrategy>): void {
|
|
360
|
+
this.taggingSecretStrategy = strategy.value;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
|
|
364
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
365
|
+
const { size } = await this.stateMachine.synchronizer
|
|
366
|
+
.getCommitted()
|
|
367
|
+
.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
368
|
+
const leafIndex = new Fr(size);
|
|
369
|
+
|
|
370
|
+
const message = new L1ToL2Message(
|
|
371
|
+
new L1Actor(sender, this.chainId.toNumber()),
|
|
372
|
+
new L2Actor(recipient, this.version.toNumber()),
|
|
373
|
+
content,
|
|
374
|
+
secretHash,
|
|
375
|
+
leafIndex,
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
await this.mineBlock({ l1ToL2Messages: [message.hash()] });
|
|
379
|
+
|
|
380
|
+
return leafIndex;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
|
|
277
384
|
const blockNumber = await this.getNextBlockNumber();
|
|
278
385
|
|
|
279
386
|
const txEffect = TxEffect.empty();
|
|
@@ -281,7 +388,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
281
388
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
282
389
|
|
|
283
390
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
284
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
391
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
285
392
|
|
|
286
393
|
const globals = makeGlobalVariables(undefined, {
|
|
287
394
|
blockNumber,
|
|
@@ -295,23 +402,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
295
402
|
|
|
296
403
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
297
404
|
|
|
298
|
-
await this.stateMachine.handleL2Block(block);
|
|
405
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
299
406
|
}
|
|
300
407
|
|
|
301
408
|
async privateCallNewFlow(
|
|
302
|
-
from: AztecAddress,
|
|
409
|
+
from: AztecAddress | undefined,
|
|
303
410
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
304
411
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
305
412
|
args: Fr[],
|
|
306
413
|
argsHash: Fr = Fr.zero(),
|
|
307
414
|
isStaticCall: boolean = false,
|
|
415
|
+
additionalScopes: AztecAddress[] = [],
|
|
308
416
|
jobId: string,
|
|
417
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
418
|
+
gasSettings: GasSettings,
|
|
309
419
|
) {
|
|
420
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
421
|
+
const anchoredContractData = new AnchoredContractData(
|
|
422
|
+
this.contractStore,
|
|
423
|
+
this.stateMachine.contractClassService,
|
|
424
|
+
blockHeader,
|
|
425
|
+
);
|
|
426
|
+
|
|
310
427
|
this.logger.verbose(
|
|
311
|
-
`Executing external function ${await
|
|
428
|
+
`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
312
429
|
);
|
|
313
430
|
|
|
314
|
-
const artifact = await
|
|
431
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
315
432
|
if (!artifact) {
|
|
316
433
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
317
434
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -319,32 +436,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
319
436
|
throw new Error(message);
|
|
320
437
|
}
|
|
321
438
|
|
|
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];
|
|
439
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
325
440
|
|
|
326
441
|
// 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);
|
|
442
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
443
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
329
444
|
};
|
|
330
445
|
|
|
331
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
332
446
|
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
333
447
|
targetContractAddress,
|
|
334
448
|
functionSelector,
|
|
335
449
|
utilityExecutor,
|
|
336
450
|
blockHeader,
|
|
337
451
|
jobId,
|
|
338
|
-
|
|
452
|
+
scopes,
|
|
339
453
|
);
|
|
340
454
|
|
|
341
455
|
const blockNumber = await this.getNextBlockNumber();
|
|
342
456
|
|
|
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());
|
|
457
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
458
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
348
459
|
|
|
349
460
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
350
461
|
|
|
@@ -359,9 +470,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
359
470
|
|
|
360
471
|
const simulator = new WASMSimulator();
|
|
361
472
|
|
|
473
|
+
const transientArrayService = new TransientArrayService();
|
|
474
|
+
const taggingSecretStrategy = this.taggingSecretStrategy;
|
|
362
475
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
363
476
|
argsHash,
|
|
364
477
|
txContext,
|
|
478
|
+
txRequestSalt: Fr.ZERO,
|
|
365
479
|
callContext,
|
|
366
480
|
anchorBlockHeader: blockHeader,
|
|
367
481
|
utilityExecutor,
|
|
@@ -370,26 +484,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
370
484
|
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
371
485
|
noteCache,
|
|
372
486
|
taggingIndexCache,
|
|
373
|
-
|
|
487
|
+
anchoredContractData,
|
|
374
488
|
noteStore: this.noteStore,
|
|
375
489
|
keyStore: this.keyStore,
|
|
376
490
|
addressStore: this.addressStore,
|
|
377
491
|
aztecNode: this.stateMachine.node,
|
|
378
492
|
senderTaggingStore: this.senderTaggingStore,
|
|
379
493
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
380
|
-
|
|
381
|
-
|
|
494
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
495
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
496
|
+
factService: new FactService(this.factStore, scopes),
|
|
382
497
|
privateEventStore: this.privateEventStore,
|
|
383
498
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
384
499
|
jobId,
|
|
385
500
|
totalPublicCalldataCount: 0,
|
|
386
501
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
387
|
-
scopes
|
|
502
|
+
scopes,
|
|
388
503
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
389
504
|
// contract would perform, including setting senderForTags.
|
|
390
505
|
senderForTags: from,
|
|
391
506
|
simulator,
|
|
392
|
-
|
|
507
|
+
txResolver: this.stateMachine.txResolver,
|
|
508
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
509
|
+
hooks: composeHooks({
|
|
510
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
|
|
511
|
+
isStaticCall ? 'private view' : 'private',
|
|
512
|
+
authorizedUtilityCallTargets,
|
|
513
|
+
),
|
|
514
|
+
// Only configure the hook when a strategy was explicitly set, so that otherwise the default tagging secret
|
|
515
|
+
// strategy is exercised.
|
|
516
|
+
resolveTaggingSecretStrategy: taggingSecretStrategy ? () => Promise.resolve(taggingSecretStrategy) : undefined,
|
|
517
|
+
}),
|
|
518
|
+
transientArrayService,
|
|
393
519
|
});
|
|
394
520
|
|
|
395
521
|
// 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 +538,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
412
538
|
);
|
|
413
539
|
const publicFunctionsCalldata = await Promise.all(
|
|
414
540
|
publicCallRequests.map(async r => {
|
|
415
|
-
const calldata = await privateExecutionOracle.
|
|
541
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
416
542
|
return new HashedValues(calldata, r.calldataHash);
|
|
417
543
|
}),
|
|
418
544
|
);
|
|
419
545
|
|
|
420
|
-
noteCache.finish();
|
|
421
546
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
422
547
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
423
548
|
} catch (err) {
|
|
@@ -429,7 +554,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
429
554
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
430
555
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
431
556
|
result,
|
|
432
|
-
(addr, sel) =>
|
|
557
|
+
(addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
|
|
433
558
|
this.stateMachine.node,
|
|
434
559
|
minRevertibleSideEffectCounter,
|
|
435
560
|
);
|
|
@@ -441,7 +566,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
441
566
|
globals.version = this.version;
|
|
442
567
|
globals.gasFees = GasFees.empty();
|
|
443
568
|
|
|
444
|
-
|
|
569
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
445
570
|
|
|
446
571
|
const bindings = this.logger.getBindings();
|
|
447
572
|
const contractsDB = new PublicContractsDB(
|
|
@@ -456,11 +581,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
456
581
|
collectStatistics: false,
|
|
457
582
|
collectCallMetadata: true,
|
|
458
583
|
});
|
|
584
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
585
|
+
const forkId = forkedWorldTrees.getRevision().forkId;
|
|
459
586
|
const processor = new PublicProcessor(
|
|
460
587
|
globals,
|
|
461
588
|
guardedMerkleTrees,
|
|
462
589
|
contractsDB,
|
|
463
|
-
new
|
|
590
|
+
new PublicTxSimulator(
|
|
591
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
592
|
+
globals,
|
|
593
|
+
contractsDB,
|
|
594
|
+
forkId,
|
|
595
|
+
config,
|
|
596
|
+
bindings,
|
|
597
|
+
),
|
|
464
598
|
new TestDateProvider(),
|
|
465
599
|
undefined,
|
|
466
600
|
createLogger('simulator:public-processor', bindings),
|
|
@@ -488,7 +622,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
488
622
|
} else if (!processedTx.revertCode.isOK()) {
|
|
489
623
|
if (processedTx.revertReason) {
|
|
490
624
|
try {
|
|
491
|
-
await enrichPublicSimulationError(
|
|
625
|
+
await enrichPublicSimulationError(
|
|
626
|
+
processedTx.revertReason,
|
|
627
|
+
this.contractStore,
|
|
628
|
+
this.stateMachine.contractClassService,
|
|
629
|
+
await this.stateMachine.anchorBlockStore.getBlockHeader(),
|
|
630
|
+
this.logger,
|
|
631
|
+
);
|
|
492
632
|
// eslint-disable-next-line no-empty
|
|
493
633
|
} catch {}
|
|
494
634
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -497,11 +637,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
497
637
|
}
|
|
498
638
|
}
|
|
499
639
|
|
|
640
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
641
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
642
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
643
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
644
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
645
|
+
|
|
500
646
|
if (isStaticCall) {
|
|
501
647
|
await checkpoint!.revert();
|
|
502
|
-
|
|
503
|
-
await forkedWorldTrees.close();
|
|
504
|
-
return executionResult.returnValues ?? [];
|
|
648
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
505
649
|
}
|
|
506
650
|
|
|
507
651
|
const txEffect = TxEffect.empty();
|
|
@@ -521,33 +665,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
521
665
|
|
|
522
666
|
await this.stateMachine.handleL2Block(l2Block);
|
|
523
667
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
return executionResult.returnValues ?? [];
|
|
668
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
527
669
|
}
|
|
528
670
|
|
|
529
671
|
async publicCallNewFlow(
|
|
530
|
-
from: AztecAddress,
|
|
672
|
+
from: AztecAddress | undefined,
|
|
531
673
|
targetContractAddress: AztecAddress,
|
|
532
674
|
calldata: Fr[],
|
|
533
675
|
isStaticCall: boolean,
|
|
676
|
+
gasSettings: GasSettings,
|
|
534
677
|
) {
|
|
678
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
679
|
+
const anchoredContractData = new AnchoredContractData(
|
|
680
|
+
this.contractStore,
|
|
681
|
+
this.stateMachine.contractClassService,
|
|
682
|
+
anchorBlockHeader,
|
|
683
|
+
);
|
|
684
|
+
|
|
535
685
|
this.logger.verbose(
|
|
536
|
-
`Executing public function ${await
|
|
686
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
537
687
|
);
|
|
538
688
|
|
|
539
689
|
const blockNumber = await this.getNextBlockNumber();
|
|
540
690
|
|
|
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
691
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
548
692
|
|
|
549
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
550
|
-
|
|
551
693
|
const calldataHash = await computeCalldataHash(calldata);
|
|
552
694
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
553
695
|
|
|
@@ -558,7 +700,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
558
700
|
globals.version = this.version;
|
|
559
701
|
globals.gasFees = GasFees.empty();
|
|
560
702
|
|
|
561
|
-
|
|
703
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
562
704
|
|
|
563
705
|
const bindings2 = this.logger.getBindings();
|
|
564
706
|
const contractsDB = new PublicContractsDB(
|
|
@@ -573,7 +715,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
573
715
|
collectStatistics: false,
|
|
574
716
|
collectCallMetadata: true,
|
|
575
717
|
});
|
|
576
|
-
|
|
718
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
719
|
+
const forkId2 = forkedWorldTrees.getRevision().forkId;
|
|
720
|
+
const simulator = new PublicTxSimulator(
|
|
721
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
722
|
+
globals,
|
|
723
|
+
contractsDB,
|
|
724
|
+
forkId2,
|
|
725
|
+
config,
|
|
726
|
+
bindings2,
|
|
727
|
+
);
|
|
577
728
|
const processor = new PublicProcessor(
|
|
578
729
|
globals,
|
|
579
730
|
guardedMerkleTrees,
|
|
@@ -595,7 +746,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
595
746
|
// may require producing reverts.
|
|
596
747
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
597
748
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
598
|
-
from,
|
|
749
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
599
750
|
targetContractAddress,
|
|
600
751
|
isStaticCall,
|
|
601
752
|
calldataHash,
|
|
@@ -640,7 +791,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
640
791
|
} else if (!processedTx.revertCode.isOK()) {
|
|
641
792
|
if (processedTx.revertReason) {
|
|
642
793
|
try {
|
|
643
|
-
await enrichPublicSimulationError(
|
|
794
|
+
await enrichPublicSimulationError(
|
|
795
|
+
processedTx.revertReason,
|
|
796
|
+
this.contractStore,
|
|
797
|
+
this.stateMachine.contractClassService,
|
|
798
|
+
anchorBlockHeader,
|
|
799
|
+
this.logger,
|
|
800
|
+
);
|
|
644
801
|
// eslint-disable-next-line no-empty
|
|
645
802
|
} catch {}
|
|
646
803
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -653,9 +810,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
653
810
|
|
|
654
811
|
if (isStaticCall) {
|
|
655
812
|
await checkpoint!.revert();
|
|
656
|
-
|
|
657
|
-
await forkedWorldTrees.close();
|
|
658
|
-
|
|
659
813
|
return returnValues ?? [];
|
|
660
814
|
}
|
|
661
815
|
|
|
@@ -676,33 +830,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
676
830
|
|
|
677
831
|
await this.stateMachine.handleL2Block(l2Block);
|
|
678
832
|
|
|
679
|
-
await forkedWorldTrees.close();
|
|
680
|
-
|
|
681
833
|
return returnValues ?? [];
|
|
682
834
|
}
|
|
683
835
|
|
|
684
836
|
async executeUtilityFunction(
|
|
837
|
+
from: AztecAddress | undefined,
|
|
685
838
|
targetContractAddress: AztecAddress,
|
|
686
839
|
functionSelector: FunctionSelector,
|
|
687
840
|
args: Fr[],
|
|
688
841
|
jobId: string,
|
|
842
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
689
843
|
) {
|
|
690
|
-
const
|
|
844
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
845
|
+
const anchoredContractData = new AnchoredContractData(
|
|
846
|
+
this.contractStore,
|
|
847
|
+
this.stateMachine.contractClassService,
|
|
848
|
+
blockHeader,
|
|
849
|
+
);
|
|
850
|
+
|
|
851
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
691
852
|
if (!artifact) {
|
|
692
853
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
693
854
|
}
|
|
694
855
|
|
|
695
856
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
696
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
697
857
|
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
698
858
|
targetContractAddress,
|
|
699
859
|
functionSelector,
|
|
700
860
|
async (call, execScopes) => {
|
|
701
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
861
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
702
862
|
},
|
|
703
863
|
blockHeader,
|
|
704
864
|
jobId,
|
|
705
|
-
|
|
865
|
+
await this.keyStore.getAccounts(),
|
|
706
866
|
);
|
|
707
867
|
|
|
708
868
|
const call = FunctionCall.from({
|
|
@@ -716,11 +876,34 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
716
876
|
returnTypes: [],
|
|
717
877
|
});
|
|
718
878
|
|
|
719
|
-
return this.executeUtilityCall(call,
|
|
879
|
+
return this.executeUtilityCall(call, {
|
|
880
|
+
from,
|
|
881
|
+
scopes: await this.keyStore.getAccounts(),
|
|
882
|
+
jobId,
|
|
883
|
+
authorizedUtilityCallTargets,
|
|
884
|
+
});
|
|
720
885
|
}
|
|
721
886
|
|
|
722
|
-
private async executeUtilityCall(
|
|
723
|
-
|
|
887
|
+
private async executeUtilityCall(
|
|
888
|
+
call: FunctionCall,
|
|
889
|
+
{
|
|
890
|
+
from = AztecAddress.NULL_MSG_SENDER,
|
|
891
|
+
scopes,
|
|
892
|
+
jobId,
|
|
893
|
+
authorizedUtilityCallTargets = [],
|
|
894
|
+
}: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
|
|
895
|
+
): Promise<Fr[]> {
|
|
896
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
897
|
+
const anchoredContractData = new AnchoredContractData(
|
|
898
|
+
this.contractStore,
|
|
899
|
+
this.stateMachine.contractClassService,
|
|
900
|
+
anchorBlockHeader,
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
904
|
+
if (!entryPointArtifact) {
|
|
905
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
906
|
+
}
|
|
724
907
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
725
908
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
726
909
|
}
|
|
@@ -731,28 +914,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
731
914
|
});
|
|
732
915
|
|
|
733
916
|
try {
|
|
734
|
-
const
|
|
917
|
+
const simulator = new WASMSimulator();
|
|
918
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
919
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
|
|
920
|
+
};
|
|
735
921
|
const oracle = new UtilityExecutionOracle({
|
|
736
|
-
|
|
922
|
+
callContext: CallContext.from({
|
|
923
|
+
msgSender: from,
|
|
924
|
+
contractAddress: call.to,
|
|
925
|
+
functionSelector: call.selector,
|
|
926
|
+
isStaticCall: true,
|
|
927
|
+
}),
|
|
737
928
|
authWitnesses: [],
|
|
738
929
|
capsules: [],
|
|
739
930
|
anchorBlockHeader,
|
|
740
|
-
|
|
931
|
+
anchoredContractData,
|
|
741
932
|
noteStore: this.noteStore,
|
|
742
933
|
keyStore: this.keyStore,
|
|
743
934
|
addressStore: this.addressStore,
|
|
744
935
|
aztecNode: this.stateMachine.node,
|
|
745
936
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
746
|
-
|
|
747
|
-
|
|
937
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
938
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
939
|
+
factService: new FactService(this.factStore, scopes),
|
|
748
940
|
privateEventStore: this.privateEventStore,
|
|
749
|
-
|
|
750
|
-
contractSyncService: this.contractSyncService,
|
|
941
|
+
txResolver: this.stateMachine.txResolver,
|
|
942
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
943
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
751
944
|
jobId,
|
|
752
945
|
scopes,
|
|
946
|
+
simulator,
|
|
947
|
+
hooks: composeHooks({
|
|
948
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
949
|
+
}),
|
|
950
|
+
utilityExecutor,
|
|
951
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
952
|
+
transientArrayService: new TransientArrayService(),
|
|
753
953
|
});
|
|
754
|
-
const acirExecutionResult = await
|
|
755
|
-
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact,
|
|
954
|
+
const acirExecutionResult = await simulator
|
|
955
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
756
956
|
.catch((err: Error) => {
|
|
757
957
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
758
958
|
throw new ExecutionError(
|
|
@@ -773,13 +973,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
773
973
|
}
|
|
774
974
|
}
|
|
775
975
|
|
|
776
|
-
close(): [bigint, Map<string, AuthWitness
|
|
976
|
+
close(): [bigint, Map<string, AuthWitness>, TaggingSecretStrategy | undefined] {
|
|
777
977
|
this.logger.debug('Exiting Top Level Context');
|
|
778
|
-
return [this.nextBlockTimestamp, this.authwits];
|
|
978
|
+
return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy];
|
|
779
979
|
}
|
|
780
980
|
|
|
781
981
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
782
|
-
const
|
|
783
|
-
return
|
|
982
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
983
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
private buildAuthorizeUtilityCallHook(
|
|
987
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
988
|
+
authorizedTargets: AztecAddress[],
|
|
989
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
990
|
+
if (authorizedTargets.length === 0) {
|
|
991
|
+
return undefined;
|
|
992
|
+
}
|
|
993
|
+
return req =>
|
|
994
|
+
Promise.resolve({
|
|
995
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
996
|
+
});
|
|
784
997
|
}
|
|
785
998
|
}
|