@aztec/txe 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f
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-KKNT527R.js +3 -0
- package/dest/ContractClassRegistry-KKNT527R.js.map +7 -0
- package/dest/ContractInstanceRegistry-GSKBNL3Q.js +3 -0
- package/dest/ContractInstanceRegistry-GSKBNL3Q.js.map +7 -0
- package/dest/FeeJuice-GUJ5O6GB.js +3 -0
- package/dest/FeeJuice-GUJ5O6GB.js.map +7 -0
- package/dest/MultiCallEntrypoint-ZQPCKVKL.js +3 -0
- package/dest/MultiCallEntrypoint-ZQPCKVKL.js.map +7 -0
- package/dest/SchnorrAccount-QIXE5DXA.js +3 -0
- package/dest/SchnorrAccount-QIXE5DXA.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 +32 -0
- package/dest/bin/index.js +3 -30
- package/dest/bin/index.js.map +7 -0
- package/dest/chunk-BJVAAXNA.js +3 -0
- package/dest/chunk-BJVAAXNA.js.map +7 -0
- package/dest/chunk-DF6RMOC6.js +304 -0
- package/dest/chunk-DF6RMOC6.js.map +7 -0
- package/dest/chunk-PPJTNNUG.js +265 -0
- package/dest/chunk-PPJTNNUG.js.map +7 -0
- package/dest/constants.d.ts +5 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +7 -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 +188 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +148 -75
- package/dest/metafile.json +38147 -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 +40 -28
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +18 -13
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +31 -16
- package/dest/oracle/txe_oracle_top_level_context.d.ts +49 -31
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +265 -119
- 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 +144 -82
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +599 -238
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +20 -67
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +65 -182
- package/dest/state_machine/dummy_p2p_client.d.ts +28 -17
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +51 -24
- 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 +10 -4
- 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 +57 -16
- package/dest/state_machine/mock_epoch_cache.d.ts +26 -8
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +49 -9
- package/dest/state_machine/synchronizer.d.ts +6 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +4 -4
- package/dest/txe_oracle_version.d.ts +17 -0
- package/dest/txe_oracle_version.d.ts.map +1 -0
- package/dest/txe_oracle_version.js +14 -0
- package/dest/txe_session.d.ts +83 -19
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +291 -66
- package/dest/utils/block_creation.d.ts +4 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +18 -5
- 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/utils/tx_effect_creation.d.ts +2 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +3 -6
- package/dest/utils/txe_account_store.d.ts +10 -0
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- package/dest/{util/txe_account_data_provider.js → utils/txe_account_store.js} +1 -1
- 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/utils/txe_public_contract_data_source.js +48 -0
- 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 -22
- package/src/bin/check_txe_oracle_version.ts +37 -0
- package/src/bin/index.ts +11 -2
- package/src/constants.ts +9 -0
- package/src/dispatcher_pool.ts +316 -0
- package/src/index.ts +166 -80
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +48 -34
- package/src/oracle/txe_oracle_public_context.ts +46 -18
- package/src/oracle/txe_oracle_top_level_context.ts +322 -169
- package/src/oracle/txe_private_execution_oracle.ts +30 -0
- package/src/rpc_server.ts +87 -0
- package/src/rpc_translator.ts +687 -326
- package/src/state_machine/archiver.ts +69 -220
- package/src/state_machine/dummy_p2p_client.ts +80 -37
- package/src/state_machine/global_variable_builder.ts +19 -4
- package/src/state_machine/index.ts +73 -16
- package/src/state_machine/mock_epoch_cache.ts +61 -14
- package/src/state_machine/synchronizer.ts +6 -6
- package/src/txe_oracle_version.ts +17 -0
- package/src/txe_session.ts +439 -132
- package/src/utils/block_creation.ts +19 -16
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/tx_effect_creation.ts +3 -11
- package/src/{util/txe_account_data_provider.ts → utils/txe_account_store.ts} +1 -1
- package/src/utils/txe_public_contract_data_source.ts +58 -0
- 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_data_provider.d.ts +0 -10
- package/dest/util/txe_account_data_provider.d.ts.map +0 -1
- package/dest/util/txe_contract_data_provider.d.ts +0 -12
- package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
- package/dest/util/txe_contract_data_provider.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/dest/util/txe_public_contract_data_source.js +0 -67
- package/src/util/txe_contract_data_provider.ts +0 -36
- package/src/util/txe_public_contract_data_source.ts +0 -86
- /package/dest/{util → utils}/expected_failure_error.js +0 -0
- /package/src/{util → utils}/expected_failure_error.ts +0 -0
|
@@ -1,40 +1,42 @@
|
|
|
1
|
-
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
|
|
1
|
+
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
7
|
-
import {
|
|
7
|
+
import { CapsuleService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
|
|
8
8
|
import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
|
|
9
9
|
import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
|
|
10
10
|
import { CppPublicTxSimulator, GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor } from '@aztec/simulator/server';
|
|
11
|
-
import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
11
|
+
import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
12
12
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
13
13
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
14
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
15
|
import { computePartialAddress } from '@aztec/stdlib/contract';
|
|
16
|
-
import { Gas, GasFees
|
|
16
|
+
import { Gas, GasFees } from '@aztec/stdlib/gas';
|
|
17
17
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
18
18
|
import { PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, PrivateToPublicAccumulatedData, PublicCallRequest } from '@aztec/stdlib/kernel';
|
|
19
|
+
import { hashPublicKey } from '@aztec/stdlib/keys';
|
|
19
20
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
20
21
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
21
22
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
22
23
|
import { CallContext, HashedValues, PrivateExecutionResult, Tx, TxConstantData, TxContext, TxEffect, TxHash, collectNested } from '@aztec/stdlib/tx';
|
|
23
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
24
|
-
import { DEFAULT_ADDRESS } from '../
|
|
25
|
-
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
24
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
25
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
26
26
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
27
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
27
28
|
export class TXEOracleTopLevelContext {
|
|
28
29
|
stateMachine;
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
contractStore;
|
|
31
|
+
noteStore;
|
|
31
32
|
keyStore;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
addressStore;
|
|
34
|
+
accountStore;
|
|
35
|
+
senderTaggingStore;
|
|
36
|
+
recipientTaggingStore;
|
|
37
|
+
senderAddressBookStore;
|
|
38
|
+
capsuleStore;
|
|
39
|
+
privateEventStore;
|
|
38
40
|
nextBlockTimestamp;
|
|
39
41
|
version;
|
|
40
42
|
chainId;
|
|
@@ -42,17 +44,18 @@ export class TXEOracleTopLevelContext {
|
|
|
42
44
|
isMisc;
|
|
43
45
|
isTxe;
|
|
44
46
|
logger;
|
|
45
|
-
constructor(stateMachine,
|
|
47
|
+
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits){
|
|
46
48
|
this.stateMachine = stateMachine;
|
|
47
|
-
this.
|
|
48
|
-
this.
|
|
49
|
+
this.contractStore = contractStore;
|
|
50
|
+
this.noteStore = noteStore;
|
|
49
51
|
this.keyStore = keyStore;
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
52
|
+
this.addressStore = addressStore;
|
|
53
|
+
this.accountStore = accountStore;
|
|
54
|
+
this.senderTaggingStore = senderTaggingStore;
|
|
55
|
+
this.recipientTaggingStore = recipientTaggingStore;
|
|
56
|
+
this.senderAddressBookStore = senderAddressBookStore;
|
|
57
|
+
this.capsuleStore = capsuleStore;
|
|
58
|
+
this.privateEventStore = privateEventStore;
|
|
56
59
|
this.nextBlockTimestamp = nextBlockTimestamp;
|
|
57
60
|
this.version = version;
|
|
58
61
|
this.chainId = chainId;
|
|
@@ -62,53 +65,84 @@ export class TXEOracleTopLevelContext {
|
|
|
62
65
|
this.logger = createLogger('txe:top_level_context');
|
|
63
66
|
this.logger.debug('Entering Top Level Context');
|
|
64
67
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
contractOracleVersion;
|
|
69
|
+
assertCompatibleOracleVersion(major, minor) {
|
|
70
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
71
|
+
const hint = major > ORACLE_VERSION_MAJOR ? '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.' : '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.';
|
|
72
|
+
throw new Error(`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`);
|
|
68
73
|
}
|
|
74
|
+
this.contractOracleVersion = {
|
|
75
|
+
major,
|
|
76
|
+
minor
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
80
|
+
nonOracleFunctionGetContractOracleVersion() {
|
|
81
|
+
return this.contractOracleVersion;
|
|
69
82
|
}
|
|
70
83
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
71
84
|
// setup.
|
|
72
|
-
|
|
85
|
+
getRandomField() {
|
|
73
86
|
return Fr.random();
|
|
74
87
|
}
|
|
75
88
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
76
|
-
|
|
89
|
+
log(level, message, fields) {
|
|
77
90
|
if (!LogLevels[level]) {
|
|
78
|
-
throw new Error(`Invalid
|
|
91
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
79
92
|
}
|
|
80
93
|
const levelName = LogLevels[level];
|
|
81
94
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, {
|
|
82
95
|
module: `${this.logger.module}:debug_log`
|
|
83
96
|
});
|
|
97
|
+
return Promise.resolve();
|
|
84
98
|
}
|
|
85
|
-
|
|
99
|
+
getDefaultAddress() {
|
|
86
100
|
return DEFAULT_ADDRESS;
|
|
87
101
|
}
|
|
88
|
-
async
|
|
102
|
+
async getNextBlockNumber() {
|
|
89
103
|
return BlockNumber(await this.getLastBlockNumber() + 1);
|
|
90
104
|
}
|
|
91
|
-
|
|
105
|
+
getNextBlockTimestamp() {
|
|
92
106
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
93
107
|
}
|
|
94
|
-
async
|
|
95
|
-
return (await this.stateMachine.node.
|
|
108
|
+
async getLastBlockTimestamp() {
|
|
109
|
+
return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
|
|
96
110
|
}
|
|
97
|
-
async
|
|
98
|
-
const
|
|
111
|
+
async getLastTxEffects() {
|
|
112
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
113
|
+
const block = await this.stateMachine.archiver.getBlock({
|
|
114
|
+
number: latestBlockNumber
|
|
115
|
+
});
|
|
99
116
|
if (block.body.txEffects.length != 1) {
|
|
100
117
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
101
118
|
throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
|
|
102
119
|
}
|
|
103
120
|
const txEffects = block.body.txEffects[0];
|
|
121
|
+
const privateLogs = txEffects.privateLogs;
|
|
122
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
123
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
124
|
+
}
|
|
104
125
|
return {
|
|
105
126
|
txHash: txEffects.txHash,
|
|
106
127
|
noteHashes: txEffects.noteHashes,
|
|
107
|
-
nullifiers: txEffects.nullifiers
|
|
128
|
+
nullifiers: txEffects.nullifiers,
|
|
129
|
+
privateLogs
|
|
108
130
|
};
|
|
109
131
|
}
|
|
110
|
-
async
|
|
111
|
-
|
|
132
|
+
async syncContractNonOracleMethod(contractAddress, scope, jobId) {
|
|
133
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
134
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
138
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
|
|
139
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
140
|
+
}, blockHeader, jobId, [
|
|
141
|
+
scope
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
async getPrivateEvents(selector, contractAddress, scope) {
|
|
145
|
+
return (await this.privateEventStore.getPrivateEvents(selector, {
|
|
112
146
|
contractAddress,
|
|
113
147
|
scopes: [
|
|
114
148
|
scope
|
|
@@ -117,62 +151,71 @@ export class TXEOracleTopLevelContext {
|
|
|
117
151
|
toBlock: await this.getLastBlockNumber() + 1
|
|
118
152
|
})).map((e)=>e.packedEvent);
|
|
119
153
|
}
|
|
120
|
-
async
|
|
154
|
+
async advanceBlocksBy(blocks) {
|
|
121
155
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
122
156
|
for(let i = 0; i < blocks; i++){
|
|
123
157
|
await this.mineBlock();
|
|
124
158
|
}
|
|
125
159
|
}
|
|
126
|
-
|
|
160
|
+
advanceTimestampBy(duration) {
|
|
127
161
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
128
162
|
this.nextBlockTimestamp += duration;
|
|
129
163
|
}
|
|
130
|
-
|
|
164
|
+
deploymentNullifier(address) {
|
|
165
|
+
return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
166
|
+
}
|
|
167
|
+
async deploy(artifact, instance, secret) {
|
|
131
168
|
// Emit deployment nullifier
|
|
132
169
|
await this.mineBlock({
|
|
133
170
|
nullifiers: [
|
|
134
|
-
await
|
|
171
|
+
await this.deploymentNullifier(instance.address)
|
|
135
172
|
]
|
|
136
173
|
});
|
|
137
174
|
if (!secret.equals(Fr.ZERO)) {
|
|
138
|
-
await this.
|
|
175
|
+
await this.addAccount(artifact, instance, secret);
|
|
139
176
|
} else {
|
|
140
|
-
await this.
|
|
141
|
-
await this.
|
|
177
|
+
await this.contractStore.addContractInstance(instance);
|
|
178
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
142
179
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
143
180
|
}
|
|
144
181
|
}
|
|
145
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
184
|
+
*/ async mineDeploymentNullifiers(addresses) {
|
|
185
|
+
await this.mineBlock({
|
|
186
|
+
nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
async addAccount(artifact, instance, secret) {
|
|
146
190
|
const partialAddress = await computePartialAddress(instance);
|
|
147
191
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
148
|
-
await this.
|
|
149
|
-
await this.
|
|
192
|
+
await this.contractStore.addContractInstance(instance);
|
|
193
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
150
194
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
151
|
-
await this.
|
|
152
|
-
await this.
|
|
195
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
196
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
153
197
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
154
198
|
return completeAddress;
|
|
155
199
|
}
|
|
156
|
-
async
|
|
200
|
+
async createAccount(secret) {
|
|
157
201
|
// This is a foot gun !
|
|
158
202
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
159
|
-
await this.
|
|
160
|
-
await this.
|
|
203
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
204
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
161
205
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
162
206
|
return completeAddress;
|
|
163
207
|
}
|
|
164
|
-
async
|
|
165
|
-
const account = await this.
|
|
166
|
-
const
|
|
208
|
+
async addAuthWitness(address, messageHash) {
|
|
209
|
+
const account = await this.accountStore.getAccount(address);
|
|
210
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
211
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
167
212
|
const schnorr = new Schnorr();
|
|
168
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
169
|
-
const authWitness = new AuthWitness(messageHash,
|
|
170
|
-
...signature.toBuffer()
|
|
171
|
-
]);
|
|
213
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
214
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
172
215
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
173
216
|
}
|
|
174
217
|
async mineBlock(options = {}) {
|
|
175
|
-
const blockNumber = await this.
|
|
218
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
176
219
|
const txEffect = TxEffect.empty();
|
|
177
220
|
txEffect.nullifiers = [
|
|
178
221
|
getSingleTxBlockRequestHash(blockNumber),
|
|
@@ -194,30 +237,74 @@ export class TXEOracleTopLevelContext {
|
|
|
194
237
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
195
238
|
await this.stateMachine.handleL2Block(block);
|
|
196
239
|
}
|
|
197
|
-
async
|
|
198
|
-
this.logger.verbose(`Executing external function ${await this.
|
|
199
|
-
const artifact = await this.
|
|
240
|
+
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
241
|
+
this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
242
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
200
243
|
if (!artifact) {
|
|
201
244
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)')) ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.' : 'Function Artifact does not exist';
|
|
202
245
|
throw new Error(message);
|
|
203
246
|
}
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
247
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
248
|
+
from,
|
|
249
|
+
...additionalScopes
|
|
250
|
+
];
|
|
251
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
252
|
+
const utilityExecutor = async (call, execScopes)=>{
|
|
253
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
254
|
+
};
|
|
255
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
256
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
257
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
258
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
259
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
209
260
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
210
|
-
const blockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
|
|
211
261
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
212
262
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
263
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
264
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
265
|
+
// marking all side effects as revertible.
|
|
266
|
+
const minRevertibleSideEffectCounter = 1;
|
|
267
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
213
268
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
214
269
|
const simulator = new WASMSimulator();
|
|
215
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
270
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
271
|
+
argsHash,
|
|
272
|
+
txContext,
|
|
273
|
+
callContext,
|
|
274
|
+
anchorBlockHeader: blockHeader,
|
|
275
|
+
utilityExecutor,
|
|
276
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
277
|
+
capsules: [],
|
|
278
|
+
executionCache: HashedValuesCache.create([
|
|
279
|
+
new HashedValues(args, argsHash)
|
|
280
|
+
]),
|
|
281
|
+
noteCache,
|
|
282
|
+
taggingIndexCache,
|
|
283
|
+
contractStore: this.contractStore,
|
|
284
|
+
noteStore: this.noteStore,
|
|
285
|
+
keyStore: this.keyStore,
|
|
286
|
+
addressStore: this.addressStore,
|
|
287
|
+
aztecNode: this.stateMachine.node,
|
|
288
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
289
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
290
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
291
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
292
|
+
privateEventStore: this.privateEventStore,
|
|
293
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
294
|
+
jobId,
|
|
295
|
+
totalPublicCalldataCount: 0,
|
|
296
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
297
|
+
scopes,
|
|
298
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
299
|
+
// contract would perform, including setting senderForTags.
|
|
300
|
+
senderForTags: from,
|
|
301
|
+
simulator,
|
|
302
|
+
messageContextService: this.stateMachine.messageContextService,
|
|
303
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
304
|
+
hooks: composeHooks({
|
|
305
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets)
|
|
306
|
+
})
|
|
307
|
+
});
|
|
221
308
|
// 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.
|
|
222
309
|
let result;
|
|
223
310
|
let executionResult;
|
|
@@ -229,21 +316,19 @@ export class TXEOracleTopLevelContext {
|
|
|
229
316
|
r.publicInputs.publicTeardownCallRequest
|
|
230
317
|
]));
|
|
231
318
|
const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
|
|
232
|
-
const calldata = await privateExecutionOracle.
|
|
319
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
233
320
|
return new HashedValues(calldata, r.calldataHash);
|
|
234
321
|
}));
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
322
|
+
noteCache.finish();
|
|
323
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
324
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
239
325
|
} catch (err) {
|
|
240
326
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
241
327
|
}
|
|
242
|
-
// According to the protocol rules,
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
const
|
|
246
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractDataProvider);
|
|
328
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
329
|
+
// the nonce generator for the note hashes.
|
|
330
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
331
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
247
332
|
const globals = makeGlobalVariables();
|
|
248
333
|
globals.blockNumber = blockNumber;
|
|
249
334
|
globals.timestamp = this.nextBlockTimestamp;
|
|
@@ -251,7 +336,8 @@ export class TXEOracleTopLevelContext {
|
|
|
251
336
|
globals.version = this.version;
|
|
252
337
|
globals.gasFees = GasFees.empty();
|
|
253
338
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
254
|
-
const
|
|
339
|
+
const bindings = this.logger.getBindings();
|
|
340
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
|
|
255
341
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
256
342
|
const config = PublicSimulatorConfig.from({
|
|
257
343
|
skipFeeEnforcement: true,
|
|
@@ -260,7 +346,7 @@ export class TXEOracleTopLevelContext {
|
|
|
260
346
|
collectStatistics: false,
|
|
261
347
|
collectCallMetadata: true
|
|
262
348
|
});
|
|
263
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config), new TestDateProvider());
|
|
349
|
+
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
|
|
264
350
|
const tx = await Tx.create({
|
|
265
351
|
data: publicInputs,
|
|
266
352
|
chonkProof: ChonkProof.empty(),
|
|
@@ -281,7 +367,7 @@ export class TXEOracleTopLevelContext {
|
|
|
281
367
|
} else if (!processedTx.revertCode.isOK()) {
|
|
282
368
|
if (processedTx.revertReason) {
|
|
283
369
|
try {
|
|
284
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
370
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
285
371
|
// eslint-disable-next-line no-empty
|
|
286
372
|
} catch {}
|
|
287
373
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -289,10 +375,20 @@ export class TXEOracleTopLevelContext {
|
|
|
289
375
|
throw new Error('Contract execution has reverted');
|
|
290
376
|
}
|
|
291
377
|
}
|
|
378
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
379
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
380
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
381
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
382
|
+
const offchainEffects = collectNested([
|
|
383
|
+
executionResult
|
|
384
|
+
], (r)=>r.offchainEffects.map((e)=>e.data));
|
|
292
385
|
if (isStaticCall) {
|
|
293
386
|
await checkpoint.revert();
|
|
294
387
|
await forkedWorldTrees.close();
|
|
295
|
-
return
|
|
388
|
+
return {
|
|
389
|
+
returnValues: executionResult.returnValues ?? [],
|
|
390
|
+
offchainEffects
|
|
391
|
+
};
|
|
296
392
|
}
|
|
297
393
|
const txEffect = TxEffect.empty();
|
|
298
394
|
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
@@ -308,16 +404,16 @@ export class TXEOracleTopLevelContext {
|
|
|
308
404
|
]);
|
|
309
405
|
await this.stateMachine.handleL2Block(l2Block);
|
|
310
406
|
await forkedWorldTrees.close();
|
|
311
|
-
return
|
|
407
|
+
return {
|
|
408
|
+
returnValues: executionResult.returnValues ?? [],
|
|
409
|
+
offchainEffects
|
|
410
|
+
};
|
|
312
411
|
}
|
|
313
|
-
async
|
|
314
|
-
this.logger.verbose(`Executing public function ${await this.
|
|
315
|
-
const blockNumber = await this.
|
|
316
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
317
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
318
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
412
|
+
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
413
|
+
this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
414
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
319
415
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
320
|
-
const anchorBlockHeader = await this.stateMachine.
|
|
416
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
321
417
|
const calldataHash = await computeCalldataHash(calldata);
|
|
322
418
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
323
419
|
const globals = makeGlobalVariables();
|
|
@@ -327,7 +423,8 @@ export class TXEOracleTopLevelContext {
|
|
|
327
423
|
globals.version = this.version;
|
|
328
424
|
globals.gasFees = GasFees.empty();
|
|
329
425
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
330
|
-
const
|
|
426
|
+
const bindings2 = this.logger.getBindings();
|
|
427
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
|
|
331
428
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
332
429
|
const config = PublicSimulatorConfig.from({
|
|
333
430
|
skipFeeEnforcement: true,
|
|
@@ -336,8 +433,8 @@ export class TXEOracleTopLevelContext {
|
|
|
336
433
|
collectStatistics: false,
|
|
337
434
|
collectCallMetadata: true
|
|
338
435
|
});
|
|
339
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
340
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
|
|
436
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
437
|
+
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
|
|
341
438
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
342
439
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
343
440
|
// side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
|
|
@@ -347,10 +444,10 @@ export class TXEOracleTopLevelContext {
|
|
|
347
444
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
348
445
|
// may require producing reverts.
|
|
349
446
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
350
|
-
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
|
|
447
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
351
448
|
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
352
449
|
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
353
|
-
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*
|
|
450
|
+
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
354
451
|
const tx = await Tx.create({
|
|
355
452
|
data: txData,
|
|
356
453
|
chonkProof: ChonkProof.empty(),
|
|
@@ -373,7 +470,7 @@ export class TXEOracleTopLevelContext {
|
|
|
373
470
|
} else if (!processedTx.revertCode.isOK()) {
|
|
374
471
|
if (processedTx.revertReason) {
|
|
375
472
|
try {
|
|
376
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
473
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
377
474
|
// eslint-disable-next-line no-empty
|
|
378
475
|
} catch {}
|
|
379
476
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -403,17 +500,30 @@ export class TXEOracleTopLevelContext {
|
|
|
403
500
|
await forkedWorldTrees.close();
|
|
404
501
|
return returnValues ?? [];
|
|
405
502
|
}
|
|
406
|
-
async
|
|
407
|
-
const artifact = await this.
|
|
503
|
+
async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
504
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
408
505
|
if (!artifact) {
|
|
409
506
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
410
507
|
}
|
|
411
|
-
|
|
508
|
+
// Sync notes before executing utility function to discover notes from previous transactions
|
|
509
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
510
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
|
|
511
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
512
|
+
}, blockHeader, jobId, await this.keyStore.getAccounts());
|
|
513
|
+
const call = FunctionCall.from({
|
|
412
514
|
name: artifact.name,
|
|
515
|
+
to: targetContractAddress,
|
|
413
516
|
selector: functionSelector,
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
517
|
+
type: FunctionType.UTILITY,
|
|
518
|
+
hideMsgSender: false,
|
|
519
|
+
isStatic: false,
|
|
520
|
+
args,
|
|
521
|
+
returnTypes: []
|
|
522
|
+
});
|
|
523
|
+
return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
|
|
524
|
+
}
|
|
525
|
+
async executeUtilityCall(call, scopes, jobId, authorizedUtilityCallTargets = []) {
|
|
526
|
+
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
417
527
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
418
528
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
419
529
|
}
|
|
@@ -422,9 +532,37 @@ export class TXEOracleTopLevelContext {
|
|
|
422
532
|
selector: call.selector
|
|
423
533
|
});
|
|
424
534
|
try {
|
|
425
|
-
const anchorBlockHeader = await this.stateMachine.
|
|
426
|
-
const
|
|
427
|
-
const
|
|
535
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
536
|
+
const simulator = new WASMSimulator();
|
|
537
|
+
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
538
|
+
await this.executeUtilityCall(syncCall, execScopes, jobId);
|
|
539
|
+
};
|
|
540
|
+
const oracle = new UtilityExecutionOracle({
|
|
541
|
+
contractAddress: call.to,
|
|
542
|
+
authWitnesses: [],
|
|
543
|
+
capsules: [],
|
|
544
|
+
anchorBlockHeader,
|
|
545
|
+
contractStore: this.contractStore,
|
|
546
|
+
noteStore: this.noteStore,
|
|
547
|
+
keyStore: this.keyStore,
|
|
548
|
+
addressStore: this.addressStore,
|
|
549
|
+
aztecNode: this.stateMachine.node,
|
|
550
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
551
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
552
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
553
|
+
privateEventStore: this.privateEventStore,
|
|
554
|
+
messageContextService: this.stateMachine.messageContextService,
|
|
555
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
556
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
557
|
+
jobId,
|
|
558
|
+
scopes,
|
|
559
|
+
simulator,
|
|
560
|
+
hooks: composeHooks({
|
|
561
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
562
|
+
}),
|
|
563
|
+
utilityExecutor
|
|
564
|
+
});
|
|
565
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
|
|
428
566
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
429
567
|
throw new ExecutionError(err.message, {
|
|
430
568
|
contractAddress: call.to,
|
|
@@ -433,10 +571,10 @@ export class TXEOracleTopLevelContext {
|
|
|
433
571
|
cause: err
|
|
434
572
|
});
|
|
435
573
|
});
|
|
436
|
-
this.logger.verbose(`Utility
|
|
574
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
437
575
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
438
576
|
} catch (err) {
|
|
439
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
577
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
440
578
|
}
|
|
441
579
|
}
|
|
442
580
|
close() {
|
|
@@ -447,7 +585,15 @@ export class TXEOracleTopLevelContext {
|
|
|
447
585
|
];
|
|
448
586
|
}
|
|
449
587
|
async getLastBlockNumber() {
|
|
450
|
-
const
|
|
451
|
-
return
|
|
588
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
589
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
590
|
+
}
|
|
591
|
+
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
592
|
+
if (authorizedTargets.length === 0) {
|
|
593
|
+
return undefined;
|
|
594
|
+
}
|
|
595
|
+
return (req)=>Promise.resolve({
|
|
596
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
|
|
597
|
+
});
|
|
452
598
|
}
|
|
453
599
|
}
|