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