@aztec/txe 0.0.1-commit.2ed92850 → 0.0.1-commit.2f68f620
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/ContractClassRegistry-PII7Q556.js +3 -0
- package/dest/ContractClassRegistry-PII7Q556.js.map +7 -0
- package/dest/ContractInstanceRegistry-3MHLGFNZ.js +3 -0
- package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +7 -0
- package/dest/FeeJuice-TQV5AQK7.js +3 -0
- package/dest/FeeJuice-TQV5AQK7.js.map +7 -0
- package/dest/MultiCallEntrypoint-SBJUIJY7.js +3 -0
- package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +7 -0
- package/dest/SchnorrAccount-MQXPIZ44.js +3 -0
- package/dest/SchnorrAccount-MQXPIZ44.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-BJVAAXNA.js +3 -0
- package/dest/chunk-BJVAAXNA.js.map +7 -0
- package/dest/chunk-CDITIZHX.js +257 -0
- package/dest/chunk-CDITIZHX.js.map +7 -0
- package/dest/chunk-W2NSX64C.js +304 -0
- package/dest/chunk-W2NSX64C.js.map +7 -0
- package/dest/constants.d.ts +5 -1
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +8 -0
- package/dest/dispatcher_pool.d.ts +67 -0
- package/dest/dispatcher_pool.d.ts.map +1 -0
- package/dest/dispatcher_pool.js +284 -0
- package/dest/index.d.ts +185 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +71 -157
- package/dest/metafile.json +36545 -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 +56 -30
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/test-resolver/fixtures.d.ts +43 -0
- package/dest/oracle/test-resolver/fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/fixtures.js +39 -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 +33 -0
- package/dest/oracle/test-resolver/resolver.d.ts +34 -0
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
- package/dest/oracle/test-resolver/resolver.js +114 -0
- package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +57 -16
- package/dest/oracle/txe_oracle_registry.d.ts +147 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +562 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +45 -26
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +251 -86
- 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 +96 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +815 -613
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +32 -21
- package/dest/state_machine/dummy_p2p_client.d.ts +26 -16
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +44 -20
- package/dest/state_machine/global_variable_builder.d.ts +9 -4
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +9 -3
- package/dest/state_machine/index.d.ts +10 -6
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +35 -12
- package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +33 -2
- package/dest/state_machine/synchronizer.d.ts +5 -5
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +4 -4
- package/dest/txe_session.d.ts +80 -15
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +241 -44
- package/dest/utils/block_creation.d.ts +1 -1
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +3 -1
- package/dest/utils/encoding.d.ts +191 -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/{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 +6 -25
- 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 +10 -0
- package/src/dispatcher_pool.ts +316 -0
- package/src/index.ts +97 -190
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +58 -35
- package/src/oracle/test-resolver/fixtures.ts +84 -0
- package/src/oracle/test-resolver/index.ts +45 -0
- package/src/oracle/test-resolver/resolver.ts +165 -0
- package/src/oracle/txe_oracle_public_context.ts +74 -16
- package/src/oracle/txe_oracle_registry.ts +401 -0
- package/src/oracle/txe_oracle_top_level_context.ts +317 -147
- 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 +1000 -988
- package/src/state_machine/archiver.ts +44 -20
- package/src/state_machine/dummy_p2p_client.ts +70 -32
- package/src/state_machine/global_variable_builder.ts +18 -3
- package/src/state_machine/index.ts +48 -13
- package/src/state_machine/mock_epoch_cache.ts +43 -3
- package/src/state_machine/synchronizer.ts +5 -5
- package/src/txe_session.ts +363 -109
- package/src/utils/block_creation.ts +3 -1
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/{util → utils}/txe_public_contract_data_source.ts +10 -38
- 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_contract_store.d.ts +0 -12
- package/dest/util/txe_contract_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.js +0 -22
- package/dest/util/txe_public_contract_data_source.d.ts +0 -21
- package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
- package/src/util/txe_contract_store.ts +0 -36
- /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,9 +1,6 @@
|
|
|
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';
|
|
@@ -14,15 +11,18 @@ import { TestDateProvider } from '@aztec/foundation/timer';
|
|
|
14
11
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
12
|
import {
|
|
16
13
|
AddressStore,
|
|
14
|
+
CapsuleService,
|
|
17
15
|
CapsuleStore,
|
|
16
|
+
type ContractStore,
|
|
17
|
+
type ExecutionHooks,
|
|
18
18
|
NoteStore,
|
|
19
|
-
|
|
19
|
+
ORACLE_VERSION_MAJOR,
|
|
20
20
|
PrivateEventStore,
|
|
21
21
|
RecipientTaggingStore,
|
|
22
22
|
SenderAddressBookStore,
|
|
23
23
|
SenderTaggingStore,
|
|
24
|
+
composeHooks,
|
|
24
25
|
enrichPublicSimulationError,
|
|
25
|
-
syncState,
|
|
26
26
|
} from '@aztec/pxe/server';
|
|
27
27
|
import {
|
|
28
28
|
ExecutionNoteCache,
|
|
@@ -45,10 +45,10 @@ import {
|
|
|
45
45
|
witnessMapToFields,
|
|
46
46
|
} from '@aztec/simulator/client';
|
|
47
47
|
import {
|
|
48
|
-
CppPublicTxSimulator,
|
|
49
48
|
GuardedMerkleTreeOperations,
|
|
50
49
|
PublicContractsDB,
|
|
51
50
|
PublicProcessor,
|
|
51
|
+
PublicTxSimulator,
|
|
52
52
|
} from '@aztec/simulator/server';
|
|
53
53
|
import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
54
54
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
PrivateToPublicAccumulatedData,
|
|
64
64
|
PublicCallRequest,
|
|
65
65
|
} from '@aztec/stdlib/kernel';
|
|
66
|
+
import { hashPublicKey } from '@aztec/stdlib/keys';
|
|
66
67
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
67
68
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
68
69
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -79,14 +80,14 @@ import {
|
|
|
79
80
|
collectNested,
|
|
80
81
|
} from '@aztec/stdlib/tx';
|
|
81
82
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
82
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
83
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
83
84
|
|
|
84
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
85
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
85
86
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
86
|
-
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
87
|
-
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
88
|
-
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
89
87
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
88
|
+
import type { TXEAccountStore } from '../utils/txe_account_store.js';
|
|
89
|
+
import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
|
|
90
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
90
91
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
91
92
|
|
|
92
93
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -97,7 +98,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
97
98
|
|
|
98
99
|
constructor(
|
|
99
100
|
private stateMachine: TXEStateMachine,
|
|
100
|
-
private contractStore:
|
|
101
|
+
private contractStore: ContractStore,
|
|
101
102
|
private noteStore: NoteStore,
|
|
102
103
|
private keyStore: KeyStore,
|
|
103
104
|
private addressStore: AddressStore,
|
|
@@ -107,59 +108,74 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
107
108
|
private senderAddressBookStore: SenderAddressBookStore,
|
|
108
109
|
private capsuleStore: CapsuleStore,
|
|
109
110
|
private privateEventStore: PrivateEventStore,
|
|
110
|
-
private jobId: string,
|
|
111
111
|
private nextBlockTimestamp: bigint,
|
|
112
112
|
private version: Fr,
|
|
113
113
|
private chainId: Fr,
|
|
114
114
|
private authwits: Map<string, AuthWitness>,
|
|
115
|
+
private readonly artifactResolver: TXEArtifactResolver,
|
|
116
|
+
private readonly rootPath: string,
|
|
117
|
+
private readonly packageName: string,
|
|
115
118
|
) {
|
|
116
119
|
this.logger = createLogger('txe:top_level_context');
|
|
117
120
|
this.logger.debug('Entering Top Level Context');
|
|
118
121
|
}
|
|
119
122
|
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
124
|
+
|
|
125
|
+
assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
126
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
127
|
+
const hint =
|
|
128
|
+
major > ORACLE_VERSION_MAJOR
|
|
129
|
+
? '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.'
|
|
130
|
+
: '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.';
|
|
122
131
|
throw new Error(
|
|
123
|
-
`Incompatible
|
|
132
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
124
133
|
);
|
|
125
134
|
}
|
|
135
|
+
this.contractOracleVersion = { major, minor };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
139
|
+
nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
|
|
140
|
+
return this.contractOracleVersion;
|
|
126
141
|
}
|
|
127
142
|
|
|
128
143
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
129
144
|
// setup.
|
|
130
|
-
|
|
145
|
+
getRandomField(): Fr {
|
|
131
146
|
return Fr.random();
|
|
132
147
|
}
|
|
133
148
|
|
|
134
149
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
135
|
-
|
|
150
|
+
log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
136
151
|
if (!LogLevels[level]) {
|
|
137
|
-
throw new Error(`Invalid
|
|
152
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
138
153
|
}
|
|
139
154
|
const levelName = LogLevels[level];
|
|
140
155
|
|
|
141
156
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
157
|
+
return Promise.resolve();
|
|
142
158
|
}
|
|
143
159
|
|
|
144
|
-
|
|
160
|
+
getDefaultAddress(): AztecAddress {
|
|
145
161
|
return DEFAULT_ADDRESS;
|
|
146
162
|
}
|
|
147
163
|
|
|
148
|
-
async
|
|
164
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
149
165
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
150
166
|
}
|
|
151
167
|
|
|
152
|
-
|
|
168
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
153
169
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
154
170
|
}
|
|
155
171
|
|
|
156
|
-
async
|
|
157
|
-
return (await this.stateMachine.node.
|
|
172
|
+
async getLastBlockTimestamp() {
|
|
173
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
158
174
|
}
|
|
159
175
|
|
|
160
|
-
async
|
|
176
|
+
async getLastTxEffects() {
|
|
161
177
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
-
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
178
|
+
const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
|
|
163
179
|
|
|
164
180
|
if (block!.body.txEffects.length != 1) {
|
|
165
181
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,11 +184,40 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
184
|
|
|
169
185
|
const txEffects = block!.body.txEffects[0];
|
|
170
186
|
|
|
171
|
-
|
|
187
|
+
const privateLogs = txEffects.privateLogs;
|
|
188
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
189
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
txHash: txEffects.txHash,
|
|
194
|
+
noteHashes: txEffects.noteHashes,
|
|
195
|
+
nullifiers: txEffects.nullifiers,
|
|
196
|
+
privateLogs,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
201
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
202
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
207
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
208
|
+
contractAddress,
|
|
209
|
+
null,
|
|
210
|
+
async (call, execScopes) => {
|
|
211
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
212
|
+
},
|
|
213
|
+
blockHeader,
|
|
214
|
+
jobId,
|
|
215
|
+
[scope],
|
|
216
|
+
);
|
|
172
217
|
}
|
|
173
218
|
|
|
174
|
-
async
|
|
175
|
-
|
|
219
|
+
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
220
|
+
const events = (
|
|
176
221
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
177
222
|
contractAddress,
|
|
178
223
|
scopes: [scope],
|
|
@@ -180,9 +225,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
180
225
|
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
181
226
|
})
|
|
182
227
|
).map(e => e.packedEvent);
|
|
228
|
+
|
|
229
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
230
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
231
|
+
}
|
|
232
|
+
if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
233
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return events;
|
|
183
237
|
}
|
|
184
238
|
|
|
185
|
-
async
|
|
239
|
+
async advanceBlocksBy(blocks: number) {
|
|
186
240
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
187
241
|
|
|
188
242
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -190,37 +244,81 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
190
244
|
}
|
|
191
245
|
}
|
|
192
246
|
|
|
193
|
-
|
|
247
|
+
advanceTimestampBy(duration: UInt64) {
|
|
194
248
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
195
249
|
this.nextBlockTimestamp += duration;
|
|
196
250
|
}
|
|
197
251
|
|
|
198
|
-
|
|
252
|
+
private deploymentNullifier(address: AztecAddress): Promise<Fr> {
|
|
253
|
+
return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async deploy(
|
|
257
|
+
contractPath: string,
|
|
258
|
+
initializer: string,
|
|
259
|
+
args: Fr[],
|
|
260
|
+
secret: Fr,
|
|
261
|
+
salt: Fr,
|
|
262
|
+
deployer: AztecAddress,
|
|
263
|
+
): Promise<Fr[]> {
|
|
264
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
265
|
+
rootPath: this.rootPath,
|
|
266
|
+
packageName: this.packageName,
|
|
267
|
+
contractPath,
|
|
268
|
+
initializer,
|
|
269
|
+
args,
|
|
270
|
+
secret,
|
|
271
|
+
salt,
|
|
272
|
+
deployer,
|
|
273
|
+
});
|
|
274
|
+
|
|
199
275
|
// Emit deployment nullifier
|
|
200
276
|
await this.mineBlock({
|
|
201
|
-
nullifiers: [
|
|
202
|
-
await siloNullifier(
|
|
203
|
-
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
204
|
-
instance.address.toField(),
|
|
205
|
-
),
|
|
206
|
-
],
|
|
277
|
+
nullifiers: [await this.deploymentNullifier(instance.address)],
|
|
207
278
|
});
|
|
208
279
|
|
|
209
280
|
if (!secret.equals(Fr.ZERO)) {
|
|
210
|
-
await this.
|
|
281
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
211
282
|
} else {
|
|
212
283
|
await this.contractStore.addContractInstance(instance);
|
|
213
|
-
await this.contractStore.addContractArtifact(
|
|
284
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
214
285
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
215
286
|
}
|
|
287
|
+
|
|
288
|
+
return [
|
|
289
|
+
instance.salt,
|
|
290
|
+
instance.deployer.toField(),
|
|
291
|
+
instance.currentContractClassId,
|
|
292
|
+
instance.initializationHash,
|
|
293
|
+
instance.immutablesHash,
|
|
294
|
+
...instance.publicKeys.toFields(),
|
|
295
|
+
];
|
|
216
296
|
}
|
|
217
297
|
|
|
218
|
-
|
|
298
|
+
/**
|
|
299
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
300
|
+
*/
|
|
301
|
+
async mineDeploymentNullifiers(addresses: AztecAddress[]) {
|
|
302
|
+
await this.mineBlock({
|
|
303
|
+
nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async addAccount(secret: Fr) {
|
|
308
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
309
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private async registerContractAndAddAccount(
|
|
313
|
+
artifact: ContractArtifact,
|
|
314
|
+
instance: ContractInstanceWithAddress,
|
|
315
|
+
secret: Fr,
|
|
316
|
+
) {
|
|
219
317
|
const partialAddress = await computePartialAddress(instance);
|
|
220
318
|
|
|
221
319
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
222
320
|
await this.contractStore.addContractInstance(instance);
|
|
223
|
-
await this.contractStore.addContractArtifact(
|
|
321
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
224
322
|
|
|
225
323
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
226
324
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -230,7 +328,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
230
328
|
return completeAddress;
|
|
231
329
|
}
|
|
232
330
|
|
|
233
|
-
async
|
|
331
|
+
async createAccount(secret: Fr) {
|
|
234
332
|
// This is a foot gun !
|
|
235
333
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
236
334
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -240,20 +338,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
240
338
|
return completeAddress;
|
|
241
339
|
}
|
|
242
340
|
|
|
243
|
-
async
|
|
341
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
244
342
|
const account = await this.accountStore.getAccount(address);
|
|
245
|
-
const
|
|
343
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
344
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
246
345
|
|
|
247
346
|
const schnorr = new Schnorr();
|
|
248
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
347
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
249
348
|
|
|
250
|
-
const authWitness = new AuthWitness(messageHash,
|
|
349
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
251
350
|
|
|
252
351
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
253
352
|
}
|
|
254
353
|
|
|
255
354
|
async mineBlock(options: { nullifiers?: Fr[] } = {}) {
|
|
256
|
-
const blockNumber = await this.
|
|
355
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
257
356
|
|
|
258
357
|
const txEffect = TxEffect.empty();
|
|
259
358
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
@@ -277,13 +376,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
277
376
|
await this.stateMachine.handleL2Block(block);
|
|
278
377
|
}
|
|
279
378
|
|
|
280
|
-
async
|
|
281
|
-
from: AztecAddress,
|
|
379
|
+
async privateCallNewFlow(
|
|
380
|
+
from: AztecAddress | undefined,
|
|
282
381
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
283
382
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
284
383
|
args: Fr[],
|
|
285
384
|
argsHash: Fr = Fr.zero(),
|
|
286
385
|
isStaticCall: boolean = false,
|
|
386
|
+
additionalScopes: AztecAddress[] = [],
|
|
387
|
+
jobId: string,
|
|
388
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
389
|
+
gasSettings: GasSettings,
|
|
287
390
|
) {
|
|
288
391
|
this.logger.verbose(
|
|
289
392
|
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
@@ -297,25 +400,30 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
297
400
|
throw new Error(message);
|
|
298
401
|
}
|
|
299
402
|
|
|
403
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
404
|
+
|
|
300
405
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
301
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
302
|
-
await this.executeUtilityCall(call);
|
|
406
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
407
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
303
408
|
};
|
|
304
409
|
|
|
305
|
-
await
|
|
306
|
-
|
|
307
|
-
|
|
410
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
411
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
412
|
+
targetContractAddress,
|
|
413
|
+
functionSelector,
|
|
414
|
+
utilityExecutor,
|
|
415
|
+
blockHeader,
|
|
416
|
+
jobId,
|
|
417
|
+
scopes,
|
|
418
|
+
);
|
|
308
419
|
|
|
309
|
-
const
|
|
420
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
310
421
|
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
422
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
423
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
314
424
|
|
|
315
425
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
316
426
|
|
|
317
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
318
|
-
|
|
319
427
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
320
428
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
321
429
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -327,43 +435,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
327
435
|
|
|
328
436
|
const simulator = new WASMSimulator();
|
|
329
437
|
|
|
330
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
438
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
331
439
|
argsHash,
|
|
332
440
|
txContext,
|
|
333
441
|
callContext,
|
|
334
|
-
|
|
335
|
-
blockHeader,
|
|
442
|
+
anchorBlockHeader: blockHeader,
|
|
336
443
|
utilityExecutor,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
[],
|
|
341
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
444
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
445
|
+
capsules: [],
|
|
446
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
342
447
|
noteCache,
|
|
343
448
|
taggingIndexCache,
|
|
344
|
-
this.contractStore,
|
|
345
|
-
this.noteStore,
|
|
346
|
-
this.keyStore,
|
|
347
|
-
this.addressStore,
|
|
348
|
-
this.stateMachine.node,
|
|
349
|
-
this.
|
|
350
|
-
this.
|
|
351
|
-
this.
|
|
352
|
-
this.
|
|
353
|
-
this.
|
|
354
|
-
this.
|
|
355
|
-
|
|
356
|
-
0,
|
|
357
|
-
minRevertibleSideEffectCounter,
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
* contract would perform, including setting senderForTags.
|
|
363
|
-
*/
|
|
364
|
-
from,
|
|
449
|
+
contractStore: this.contractStore,
|
|
450
|
+
noteStore: this.noteStore,
|
|
451
|
+
keyStore: this.keyStore,
|
|
452
|
+
addressStore: this.addressStore,
|
|
453
|
+
aztecNode: this.stateMachine.node,
|
|
454
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
455
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
456
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
457
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
458
|
+
privateEventStore: this.privateEventStore,
|
|
459
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
460
|
+
jobId,
|
|
461
|
+
totalPublicCalldataCount: 0,
|
|
462
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
463
|
+
scopes,
|
|
464
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
465
|
+
// contract would perform, including setting senderForTags.
|
|
466
|
+
senderForTags: from,
|
|
365
467
|
simulator,
|
|
366
|
-
|
|
468
|
+
messageContextService: this.stateMachine.messageContextService,
|
|
469
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
470
|
+
hooks: composeHooks({
|
|
471
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
|
|
472
|
+
isStaticCall ? 'private view' : 'private',
|
|
473
|
+
authorizedUtilityCallTargets,
|
|
474
|
+
),
|
|
475
|
+
}),
|
|
476
|
+
});
|
|
367
477
|
|
|
368
478
|
// 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.
|
|
369
479
|
let result: PrivateExecutionResult;
|
|
@@ -385,7 +495,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
385
495
|
);
|
|
386
496
|
const publicFunctionsCalldata = await Promise.all(
|
|
387
497
|
publicCallRequests.map(async r => {
|
|
388
|
-
const calldata = await privateExecutionOracle.
|
|
498
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
389
499
|
return new HashedValues(calldata, r.calldataHash);
|
|
390
500
|
}),
|
|
391
501
|
);
|
|
@@ -402,7 +512,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
402
512
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
403
513
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
404
514
|
result,
|
|
405
|
-
this.contractStore,
|
|
515
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
516
|
+
this.stateMachine.node,
|
|
406
517
|
minRevertibleSideEffectCounter,
|
|
407
518
|
);
|
|
408
519
|
|
|
@@ -415,7 +526,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
415
526
|
|
|
416
527
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
417
528
|
|
|
418
|
-
const
|
|
529
|
+
const bindings = this.logger.getBindings();
|
|
530
|
+
const contractsDB = new PublicContractsDB(
|
|
531
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
532
|
+
bindings,
|
|
533
|
+
);
|
|
419
534
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
420
535
|
const config = PublicSimulatorConfig.from({
|
|
421
536
|
skipFeeEnforcement: true,
|
|
@@ -428,8 +543,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
428
543
|
globals,
|
|
429
544
|
guardedMerkleTrees,
|
|
430
545
|
contractsDB,
|
|
431
|
-
new
|
|
546
|
+
new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
432
547
|
new TestDateProvider(),
|
|
548
|
+
undefined,
|
|
549
|
+
createLogger('simulator:public-processor', bindings),
|
|
433
550
|
);
|
|
434
551
|
|
|
435
552
|
const tx = await Tx.create({
|
|
@@ -463,11 +580,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
463
580
|
}
|
|
464
581
|
}
|
|
465
582
|
|
|
583
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
584
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
585
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
586
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
587
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
588
|
+
|
|
466
589
|
if (isStaticCall) {
|
|
467
590
|
await checkpoint!.revert();
|
|
468
591
|
|
|
469
592
|
await forkedWorldTrees.close();
|
|
470
|
-
return executionResult.returnValues ?? [];
|
|
593
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
471
594
|
}
|
|
472
595
|
|
|
473
596
|
const txEffect = TxEffect.empty();
|
|
@@ -489,26 +612,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
489
612
|
|
|
490
613
|
await forkedWorldTrees.close();
|
|
491
614
|
|
|
492
|
-
return executionResult.returnValues ?? [];
|
|
615
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
493
616
|
}
|
|
494
617
|
|
|
495
|
-
async
|
|
496
|
-
from: AztecAddress,
|
|
618
|
+
async publicCallNewFlow(
|
|
619
|
+
from: AztecAddress | undefined,
|
|
497
620
|
targetContractAddress: AztecAddress,
|
|
498
621
|
calldata: Fr[],
|
|
499
622
|
isStaticCall: boolean,
|
|
623
|
+
gasSettings: GasSettings,
|
|
500
624
|
) {
|
|
501
625
|
this.logger.verbose(
|
|
502
626
|
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
503
627
|
);
|
|
504
628
|
|
|
505
|
-
const blockNumber = await this.
|
|
506
|
-
|
|
507
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
508
|
-
|
|
509
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
510
|
-
|
|
511
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
629
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
512
630
|
|
|
513
631
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
514
632
|
|
|
@@ -526,7 +644,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
526
644
|
|
|
527
645
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
528
646
|
|
|
529
|
-
const
|
|
647
|
+
const bindings2 = this.logger.getBindings();
|
|
648
|
+
const contractsDB = new PublicContractsDB(
|
|
649
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
650
|
+
bindings2,
|
|
651
|
+
);
|
|
530
652
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
531
653
|
const config = PublicSimulatorConfig.from({
|
|
532
654
|
skipFeeEnforcement: true,
|
|
@@ -535,8 +657,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
535
657
|
collectStatistics: false,
|
|
536
658
|
collectCallMetadata: true,
|
|
537
659
|
});
|
|
538
|
-
const simulator = new
|
|
539
|
-
const processor = new PublicProcessor(
|
|
660
|
+
const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
661
|
+
const processor = new PublicProcessor(
|
|
662
|
+
globals,
|
|
663
|
+
guardedMerkleTrees,
|
|
664
|
+
contractsDB,
|
|
665
|
+
simulator,
|
|
666
|
+
new TestDateProvider(),
|
|
667
|
+
undefined,
|
|
668
|
+
createLogger('simulator:public-processor', bindings2),
|
|
669
|
+
);
|
|
540
670
|
|
|
541
671
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
542
672
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -549,7 +679,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
549
679
|
// may require producing reverts.
|
|
550
680
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
551
681
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
552
|
-
from,
|
|
682
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
553
683
|
targetContractAddress,
|
|
554
684
|
isStaticCall,
|
|
555
685
|
calldataHash,
|
|
@@ -567,7 +697,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
567
697
|
constantData,
|
|
568
698
|
/*gasUsed=*/ new Gas(0, 0),
|
|
569
699
|
/*feePayer=*/ AztecAddress.zero(),
|
|
570
|
-
/*
|
|
700
|
+
/*expirationTimestamp=*/ 0n,
|
|
571
701
|
inputsForPublic,
|
|
572
702
|
undefined,
|
|
573
703
|
);
|
|
@@ -635,10 +765,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
635
765
|
return returnValues ?? [];
|
|
636
766
|
}
|
|
637
767
|
|
|
638
|
-
async
|
|
768
|
+
async executeUtilityFunction(
|
|
639
769
|
targetContractAddress: AztecAddress,
|
|
640
770
|
functionSelector: FunctionSelector,
|
|
641
771
|
args: Fr[],
|
|
772
|
+
jobId: string,
|
|
773
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
642
774
|
) {
|
|
643
775
|
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
644
776
|
if (!artifact) {
|
|
@@ -646,25 +778,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
646
778
|
}
|
|
647
779
|
|
|
648
780
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
649
|
-
await
|
|
650
|
-
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
const call = new FunctionCall(
|
|
654
|
-
artifact.name,
|
|
781
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
782
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
655
783
|
targetContractAddress,
|
|
656
784
|
functionSelector,
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
785
|
+
async (call, execScopes) => {
|
|
786
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
787
|
+
},
|
|
788
|
+
blockHeader,
|
|
789
|
+
jobId,
|
|
790
|
+
await this.keyStore.getAccounts(),
|
|
662
791
|
);
|
|
663
792
|
|
|
664
|
-
|
|
793
|
+
const call = FunctionCall.from({
|
|
794
|
+
name: artifact.name,
|
|
795
|
+
to: targetContractAddress,
|
|
796
|
+
selector: functionSelector,
|
|
797
|
+
type: FunctionType.UTILITY,
|
|
798
|
+
hideMsgSender: false,
|
|
799
|
+
isStatic: false,
|
|
800
|
+
args,
|
|
801
|
+
returnTypes: [],
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
|
|
665
805
|
}
|
|
666
806
|
|
|
667
|
-
private async executeUtilityCall(
|
|
807
|
+
private async executeUtilityCall(
|
|
808
|
+
call: FunctionCall,
|
|
809
|
+
scopes: AztecAddress[],
|
|
810
|
+
jobId: string,
|
|
811
|
+
authorizedUtilityCallTargets: AztecAddress[] = [],
|
|
812
|
+
): Promise<Fr[]> {
|
|
668
813
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
669
814
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
670
815
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -677,24 +822,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
677
822
|
|
|
678
823
|
try {
|
|
679
824
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
825
|
+
const simulator = new WASMSimulator();
|
|
826
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
827
|
+
await this.executeUtilityCall(syncCall, execScopes, jobId);
|
|
828
|
+
};
|
|
829
|
+
const oracle = new UtilityExecutionOracle({
|
|
830
|
+
contractAddress: call.to,
|
|
831
|
+
authWitnesses: [],
|
|
832
|
+
capsules: [],
|
|
684
833
|
anchorBlockHeader,
|
|
685
|
-
this.contractStore,
|
|
686
|
-
this.noteStore,
|
|
687
|
-
this.keyStore,
|
|
688
|
-
this.addressStore,
|
|
689
|
-
this.stateMachine.node,
|
|
690
|
-
this.
|
|
691
|
-
this.
|
|
692
|
-
this.
|
|
693
|
-
this.
|
|
694
|
-
this.
|
|
695
|
-
this.
|
|
696
|
-
|
|
697
|
-
|
|
834
|
+
contractStore: this.contractStore,
|
|
835
|
+
noteStore: this.noteStore,
|
|
836
|
+
keyStore: this.keyStore,
|
|
837
|
+
addressStore: this.addressStore,
|
|
838
|
+
aztecNode: this.stateMachine.node,
|
|
839
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
840
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
841
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
842
|
+
privateEventStore: this.privateEventStore,
|
|
843
|
+
messageContextService: this.stateMachine.messageContextService,
|
|
844
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
845
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
846
|
+
jobId,
|
|
847
|
+
scopes,
|
|
848
|
+
simulator,
|
|
849
|
+
hooks: composeHooks({
|
|
850
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
851
|
+
}),
|
|
852
|
+
utilityExecutor,
|
|
853
|
+
});
|
|
854
|
+
const acirExecutionResult = await simulator
|
|
698
855
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
699
856
|
.catch((err: Error) => {
|
|
700
857
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
@@ -709,10 +866,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
709
866
|
);
|
|
710
867
|
});
|
|
711
868
|
|
|
712
|
-
this.logger.verbose(`Utility
|
|
869
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
713
870
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
714
871
|
} catch (err) {
|
|
715
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
872
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
716
873
|
}
|
|
717
874
|
}
|
|
718
875
|
|
|
@@ -722,7 +879,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
722
879
|
}
|
|
723
880
|
|
|
724
881
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
725
|
-
const
|
|
726
|
-
return
|
|
882
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
883
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
private buildAuthorizeUtilityCallHook(
|
|
887
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
888
|
+
authorizedTargets: AztecAddress[],
|
|
889
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
890
|
+
if (authorizedTargets.length === 0) {
|
|
891
|
+
return undefined;
|
|
892
|
+
}
|
|
893
|
+
return req =>
|
|
894
|
+
Promise.resolve({
|
|
895
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
896
|
+
});
|
|
727
897
|
}
|
|
728
898
|
}
|