@aztec/txe 0.0.1-commit.2ed92850 → 0.0.1-commit.3100065
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-FSRZIMX6.js +3 -0
- package/dest/AuthRegistry-FSRZIMX6.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-KKUEU7XW.js +3 -0
- package/dest/HandshakeRegistry-KKUEU7XW.js.map +7 -0
- package/dest/MultiCallEntrypoint-TGICA67H.js +3 -0
- package/dest/MultiCallEntrypoint-TGICA67H.js.map +7 -0
- package/dest/SchnorrAccount-J5T6OKR3.js +3 -0
- package/dest/SchnorrAccount-J5T6OKR3.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js +3 -0
- package/dest/SchnorrInitializerlessAccount-OOES6Q4F.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-PDOEF22H.js +304 -0
- package/dest/chunk-PDOEF22H.js.map +7 -0
- package/dest/chunk-YP4ODNMQ.js +268 -0
- package/dest/chunk-YP4ODNMQ.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 +39883 -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 +65 -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 +63 -16
- package/dest/oracle/txe_oracle_registry.d.ts +170 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +749 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +56 -29
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +330 -103
- 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 +113 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +885 -613
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +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 +89 -16
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +363 -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 +71 -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 +76 -16
- package/src/oracle/txe_oracle_registry.ts +539 -0
- package/src/oracle/txe_oracle_top_level_context.ts +440 -168
- 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 +1098 -988
- 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 +603 -128
- 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,86 @@ 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 readonly artifactResolver: TXEArtifactResolver,
|
|
130
|
+
private readonly rootPath: string,
|
|
131
|
+
private readonly packageName: string,
|
|
115
132
|
) {
|
|
116
133
|
this.logger = createLogger('txe:top_level_context');
|
|
117
134
|
this.logger.debug('Entering Top Level Context');
|
|
118
135
|
}
|
|
119
136
|
|
|
120
|
-
|
|
121
|
-
|
|
137
|
+
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
138
|
+
|
|
139
|
+
assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
140
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
141
|
+
const hint =
|
|
142
|
+
major > ORACLE_VERSION_MAJOR
|
|
143
|
+
? '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.'
|
|
144
|
+
: '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
145
|
throw new Error(
|
|
123
|
-
`Incompatible
|
|
146
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
124
147
|
);
|
|
125
148
|
}
|
|
149
|
+
this.contractOracleVersion = { major, minor };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
153
|
+
nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
|
|
154
|
+
return this.contractOracleVersion;
|
|
126
155
|
}
|
|
127
156
|
|
|
128
157
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
129
158
|
// setup.
|
|
130
|
-
|
|
159
|
+
getRandomField(): Fr {
|
|
131
160
|
return Fr.random();
|
|
132
161
|
}
|
|
133
162
|
|
|
134
163
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
135
|
-
|
|
164
|
+
log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
136
165
|
if (!LogLevels[level]) {
|
|
137
|
-
throw new Error(`Invalid
|
|
166
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
138
167
|
}
|
|
139
168
|
const levelName = LogLevels[level];
|
|
140
169
|
|
|
141
170
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
171
|
+
return Promise.resolve();
|
|
142
172
|
}
|
|
143
173
|
|
|
144
|
-
|
|
174
|
+
getDefaultAddress(): AztecAddress {
|
|
145
175
|
return DEFAULT_ADDRESS;
|
|
146
176
|
}
|
|
147
177
|
|
|
148
|
-
async
|
|
178
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
149
179
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
150
180
|
}
|
|
151
181
|
|
|
152
|
-
|
|
182
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
153
183
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
154
184
|
}
|
|
155
185
|
|
|
156
|
-
async
|
|
157
|
-
return (await this.stateMachine.node.
|
|
186
|
+
async getLastBlockTimestamp() {
|
|
187
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
158
188
|
}
|
|
159
189
|
|
|
160
|
-
async
|
|
190
|
+
async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
|
|
161
191
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
-
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
192
|
+
const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
|
|
163
193
|
|
|
164
194
|
if (block!.body.txEffects.length != 1) {
|
|
165
195
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,11 +198,40 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
198
|
|
|
169
199
|
const txEffects = block!.body.txEffects[0];
|
|
170
200
|
|
|
171
|
-
|
|
201
|
+
const privateLogs = txEffects.privateLogs;
|
|
202
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
203
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
txHash: txEffects.txHash,
|
|
208
|
+
noteHashes: txEffects.noteHashes,
|
|
209
|
+
nullifiers: txEffects.nullifiers,
|
|
210
|
+
privateLogs,
|
|
211
|
+
};
|
|
172
212
|
}
|
|
173
213
|
|
|
174
|
-
async
|
|
175
|
-
|
|
214
|
+
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
215
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
216
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
221
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
222
|
+
contractAddress,
|
|
223
|
+
null,
|
|
224
|
+
async (call, execScopes) => {
|
|
225
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
226
|
+
},
|
|
227
|
+
blockHeader,
|
|
228
|
+
jobId,
|
|
229
|
+
[scope],
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
234
|
+
const events = (
|
|
176
235
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
177
236
|
contractAddress,
|
|
178
237
|
scopes: [scope],
|
|
@@ -180,9 +239,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
180
239
|
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
181
240
|
})
|
|
182
241
|
).map(e => e.packedEvent);
|
|
242
|
+
|
|
243
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
244
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
245
|
+
}
|
|
246
|
+
if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
247
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return events;
|
|
183
251
|
}
|
|
184
252
|
|
|
185
|
-
async
|
|
253
|
+
async advanceBlocksBy(blocks: number) {
|
|
186
254
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
187
255
|
|
|
188
256
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -190,39 +258,76 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
190
258
|
}
|
|
191
259
|
}
|
|
192
260
|
|
|
193
|
-
|
|
261
|
+
advanceTimestampBy(duration: UInt64) {
|
|
194
262
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
195
263
|
this.nextBlockTimestamp += duration;
|
|
196
264
|
}
|
|
197
265
|
|
|
198
|
-
|
|
266
|
+
private deploymentNullifier(address: AztecAddress): Promise<Fr> {
|
|
267
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async deploy(
|
|
271
|
+
contractPath: string,
|
|
272
|
+
initializer: string,
|
|
273
|
+
args: Fr[],
|
|
274
|
+
secret: Fr,
|
|
275
|
+
salt: Fr,
|
|
276
|
+
deployer: AztecAddress,
|
|
277
|
+
): Promise<Fr[]> {
|
|
278
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
279
|
+
rootPath: this.rootPath,
|
|
280
|
+
packageName: this.packageName,
|
|
281
|
+
contractPath,
|
|
282
|
+
initializer,
|
|
283
|
+
args,
|
|
284
|
+
secret,
|
|
285
|
+
salt,
|
|
286
|
+
deployer,
|
|
287
|
+
});
|
|
288
|
+
|
|
199
289
|
// Emit deployment nullifier
|
|
200
290
|
await this.mineBlock({
|
|
201
|
-
nullifiers: [
|
|
202
|
-
await siloNullifier(
|
|
203
|
-
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
204
|
-
instance.address.toField(),
|
|
205
|
-
),
|
|
206
|
-
],
|
|
291
|
+
nullifiers: [await this.deploymentNullifier(instance.address)],
|
|
207
292
|
});
|
|
208
293
|
|
|
209
294
|
if (!secret.equals(Fr.ZERO)) {
|
|
210
|
-
await this.
|
|
295
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
211
296
|
} else {
|
|
212
297
|
await this.contractStore.addContractInstance(instance);
|
|
213
|
-
await this.contractStore.addContractArtifact(
|
|
298
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
214
299
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
215
300
|
}
|
|
301
|
+
|
|
302
|
+
return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
307
|
+
*/
|
|
308
|
+
async mineDeploymentNullifiers(addresses: AztecAddress[]) {
|
|
309
|
+
await this.mineBlock({
|
|
310
|
+
nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
|
|
311
|
+
});
|
|
216
312
|
}
|
|
217
313
|
|
|
218
|
-
async
|
|
314
|
+
async addAccount(secret: Fr) {
|
|
315
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
316
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
private async registerContractAndAddAccount(
|
|
320
|
+
artifact: ContractArtifact,
|
|
321
|
+
instance: ContractInstanceWithAddress,
|
|
322
|
+
secret: Fr,
|
|
323
|
+
) {
|
|
219
324
|
const partialAddress = await computePartialAddress(instance);
|
|
220
325
|
|
|
221
326
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
222
327
|
await this.contractStore.addContractInstance(instance);
|
|
223
|
-
await this.contractStore.addContractArtifact(
|
|
328
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
224
329
|
|
|
225
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
330
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
226
331
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
227
332
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
228
333
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -230,9 +335,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
230
335
|
return completeAddress;
|
|
231
336
|
}
|
|
232
337
|
|
|
233
|
-
async
|
|
338
|
+
async createAccount(secret: Fr) {
|
|
234
339
|
// This is a foot gun !
|
|
235
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
340
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
|
|
236
341
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
237
342
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
238
343
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -240,27 +345,63 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
240
345
|
return completeAddress;
|
|
241
346
|
}
|
|
242
347
|
|
|
243
|
-
async
|
|
348
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
244
349
|
const account = await this.accountStore.getAccount(address);
|
|
245
|
-
const
|
|
350
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
351
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
246
352
|
|
|
247
353
|
const schnorr = new Schnorr();
|
|
248
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
354
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
249
355
|
|
|
250
|
-
const authWitness = new AuthWitness(messageHash,
|
|
356
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
251
357
|
|
|
252
358
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
253
359
|
}
|
|
254
360
|
|
|
255
|
-
|
|
256
|
-
|
|
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
|
+
async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
|
|
377
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
378
|
+
const { size } = await this.stateMachine.synchronizer
|
|
379
|
+
.getCommitted()
|
|
380
|
+
.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
381
|
+
const leafIndex = new Fr(size);
|
|
382
|
+
|
|
383
|
+
const message = new L1ToL2Message(
|
|
384
|
+
new L1Actor(sender, this.chainId.toNumber()),
|
|
385
|
+
new L2Actor(recipient, this.version.toNumber()),
|
|
386
|
+
content,
|
|
387
|
+
secretHash,
|
|
388
|
+
leafIndex,
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
await this.mineBlock({ l1ToL2Messages: [message.hash()] });
|
|
392
|
+
|
|
393
|
+
return leafIndex;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
|
|
397
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
257
398
|
|
|
258
399
|
const txEffect = TxEffect.empty();
|
|
259
400
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
260
401
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
261
402
|
|
|
262
403
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
263
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
404
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
264
405
|
|
|
265
406
|
const globals = makeGlobalVariables(undefined, {
|
|
266
407
|
blockNumber,
|
|
@@ -274,22 +415,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
274
415
|
|
|
275
416
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
276
417
|
|
|
277
|
-
await this.stateMachine.handleL2Block(block);
|
|
418
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
278
419
|
}
|
|
279
420
|
|
|
280
|
-
async
|
|
281
|
-
from: AztecAddress,
|
|
421
|
+
async privateCallNewFlow(
|
|
422
|
+
from: AztecAddress | undefined,
|
|
282
423
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
283
424
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
284
425
|
args: Fr[],
|
|
285
426
|
argsHash: Fr = Fr.zero(),
|
|
286
427
|
isStaticCall: boolean = false,
|
|
428
|
+
additionalScopes: AztecAddress[] = [],
|
|
429
|
+
jobId: string,
|
|
430
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
431
|
+
gasSettings: GasSettings,
|
|
287
432
|
) {
|
|
433
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
434
|
+
const anchoredContractData = new AnchoredContractData(
|
|
435
|
+
this.contractStore,
|
|
436
|
+
this.stateMachine.contractClassService,
|
|
437
|
+
blockHeader,
|
|
438
|
+
);
|
|
439
|
+
|
|
288
440
|
this.logger.verbose(
|
|
289
|
-
`Executing external function ${await
|
|
441
|
+
`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
290
442
|
);
|
|
291
443
|
|
|
292
|
-
const artifact = await
|
|
444
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
293
445
|
if (!artifact) {
|
|
294
446
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
295
447
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -297,25 +449,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
297
449
|
throw new Error(message);
|
|
298
450
|
}
|
|
299
451
|
|
|
452
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
453
|
+
|
|
300
454
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
301
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
302
|
-
await this.executeUtilityCall(call);
|
|
455
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
456
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
303
457
|
};
|
|
304
458
|
|
|
305
|
-
await
|
|
306
|
-
|
|
307
|
-
|
|
459
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
460
|
+
targetContractAddress,
|
|
461
|
+
functionSelector,
|
|
462
|
+
utilityExecutor,
|
|
463
|
+
blockHeader,
|
|
464
|
+
jobId,
|
|
465
|
+
scopes,
|
|
466
|
+
);
|
|
308
467
|
|
|
309
|
-
const
|
|
468
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
310
469
|
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
470
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
471
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
314
472
|
|
|
315
473
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
316
474
|
|
|
317
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
318
|
-
|
|
319
475
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
320
476
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
321
477
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -327,43 +483,51 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
327
483
|
|
|
328
484
|
const simulator = new WASMSimulator();
|
|
329
485
|
|
|
330
|
-
const
|
|
486
|
+
const transientArrayService = new TransientArrayService();
|
|
487
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
331
488
|
argsHash,
|
|
332
489
|
txContext,
|
|
490
|
+
// The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
|
|
491
|
+
txRequestSalt: Fr.ZERO,
|
|
333
492
|
callContext,
|
|
334
|
-
|
|
335
|
-
blockHeader,
|
|
493
|
+
anchorBlockHeader: blockHeader,
|
|
336
494
|
utilityExecutor,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
[],
|
|
341
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
495
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
496
|
+
capsules: [],
|
|
497
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
342
498
|
noteCache,
|
|
343
499
|
taggingIndexCache,
|
|
344
|
-
|
|
345
|
-
this.noteStore,
|
|
346
|
-
this.keyStore,
|
|
347
|
-
this.addressStore,
|
|
348
|
-
this.stateMachine.node,
|
|
349
|
-
this.
|
|
350
|
-
this.
|
|
351
|
-
this.
|
|
352
|
-
this.
|
|
353
|
-
this.
|
|
354
|
-
this.privateEventStore,
|
|
355
|
-
this.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
*/
|
|
364
|
-
from,
|
|
500
|
+
anchoredContractData,
|
|
501
|
+
noteStore: this.noteStore,
|
|
502
|
+
keyStore: this.keyStore,
|
|
503
|
+
addressStore: this.addressStore,
|
|
504
|
+
aztecNode: this.stateMachine.node,
|
|
505
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
506
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
507
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
508
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
509
|
+
factService: new FactService(this.factStore, scopes),
|
|
510
|
+
privateEventStore: this.privateEventStore,
|
|
511
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
512
|
+
jobId,
|
|
513
|
+
totalPublicCalldataCount: 0,
|
|
514
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
515
|
+
scopes,
|
|
516
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
517
|
+
// contract would perform, including setting senderForTags.
|
|
518
|
+
senderForTags: from,
|
|
365
519
|
simulator,
|
|
366
|
-
|
|
520
|
+
txResolver: this.stateMachine.txResolver,
|
|
521
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
522
|
+
hooks: composeHooks({
|
|
523
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
|
|
524
|
+
isStaticCall ? 'private view' : 'private',
|
|
525
|
+
authorizedUtilityCallTargets,
|
|
526
|
+
),
|
|
527
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
|
|
528
|
+
}),
|
|
529
|
+
transientArrayService,
|
|
530
|
+
});
|
|
367
531
|
|
|
368
532
|
// Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
|
|
369
533
|
let result: PrivateExecutionResult;
|
|
@@ -385,12 +549,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
385
549
|
);
|
|
386
550
|
const publicFunctionsCalldata = await Promise.all(
|
|
387
551
|
publicCallRequests.map(async r => {
|
|
388
|
-
const calldata = await privateExecutionOracle.
|
|
552
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
389
553
|
return new HashedValues(calldata, r.calldataHash);
|
|
390
554
|
}),
|
|
391
555
|
);
|
|
392
556
|
|
|
393
|
-
noteCache.finish();
|
|
394
557
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
395
558
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
396
559
|
} catch (err) {
|
|
@@ -402,7 +565,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
402
565
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
403
566
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
404
567
|
result,
|
|
405
|
-
|
|
568
|
+
(addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
|
|
569
|
+
this.stateMachine.node,
|
|
406
570
|
minRevertibleSideEffectCounter,
|
|
407
571
|
);
|
|
408
572
|
|
|
@@ -415,7 +579,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
415
579
|
|
|
416
580
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
417
581
|
|
|
418
|
-
const
|
|
582
|
+
const bindings = this.logger.getBindings();
|
|
583
|
+
const contractsDB = new PublicContractsDB(
|
|
584
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
585
|
+
bindings,
|
|
586
|
+
);
|
|
419
587
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
420
588
|
const config = PublicSimulatorConfig.from({
|
|
421
589
|
skipFeeEnforcement: true,
|
|
@@ -428,8 +596,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
428
596
|
globals,
|
|
429
597
|
guardedMerkleTrees,
|
|
430
598
|
contractsDB,
|
|
431
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
599
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
432
600
|
new TestDateProvider(),
|
|
601
|
+
undefined,
|
|
602
|
+
createLogger('simulator:public-processor', bindings),
|
|
433
603
|
);
|
|
434
604
|
|
|
435
605
|
const tx = await Tx.create({
|
|
@@ -454,7 +624,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
454
624
|
} else if (!processedTx.revertCode.isOK()) {
|
|
455
625
|
if (processedTx.revertReason) {
|
|
456
626
|
try {
|
|
457
|
-
await enrichPublicSimulationError(
|
|
627
|
+
await enrichPublicSimulationError(
|
|
628
|
+
processedTx.revertReason,
|
|
629
|
+
this.contractStore,
|
|
630
|
+
this.stateMachine.contractClassService,
|
|
631
|
+
await this.stateMachine.anchorBlockStore.getBlockHeader(),
|
|
632
|
+
this.logger,
|
|
633
|
+
);
|
|
458
634
|
// eslint-disable-next-line no-empty
|
|
459
635
|
} catch {}
|
|
460
636
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -463,11 +639,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
463
639
|
}
|
|
464
640
|
}
|
|
465
641
|
|
|
642
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
643
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
644
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
645
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
646
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
647
|
+
|
|
466
648
|
if (isStaticCall) {
|
|
467
649
|
await checkpoint!.revert();
|
|
468
650
|
|
|
469
651
|
await forkedWorldTrees.close();
|
|
470
|
-
return executionResult.returnValues ?? [];
|
|
652
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
471
653
|
}
|
|
472
654
|
|
|
473
655
|
const txEffect = TxEffect.empty();
|
|
@@ -489,31 +671,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
489
671
|
|
|
490
672
|
await forkedWorldTrees.close();
|
|
491
673
|
|
|
492
|
-
return executionResult.returnValues ?? [];
|
|
674
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
493
675
|
}
|
|
494
676
|
|
|
495
|
-
async
|
|
496
|
-
from: AztecAddress,
|
|
677
|
+
async publicCallNewFlow(
|
|
678
|
+
from: AztecAddress | undefined,
|
|
497
679
|
targetContractAddress: AztecAddress,
|
|
498
680
|
calldata: Fr[],
|
|
499
681
|
isStaticCall: boolean,
|
|
682
|
+
gasSettings: GasSettings,
|
|
500
683
|
) {
|
|
501
|
-
this.
|
|
502
|
-
|
|
684
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
685
|
+
const anchoredContractData = new AnchoredContractData(
|
|
686
|
+
this.contractStore,
|
|
687
|
+
this.stateMachine.contractClassService,
|
|
688
|
+
anchorBlockHeader,
|
|
503
689
|
);
|
|
504
690
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
691
|
+
this.logger.verbose(
|
|
692
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
693
|
+
);
|
|
510
694
|
|
|
511
|
-
const
|
|
695
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
512
696
|
|
|
513
697
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
514
698
|
|
|
515
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
516
|
-
|
|
517
699
|
const calldataHash = await computeCalldataHash(calldata);
|
|
518
700
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
519
701
|
|
|
@@ -526,7 +708,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
526
708
|
|
|
527
709
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
528
710
|
|
|
529
|
-
const
|
|
711
|
+
const bindings2 = this.logger.getBindings();
|
|
712
|
+
const contractsDB = new PublicContractsDB(
|
|
713
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
714
|
+
bindings2,
|
|
715
|
+
);
|
|
530
716
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
531
717
|
const config = PublicSimulatorConfig.from({
|
|
532
718
|
skipFeeEnforcement: true,
|
|
@@ -535,8 +721,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
535
721
|
collectStatistics: false,
|
|
536
722
|
collectCallMetadata: true,
|
|
537
723
|
});
|
|
538
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
539
|
-
const processor = new PublicProcessor(
|
|
724
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
725
|
+
const processor = new PublicProcessor(
|
|
726
|
+
globals,
|
|
727
|
+
guardedMerkleTrees,
|
|
728
|
+
contractsDB,
|
|
729
|
+
simulator,
|
|
730
|
+
new TestDateProvider(),
|
|
731
|
+
undefined,
|
|
732
|
+
createLogger('simulator:public-processor', bindings2),
|
|
733
|
+
);
|
|
540
734
|
|
|
541
735
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
542
736
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -549,7 +743,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
549
743
|
// may require producing reverts.
|
|
550
744
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
551
745
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
552
|
-
from,
|
|
746
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
553
747
|
targetContractAddress,
|
|
554
748
|
isStaticCall,
|
|
555
749
|
calldataHash,
|
|
@@ -567,7 +761,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
567
761
|
constantData,
|
|
568
762
|
/*gasUsed=*/ new Gas(0, 0),
|
|
569
763
|
/*feePayer=*/ AztecAddress.zero(),
|
|
570
|
-
/*
|
|
764
|
+
/*expirationTimestamp=*/ 0n,
|
|
571
765
|
inputsForPublic,
|
|
572
766
|
undefined,
|
|
573
767
|
);
|
|
@@ -594,7 +788,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
594
788
|
} else if (!processedTx.revertCode.isOK()) {
|
|
595
789
|
if (processedTx.revertReason) {
|
|
596
790
|
try {
|
|
597
|
-
await enrichPublicSimulationError(
|
|
791
|
+
await enrichPublicSimulationError(
|
|
792
|
+
processedTx.revertReason,
|
|
793
|
+
this.contractStore,
|
|
794
|
+
this.stateMachine.contractClassService,
|
|
795
|
+
anchorBlockHeader,
|
|
796
|
+
this.logger,
|
|
797
|
+
);
|
|
598
798
|
// eslint-disable-next-line no-empty
|
|
599
799
|
} catch {}
|
|
600
800
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -635,37 +835,77 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
635
835
|
return returnValues ?? [];
|
|
636
836
|
}
|
|
637
837
|
|
|
638
|
-
async
|
|
838
|
+
async executeUtilityFunction(
|
|
839
|
+
from: AztecAddress | undefined,
|
|
639
840
|
targetContractAddress: AztecAddress,
|
|
640
841
|
functionSelector: FunctionSelector,
|
|
641
842
|
args: Fr[],
|
|
843
|
+
jobId: string,
|
|
844
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
642
845
|
) {
|
|
643
|
-
const
|
|
846
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
847
|
+
const anchoredContractData = new AnchoredContractData(
|
|
848
|
+
this.contractStore,
|
|
849
|
+
this.stateMachine.contractClassService,
|
|
850
|
+
blockHeader,
|
|
851
|
+
);
|
|
852
|
+
|
|
853
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
644
854
|
if (!artifact) {
|
|
645
855
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
646
856
|
}
|
|
647
857
|
|
|
648
858
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
649
|
-
await
|
|
650
|
-
await this.executeUtilityCall(call);
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
const call = new FunctionCall(
|
|
654
|
-
artifact.name,
|
|
859
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
655
860
|
targetContractAddress,
|
|
656
861
|
functionSelector,
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
862
|
+
async (call, execScopes) => {
|
|
863
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
864
|
+
},
|
|
865
|
+
blockHeader,
|
|
866
|
+
jobId,
|
|
867
|
+
await this.keyStore.getAccounts(),
|
|
662
868
|
);
|
|
663
869
|
|
|
664
|
-
|
|
870
|
+
const call = FunctionCall.from({
|
|
871
|
+
name: artifact.name,
|
|
872
|
+
to: targetContractAddress,
|
|
873
|
+
selector: functionSelector,
|
|
874
|
+
type: FunctionType.UTILITY,
|
|
875
|
+
hideMsgSender: false,
|
|
876
|
+
isStatic: false,
|
|
877
|
+
args,
|
|
878
|
+
returnTypes: [],
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
return this.executeUtilityCall(call, {
|
|
882
|
+
from,
|
|
883
|
+
scopes: await this.keyStore.getAccounts(),
|
|
884
|
+
jobId,
|
|
885
|
+
authorizedUtilityCallTargets,
|
|
886
|
+
});
|
|
665
887
|
}
|
|
666
888
|
|
|
667
|
-
private async executeUtilityCall(
|
|
668
|
-
|
|
889
|
+
private async executeUtilityCall(
|
|
890
|
+
call: FunctionCall,
|
|
891
|
+
{
|
|
892
|
+
from = AztecAddress.NULL_MSG_SENDER,
|
|
893
|
+
scopes,
|
|
894
|
+
jobId,
|
|
895
|
+
authorizedUtilityCallTargets = [],
|
|
896
|
+
}: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
|
|
897
|
+
): Promise<Fr[]> {
|
|
898
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
899
|
+
const anchoredContractData = new AnchoredContractData(
|
|
900
|
+
this.contractStore,
|
|
901
|
+
this.stateMachine.contractClassService,
|
|
902
|
+
anchorBlockHeader,
|
|
903
|
+
);
|
|
904
|
+
|
|
905
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
906
|
+
if (!entryPointArtifact) {
|
|
907
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
908
|
+
}
|
|
669
909
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
670
910
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
671
911
|
}
|
|
@@ -676,26 +916,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
676
916
|
});
|
|
677
917
|
|
|
678
918
|
try {
|
|
679
|
-
const
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
919
|
+
const simulator = new WASMSimulator();
|
|
920
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
921
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId, authorizedUtilityCallTargets });
|
|
922
|
+
};
|
|
923
|
+
const oracle = new UtilityExecutionOracle({
|
|
924
|
+
callContext: CallContext.from({
|
|
925
|
+
msgSender: from,
|
|
926
|
+
contractAddress: call.to,
|
|
927
|
+
functionSelector: call.selector,
|
|
928
|
+
isStaticCall: true,
|
|
929
|
+
}),
|
|
930
|
+
authWitnesses: [],
|
|
931
|
+
capsules: [],
|
|
684
932
|
anchorBlockHeader,
|
|
685
|
-
|
|
686
|
-
this.noteStore,
|
|
687
|
-
this.keyStore,
|
|
688
|
-
this.addressStore,
|
|
689
|
-
this.stateMachine.node,
|
|
690
|
-
this.
|
|
691
|
-
this.
|
|
692
|
-
this.
|
|
693
|
-
this.
|
|
694
|
-
this.privateEventStore,
|
|
695
|
-
this.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
933
|
+
anchoredContractData,
|
|
934
|
+
noteStore: this.noteStore,
|
|
935
|
+
keyStore: this.keyStore,
|
|
936
|
+
addressStore: this.addressStore,
|
|
937
|
+
aztecNode: this.stateMachine.node,
|
|
938
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
939
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
940
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
941
|
+
factService: new FactService(this.factStore, scopes),
|
|
942
|
+
privateEventStore: this.privateEventStore,
|
|
943
|
+
txResolver: this.stateMachine.txResolver,
|
|
944
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
945
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
946
|
+
jobId,
|
|
947
|
+
scopes,
|
|
948
|
+
simulator,
|
|
949
|
+
utilityExecutor,
|
|
950
|
+
hooks: composeHooks({
|
|
951
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
952
|
+
}),
|
|
953
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
954
|
+
transientArrayService: new TransientArrayService(),
|
|
955
|
+
});
|
|
956
|
+
const acirExecutionResult = await simulator
|
|
957
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
699
958
|
.catch((err: Error) => {
|
|
700
959
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
701
960
|
throw new ExecutionError(
|
|
@@ -709,20 +968,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
709
968
|
);
|
|
710
969
|
});
|
|
711
970
|
|
|
712
|
-
this.logger.verbose(`Utility
|
|
971
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
713
972
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
714
973
|
} catch (err) {
|
|
715
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
974
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
716
975
|
}
|
|
717
976
|
}
|
|
718
977
|
|
|
719
|
-
close(): [bigint, Map<string, AuthWitness
|
|
978
|
+
close(): [bigint, Map<string, AuthWitness>, TXETaggingSecretStrategies] {
|
|
720
979
|
this.logger.debug('Exiting Top Level Context');
|
|
721
|
-
return [this.nextBlockTimestamp, this.authwits];
|
|
980
|
+
return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategies];
|
|
722
981
|
}
|
|
723
982
|
|
|
724
983
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
725
|
-
const
|
|
726
|
-
return
|
|
984
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
985
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
private buildAuthorizeUtilityCallHook(
|
|
989
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
990
|
+
authorizedTargets: AztecAddress[],
|
|
991
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
992
|
+
if (authorizedTargets.length === 0) {
|
|
993
|
+
return undefined;
|
|
994
|
+
}
|
|
995
|
+
return req =>
|
|
996
|
+
Promise.resolve({
|
|
997
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
998
|
+
});
|
|
727
999
|
}
|
|
728
1000
|
}
|