@aztec/txe 0.0.1-commit.c31f2472 → 0.0.1-commit.c52d6e7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/AuthRegistry-QVGDDH5X.js +3 -0
- package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
- package/dest/ContractClassRegistry-PVNCKGG7.js +3 -0
- package/dest/ContractClassRegistry-PVNCKGG7.js.map +7 -0
- package/dest/ContractInstanceRegistry-WLOZKTR6.js +3 -0
- package/dest/ContractInstanceRegistry-WLOZKTR6.js.map +7 -0
- package/dest/FeeJuice-MAQJU53K.js +3 -0
- package/dest/FeeJuice-MAQJU53K.js.map +7 -0
- package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
- package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
- package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
- package/dest/MultiCallEntrypoint-QG5H33ZZ.js.map +7 -0
- package/dest/SchnorrAccount-ADD65DYA.js +3 -0
- package/dest/SchnorrAccount-ADD65DYA.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js +3 -0
- package/dest/SchnorrInitializerlessAccount-TWGKRUSY.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 +22 -0
- package/dest/bin/index.js +3 -30
- package/dest/bin/index.js.map +7 -0
- package/dest/bin/oracle_test_server.d.ts +3 -0
- package/dest/bin/oracle_test_server.d.ts.map +1 -0
- package/dest/bin/oracle_test_server.js +41 -0
- package/dest/chunk-32UHX7YY.js +3 -0
- package/dest/chunk-32UHX7YY.js.map +7 -0
- package/dest/chunk-RVEPNDEP.js +304 -0
- package/dest/chunk-RVEPNDEP.js.map +7 -0
- package/dest/chunk-XWIMXLKD.js +258 -0
- package/dest/chunk-XWIMXLKD.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 +38833 -0
- package/dest/msgpackr_fr_extension.d.ts +2 -0
- package/dest/msgpackr_fr_extension.d.ts.map +1 -0
- package/dest/msgpackr_fr_extension.js +21 -0
- package/dest/oracle/interfaces.d.ts +69 -30
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
- package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
- package/dest/oracle/tagging_secret_strategy.js +12 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/default_fixtures.js +200 -0
- package/dest/oracle/test-resolver/index.d.ts +9 -0
- package/dest/oracle/test-resolver/index.d.ts.map +1 -0
- package/dest/oracle/test-resolver/index.js +32 -0
- package/dest/oracle/test-resolver/resolver.d.ts +48 -0
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
- package/dest/oracle/test-resolver/resolver.js +181 -0
- package/dest/oracle/txe_oracle_public_context.d.ts +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 +767 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +69 -29
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +607 -279
- 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 +116 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +909 -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 +19 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +36 -2
- package/dest/state_machine/synchronizer.d.ts +14 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +22 -9
- package/dest/txe_session.d.ts +92 -16
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +380 -57
- 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 +194 -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 +31 -0
- package/src/bin/index.ts +11 -2
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +11 -1
- package/src/dispatcher_pool.ts +317 -0
- package/src/index.ts +99 -190
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +75 -35
- package/src/oracle/tagging_secret_strategy.ts +25 -0
- package/src/oracle/test-resolver/default_fixtures.ts +271 -0
- package/src/oracle/test-resolver/index.ts +44 -0
- package/src/oracle/test-resolver/resolver.ts +245 -0
- package/src/oracle/txe_oracle_public_context.ts +74 -12
- package/src/oracle/txe_oracle_registry.ts +556 -0
- package/src/oracle/txe_oracle_top_level_context.ts +464 -178
- 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 +1126 -987
- 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 +47 -3
- package/src/state_machine/synchronizer.ts +31 -10
- package/src/txe_session.ts +625 -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';
|
|
@@ -45,10 +53,10 @@ import {
|
|
|
45
53
|
witnessMapToFields,
|
|
46
54
|
} from '@aztec/simulator/client';
|
|
47
55
|
import {
|
|
48
|
-
CppPublicTxSimulator,
|
|
49
56
|
GuardedMerkleTreeOperations,
|
|
50
57
|
PublicContractsDB,
|
|
51
58
|
PublicProcessor,
|
|
59
|
+
PublicTxSimulator,
|
|
52
60
|
} from '@aztec/simulator/server';
|
|
53
61
|
import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
54
62
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
@@ -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();
|
|
304
|
+
}
|
|
305
|
+
|
|
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);
|
|
216
318
|
}
|
|
217
319
|
|
|
218
|
-
async
|
|
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,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
230
336
|
return completeAddress;
|
|
231
337
|
}
|
|
232
338
|
|
|
233
|
-
async
|
|
234
|
-
|
|
235
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
339
|
+
async createAccount(secret: Fr, partialAddress: Fr) {
|
|
340
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
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,67 @@ 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
|
+
setAuthorizeAllUtilityCallTargets(authorizeAll: boolean): void {
|
|
377
|
+
this.authorizeAllUtilityCallTargets = authorizeAll;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
|
|
381
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
382
|
+
const { size } = await this.stateMachine.synchronizer
|
|
383
|
+
.getCommitted()
|
|
384
|
+
.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
385
|
+
const leafIndex = new Fr(size);
|
|
386
|
+
|
|
387
|
+
const message = new L1ToL2Message(
|
|
388
|
+
new L1Actor(sender, this.chainId.toNumber()),
|
|
389
|
+
new L2Actor(recipient, this.version.toNumber()),
|
|
390
|
+
content,
|
|
391
|
+
secretHash,
|
|
392
|
+
leafIndex,
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
await this.mineBlock({ l1ToL2Messages: [message.hash()] });
|
|
396
|
+
|
|
397
|
+
return leafIndex;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
|
|
401
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
257
402
|
|
|
258
403
|
const txEffect = TxEffect.empty();
|
|
259
404
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
260
405
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
261
406
|
|
|
262
407
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
263
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
408
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
264
409
|
|
|
265
410
|
const globals = makeGlobalVariables(undefined, {
|
|
266
411
|
blockNumber,
|
|
@@ -274,22 +419,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
274
419
|
|
|
275
420
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
276
421
|
|
|
277
|
-
await this.stateMachine.handleL2Block(block);
|
|
422
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
278
423
|
}
|
|
279
424
|
|
|
280
|
-
async
|
|
281
|
-
from: AztecAddress,
|
|
425
|
+
async privateCallNewFlow(
|
|
426
|
+
from: AztecAddress | undefined,
|
|
282
427
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
283
428
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
284
429
|
args: Fr[],
|
|
285
430
|
argsHash: Fr = Fr.zero(),
|
|
286
431
|
isStaticCall: boolean = false,
|
|
432
|
+
additionalScopes: AztecAddress[] = [],
|
|
433
|
+
jobId: string,
|
|
434
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
435
|
+
gasSettings: GasSettings,
|
|
287
436
|
) {
|
|
437
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
438
|
+
const anchoredContractData = new AnchoredContractData(
|
|
439
|
+
this.contractStore,
|
|
440
|
+
this.stateMachine.contractClassService,
|
|
441
|
+
blockHeader,
|
|
442
|
+
);
|
|
443
|
+
|
|
288
444
|
this.logger.verbose(
|
|
289
|
-
`Executing external function ${await
|
|
445
|
+
`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
290
446
|
);
|
|
291
447
|
|
|
292
|
-
const artifact = await
|
|
448
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
293
449
|
if (!artifact) {
|
|
294
450
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
295
451
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -297,25 +453,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
297
453
|
throw new Error(message);
|
|
298
454
|
}
|
|
299
455
|
|
|
456
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
457
|
+
|
|
300
458
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
301
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
302
|
-
await this.executeUtilityCall(call);
|
|
459
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
460
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
303
461
|
};
|
|
304
462
|
|
|
305
|
-
await
|
|
306
|
-
|
|
307
|
-
|
|
463
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
464
|
+
targetContractAddress,
|
|
465
|
+
functionSelector,
|
|
466
|
+
utilityExecutor,
|
|
467
|
+
blockHeader,
|
|
468
|
+
jobId,
|
|
469
|
+
scopes,
|
|
470
|
+
);
|
|
308
471
|
|
|
309
|
-
const
|
|
472
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
310
473
|
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
474
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
475
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
314
476
|
|
|
315
477
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
316
478
|
|
|
317
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
318
|
-
|
|
319
479
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
320
480
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
321
481
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -327,43 +487,50 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
327
487
|
|
|
328
488
|
const simulator = new WASMSimulator();
|
|
329
489
|
|
|
330
|
-
const
|
|
490
|
+
const transientArrayService = new TransientArrayService();
|
|
491
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
331
492
|
argsHash,
|
|
332
493
|
txContext,
|
|
494
|
+
txRequestSalt: Fr.ZERO,
|
|
333
495
|
callContext,
|
|
334
|
-
|
|
335
|
-
blockHeader,
|
|
496
|
+
anchorBlockHeader: blockHeader,
|
|
336
497
|
utilityExecutor,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
[],
|
|
341
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
498
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
499
|
+
capsules: [],
|
|
500
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
342
501
|
noteCache,
|
|
343
502
|
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,
|
|
503
|
+
anchoredContractData,
|
|
504
|
+
noteStore: this.noteStore,
|
|
505
|
+
keyStore: this.keyStore,
|
|
506
|
+
addressStore: this.addressStore,
|
|
507
|
+
aztecNode: this.stateMachine.node,
|
|
508
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
509
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
510
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
511
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
512
|
+
factService: new FactService(this.factStore, scopes),
|
|
513
|
+
privateEventStore: this.privateEventStore,
|
|
514
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
515
|
+
jobId,
|
|
516
|
+
totalPublicCalldataCount: 0,
|
|
517
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
518
|
+
scopes,
|
|
519
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
520
|
+
// contract would perform, including setting senderForTags.
|
|
521
|
+
senderForTags: from,
|
|
365
522
|
simulator,
|
|
366
|
-
|
|
523
|
+
txResolver: this.stateMachine.txResolver,
|
|
524
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
525
|
+
hooks: composeHooks({
|
|
526
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
|
|
527
|
+
isStaticCall ? 'private view' : 'private',
|
|
528
|
+
authorizedUtilityCallTargets,
|
|
529
|
+
),
|
|
530
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
|
|
531
|
+
}),
|
|
532
|
+
transientArrayService,
|
|
533
|
+
});
|
|
367
534
|
|
|
368
535
|
// Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
|
|
369
536
|
let result: PrivateExecutionResult;
|
|
@@ -385,12 +552,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
385
552
|
);
|
|
386
553
|
const publicFunctionsCalldata = await Promise.all(
|
|
387
554
|
publicCallRequests.map(async r => {
|
|
388
|
-
const calldata = await privateExecutionOracle.
|
|
555
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
389
556
|
return new HashedValues(calldata, r.calldataHash);
|
|
390
557
|
}),
|
|
391
558
|
);
|
|
392
559
|
|
|
393
|
-
noteCache.finish();
|
|
394
560
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
395
561
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
396
562
|
} catch (err) {
|
|
@@ -402,7 +568,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
402
568
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
403
569
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
404
570
|
result,
|
|
405
|
-
|
|
571
|
+
(addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
|
|
572
|
+
this.stateMachine.node,
|
|
406
573
|
minRevertibleSideEffectCounter,
|
|
407
574
|
);
|
|
408
575
|
|
|
@@ -413,7 +580,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
413
580
|
globals.version = this.version;
|
|
414
581
|
globals.gasFees = GasFees.empty();
|
|
415
582
|
|
|
416
|
-
|
|
583
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
417
584
|
|
|
418
585
|
const bindings = this.logger.getBindings();
|
|
419
586
|
const contractsDB = new PublicContractsDB(
|
|
@@ -428,11 +595,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
428
595
|
collectStatistics: false,
|
|
429
596
|
collectCallMetadata: true,
|
|
430
597
|
});
|
|
598
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
599
|
+
const forkId = forkedWorldTrees.getRevision().forkId;
|
|
431
600
|
const processor = new PublicProcessor(
|
|
432
601
|
globals,
|
|
433
602
|
guardedMerkleTrees,
|
|
434
603
|
contractsDB,
|
|
435
|
-
new
|
|
604
|
+
new PublicTxSimulator(
|
|
605
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
606
|
+
globals,
|
|
607
|
+
contractsDB,
|
|
608
|
+
forkId,
|
|
609
|
+
config,
|
|
610
|
+
bindings,
|
|
611
|
+
),
|
|
436
612
|
new TestDateProvider(),
|
|
437
613
|
undefined,
|
|
438
614
|
createLogger('simulator:public-processor', bindings),
|
|
@@ -460,7 +636,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
460
636
|
} else if (!processedTx.revertCode.isOK()) {
|
|
461
637
|
if (processedTx.revertReason) {
|
|
462
638
|
try {
|
|
463
|
-
await enrichPublicSimulationError(
|
|
639
|
+
await enrichPublicSimulationError(
|
|
640
|
+
processedTx.revertReason,
|
|
641
|
+
this.contractStore,
|
|
642
|
+
this.stateMachine.contractClassService,
|
|
643
|
+
await this.stateMachine.anchorBlockStore.getBlockHeader(),
|
|
644
|
+
this.logger,
|
|
645
|
+
);
|
|
464
646
|
// eslint-disable-next-line no-empty
|
|
465
647
|
} catch {}
|
|
466
648
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -469,11 +651,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
469
651
|
}
|
|
470
652
|
}
|
|
471
653
|
|
|
654
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
655
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
656
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
657
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
658
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
659
|
+
|
|
472
660
|
if (isStaticCall) {
|
|
473
661
|
await checkpoint!.revert();
|
|
474
|
-
|
|
475
|
-
await forkedWorldTrees.close();
|
|
476
|
-
return executionResult.returnValues ?? [];
|
|
662
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
477
663
|
}
|
|
478
664
|
|
|
479
665
|
const txEffect = TxEffect.empty();
|
|
@@ -493,33 +679,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
493
679
|
|
|
494
680
|
await this.stateMachine.handleL2Block(l2Block);
|
|
495
681
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
return executionResult.returnValues ?? [];
|
|
682
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
499
683
|
}
|
|
500
684
|
|
|
501
|
-
async
|
|
502
|
-
from: AztecAddress,
|
|
685
|
+
async publicCallNewFlow(
|
|
686
|
+
from: AztecAddress | undefined,
|
|
503
687
|
targetContractAddress: AztecAddress,
|
|
504
688
|
calldata: Fr[],
|
|
505
689
|
isStaticCall: boolean,
|
|
690
|
+
gasSettings: GasSettings,
|
|
506
691
|
) {
|
|
507
|
-
this.
|
|
508
|
-
|
|
692
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
693
|
+
const anchoredContractData = new AnchoredContractData(
|
|
694
|
+
this.contractStore,
|
|
695
|
+
this.stateMachine.contractClassService,
|
|
696
|
+
anchorBlockHeader,
|
|
509
697
|
);
|
|
510
698
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
699
|
+
this.logger.verbose(
|
|
700
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
701
|
+
);
|
|
516
702
|
|
|
517
|
-
const
|
|
703
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
518
704
|
|
|
519
705
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
520
706
|
|
|
521
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
522
|
-
|
|
523
707
|
const calldataHash = await computeCalldataHash(calldata);
|
|
524
708
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
525
709
|
|
|
@@ -530,7 +714,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
530
714
|
globals.version = this.version;
|
|
531
715
|
globals.gasFees = GasFees.empty();
|
|
532
716
|
|
|
533
|
-
|
|
717
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
534
718
|
|
|
535
719
|
const bindings2 = this.logger.getBindings();
|
|
536
720
|
const contractsDB = new PublicContractsDB(
|
|
@@ -545,7 +729,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
545
729
|
collectStatistics: false,
|
|
546
730
|
collectCallMetadata: true,
|
|
547
731
|
});
|
|
548
|
-
|
|
732
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
733
|
+
const forkId2 = forkedWorldTrees.getRevision().forkId;
|
|
734
|
+
const simulator = new PublicTxSimulator(
|
|
735
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
736
|
+
globals,
|
|
737
|
+
contractsDB,
|
|
738
|
+
forkId2,
|
|
739
|
+
config,
|
|
740
|
+
bindings2,
|
|
741
|
+
);
|
|
549
742
|
const processor = new PublicProcessor(
|
|
550
743
|
globals,
|
|
551
744
|
guardedMerkleTrees,
|
|
@@ -567,7 +760,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
567
760
|
// may require producing reverts.
|
|
568
761
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
569
762
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
570
|
-
from,
|
|
763
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
571
764
|
targetContractAddress,
|
|
572
765
|
isStaticCall,
|
|
573
766
|
calldataHash,
|
|
@@ -585,7 +778,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
585
778
|
constantData,
|
|
586
779
|
/*gasUsed=*/ new Gas(0, 0),
|
|
587
780
|
/*feePayer=*/ AztecAddress.zero(),
|
|
588
|
-
/*
|
|
781
|
+
/*expirationTimestamp=*/ 0n,
|
|
589
782
|
inputsForPublic,
|
|
590
783
|
undefined,
|
|
591
784
|
);
|
|
@@ -612,7 +805,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
612
805
|
} else if (!processedTx.revertCode.isOK()) {
|
|
613
806
|
if (processedTx.revertReason) {
|
|
614
807
|
try {
|
|
615
|
-
await enrichPublicSimulationError(
|
|
808
|
+
await enrichPublicSimulationError(
|
|
809
|
+
processedTx.revertReason,
|
|
810
|
+
this.contractStore,
|
|
811
|
+
this.stateMachine.contractClassService,
|
|
812
|
+
anchorBlockHeader,
|
|
813
|
+
this.logger,
|
|
814
|
+
);
|
|
616
815
|
// eslint-disable-next-line no-empty
|
|
617
816
|
} catch {}
|
|
618
817
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -625,9 +824,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
625
824
|
|
|
626
825
|
if (isStaticCall) {
|
|
627
826
|
await checkpoint!.revert();
|
|
628
|
-
|
|
629
|
-
await forkedWorldTrees.close();
|
|
630
|
-
|
|
631
827
|
return returnValues ?? [];
|
|
632
828
|
}
|
|
633
829
|
|
|
@@ -648,42 +844,79 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
648
844
|
|
|
649
845
|
await this.stateMachine.handleL2Block(l2Block);
|
|
650
846
|
|
|
651
|
-
await forkedWorldTrees.close();
|
|
652
|
-
|
|
653
847
|
return returnValues ?? [];
|
|
654
848
|
}
|
|
655
849
|
|
|
656
|
-
async
|
|
850
|
+
async executeUtilityFunction(
|
|
851
|
+
from: AztecAddress | undefined,
|
|
657
852
|
targetContractAddress: AztecAddress,
|
|
658
853
|
functionSelector: FunctionSelector,
|
|
659
854
|
args: Fr[],
|
|
855
|
+
jobId: string,
|
|
856
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
660
857
|
) {
|
|
661
|
-
const
|
|
858
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
859
|
+
const anchoredContractData = new AnchoredContractData(
|
|
860
|
+
this.contractStore,
|
|
861
|
+
this.stateMachine.contractClassService,
|
|
862
|
+
blockHeader,
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
662
866
|
if (!artifact) {
|
|
663
867
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
664
868
|
}
|
|
665
869
|
|
|
666
870
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
667
|
-
await
|
|
668
|
-
await this.executeUtilityCall(call);
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
const call = new FunctionCall(
|
|
672
|
-
artifact.name,
|
|
871
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
673
872
|
targetContractAddress,
|
|
674
873
|
functionSelector,
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
874
|
+
async (call, execScopes) => {
|
|
875
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
876
|
+
},
|
|
877
|
+
blockHeader,
|
|
878
|
+
jobId,
|
|
879
|
+
await this.keyStore.getAccounts(),
|
|
680
880
|
);
|
|
681
881
|
|
|
682
|
-
|
|
882
|
+
const call = FunctionCall.from({
|
|
883
|
+
name: artifact.name,
|
|
884
|
+
to: targetContractAddress,
|
|
885
|
+
selector: functionSelector,
|
|
886
|
+
type: FunctionType.UTILITY,
|
|
887
|
+
hideMsgSender: false,
|
|
888
|
+
isStatic: false,
|
|
889
|
+
args,
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
return this.executeUtilityCall(call, {
|
|
893
|
+
from,
|
|
894
|
+
scopes: await this.keyStore.getAccounts(),
|
|
895
|
+
jobId,
|
|
896
|
+
authorizedUtilityCallTargets,
|
|
897
|
+
});
|
|
683
898
|
}
|
|
684
899
|
|
|
685
|
-
private async executeUtilityCall(
|
|
686
|
-
|
|
900
|
+
private async executeUtilityCall(
|
|
901
|
+
call: FunctionCall,
|
|
902
|
+
{
|
|
903
|
+
from = AztecAddress.NULL_MSG_SENDER,
|
|
904
|
+
scopes,
|
|
905
|
+
jobId,
|
|
906
|
+
authorizedUtilityCallTargets = [],
|
|
907
|
+
}: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
|
|
908
|
+
): Promise<Fr[]> {
|
|
909
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
910
|
+
const anchoredContractData = new AnchoredContractData(
|
|
911
|
+
this.contractStore,
|
|
912
|
+
this.stateMachine.contractClassService,
|
|
913
|
+
anchorBlockHeader,
|
|
914
|
+
);
|
|
915
|
+
|
|
916
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
917
|
+
if (!entryPointArtifact) {
|
|
918
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
919
|
+
}
|
|
687
920
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
688
921
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
689
922
|
}
|
|
@@ -694,26 +927,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
694
927
|
});
|
|
695
928
|
|
|
696
929
|
try {
|
|
697
|
-
const
|
|
698
|
-
const
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
930
|
+
const simulator = new WASMSimulator();
|
|
931
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
932
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
|
|
933
|
+
};
|
|
934
|
+
const oracle = new UtilityExecutionOracle({
|
|
935
|
+
callContext: CallContext.from({
|
|
936
|
+
msgSender: from,
|
|
937
|
+
contractAddress: call.to,
|
|
938
|
+
functionSelector: call.selector,
|
|
939
|
+
isStaticCall: true,
|
|
940
|
+
}),
|
|
941
|
+
authWitnesses: [],
|
|
942
|
+
capsules: [],
|
|
702
943
|
anchorBlockHeader,
|
|
703
|
-
|
|
704
|
-
this.noteStore,
|
|
705
|
-
this.keyStore,
|
|
706
|
-
this.addressStore,
|
|
707
|
-
this.stateMachine.node,
|
|
708
|
-
this.
|
|
709
|
-
this.
|
|
710
|
-
this.
|
|
711
|
-
this.
|
|
712
|
-
this.privateEventStore,
|
|
713
|
-
this.
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
944
|
+
anchoredContractData,
|
|
945
|
+
noteStore: this.noteStore,
|
|
946
|
+
keyStore: this.keyStore,
|
|
947
|
+
addressStore: this.addressStore,
|
|
948
|
+
aztecNode: this.stateMachine.node,
|
|
949
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
950
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
951
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
952
|
+
factService: new FactService(this.factStore, scopes),
|
|
953
|
+
privateEventStore: this.privateEventStore,
|
|
954
|
+
txResolver: this.stateMachine.txResolver,
|
|
955
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
956
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
957
|
+
jobId,
|
|
958
|
+
scopes,
|
|
959
|
+
simulator,
|
|
960
|
+
hooks: composeHooks({
|
|
961
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
962
|
+
}),
|
|
963
|
+
utilityExecutor,
|
|
964
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
965
|
+
transientArrayService: new TransientArrayService(),
|
|
966
|
+
});
|
|
967
|
+
const acirExecutionResult = await simulator
|
|
968
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
717
969
|
.catch((err: Error) => {
|
|
718
970
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
719
971
|
throw new ExecutionError(
|
|
@@ -727,20 +979,54 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
727
979
|
);
|
|
728
980
|
});
|
|
729
981
|
|
|
730
|
-
this.logger.verbose(`Utility
|
|
982
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
731
983
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
732
984
|
} catch (err) {
|
|
733
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
985
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
734
986
|
}
|
|
735
987
|
}
|
|
736
988
|
|
|
737
|
-
close():
|
|
989
|
+
close(): {
|
|
990
|
+
nextBlockTimestamp: bigint;
|
|
991
|
+
authwits: Map<string, AuthWitness>;
|
|
992
|
+
taggingSecretStrategies: TXETaggingSecretStrategies;
|
|
993
|
+
authorizeAllUtilityCallTargets: boolean;
|
|
994
|
+
} {
|
|
738
995
|
this.logger.debug('Exiting Top Level Context');
|
|
739
|
-
return
|
|
996
|
+
return {
|
|
997
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
998
|
+
authwits: this.authwits,
|
|
999
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
1000
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
|
|
1001
|
+
};
|
|
740
1002
|
}
|
|
741
1003
|
|
|
742
1004
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
743
|
-
const
|
|
744
|
-
return
|
|
1005
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
1006
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
private buildAuthorizeUtilityCallHook(
|
|
1010
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
1011
|
+
authorizedTargets: AztecAddress[],
|
|
1012
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
1013
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
1014
|
+
return authorizeAllUtilityCallsHook;
|
|
1015
|
+
}
|
|
1016
|
+
if (authorizedTargets.length === 0) {
|
|
1017
|
+
return undefined;
|
|
1018
|
+
}
|
|
1019
|
+
return req =>
|
|
1020
|
+
Promise.resolve({
|
|
1021
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
1022
|
+
});
|
|
745
1023
|
}
|
|
746
1024
|
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
|
|
1028
|
+
*
|
|
1029
|
+
* Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
|
|
1030
|
+
*/
|
|
1031
|
+
export const authorizeAllUtilityCallsHook: NonNullable<ExecutionHooks['authorizeUtilityCall']> = () =>
|
|
1032
|
+
Promise.resolve({ authorized: true });
|