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