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