@aztec/txe 0.0.1-commit.a072138 → 0.0.1-commit.a4600f49
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-HMC7WEOJ.js +3 -0
- package/dest/AuthRegistry-HMC7WEOJ.js.map +7 -0
- package/dest/ContractClassRegistry-TXCDCFNC.js +3 -0
- package/dest/ContractClassRegistry-TXCDCFNC.js.map +7 -0
- package/dest/ContractInstanceRegistry-2TZHWOTT.js +3 -0
- package/dest/ContractInstanceRegistry-2TZHWOTT.js.map +7 -0
- package/dest/FeeJuice-FDF3J2Q5.js +3 -0
- package/dest/FeeJuice-FDF3J2Q5.js.map +7 -0
- package/dest/HandshakeRegistry-C7JF4R54.js +3 -0
- package/dest/HandshakeRegistry-C7JF4R54.js.map +7 -0
- package/dest/MultiCallEntrypoint-IGLO227K.js +3 -0
- package/dest/MultiCallEntrypoint-IGLO227K.js.map +7 -0
- package/dest/SchnorrAccount-KCIHUCXS.js +3 -0
- package/dest/SchnorrAccount-KCIHUCXS.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-PVR6XUSN.js +3 -0
- package/dest/SchnorrInitializerlessAccount-PVR6XUSN.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-32UHX7YY.js +3 -0
- package/dest/chunk-32UHX7YY.js.map +7 -0
- package/dest/chunk-6AVNR3XX.js +304 -0
- package/dest/chunk-6AVNR3XX.js.map +7 -0
- package/dest/chunk-CJEH2W44.js +260 -0
- package/dest/chunk-CJEH2W44.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 +38497 -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 +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 +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 +582 -275
- 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 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +877 -612
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +30 -20
- package/dest/state_machine/dummy_p2p_client.d.ts +29 -16
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +53 -20
- package/dest/state_machine/global_variable_builder.d.ts +10 -6
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +8 -5
- package/dest/state_machine/index.d.ts +13 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +60 -15
- package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +33 -2
- package/dest/state_machine/synchronizer.d.ts +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 +89 -16
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +370 -55
- package/dest/utils/block_creation.d.ts +2 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +5 -3
- package/dest/utils/encoding.d.ts +192 -0
- package/dest/utils/encoding.d.ts.map +1 -0
- package/dest/{util → utils}/encoding.js +7 -2
- package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
- package/dest/utils/expected_failure_error.d.ts.map +1 -0
- package/dest/utils/tx_effect_creation.d.ts +1 -1
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +0 -1
- package/dest/{util → utils}/txe_account_store.d.ts +1 -1
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.d.ts +37 -0
- package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.js +161 -0
- package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/utils/txe_public_contract_data_source.js +51 -0
- package/dest/worker.bundle.js +3 -0
- package/dest/worker.bundle.js.map +7 -0
- package/dest/worker.d.ts +2 -0
- package/dest/worker.d.ts.map +1 -0
- package/dest/worker.js +92 -0
- package/package.json +38 -21
- package/src/bin/check_txe_oracle_version.ts +70 -0
- package/src/bin/index.ts +11 -2
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +11 -1
- package/src/dispatcher_pool.ts +317 -0
- package/src/index.ts +99 -190
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +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 +74 -12
- package/src/oracle/txe_oracle_registry.ts +536 -0
- package/src/oracle/txe_oracle_top_level_context.ts +429 -175
- 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 -995
- package/src/state_machine/archiver.ts +43 -20
- package/src/state_machine/dummy_p2p_client.ts +83 -32
- package/src/state_machine/global_variable_builder.ts +12 -11
- package/src/state_machine/index.ts +84 -33
- package/src/state_machine/mock_epoch_cache.ts +43 -3
- package/src/state_machine/synchronizer.ts +31 -10
- package/src/txe_session.ts +601 -114
- 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,9 @@ 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 { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
66
77
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
67
78
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
68
79
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -79,14 +90,14 @@ import {
|
|
|
79
90
|
collectNested,
|
|
80
91
|
} from '@aztec/stdlib/tx';
|
|
81
92
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
82
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
93
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
83
94
|
|
|
84
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
95
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
85
96
|
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
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';
|
|
90
101
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
91
102
|
|
|
92
103
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -97,69 +108,86 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
97
108
|
|
|
98
109
|
constructor(
|
|
99
110
|
private stateMachine: TXEStateMachine,
|
|
100
|
-
private contractStore:
|
|
111
|
+
private contractStore: ContractStore,
|
|
101
112
|
private noteStore: NoteStore,
|
|
102
113
|
private keyStore: KeyStore,
|
|
103
114
|
private addressStore: AddressStore,
|
|
104
115
|
private accountStore: TXEAccountStore,
|
|
105
116
|
private senderTaggingStore: SenderTaggingStore,
|
|
106
117
|
private recipientTaggingStore: RecipientTaggingStore,
|
|
107
|
-
private
|
|
118
|
+
private taggingSecretSourcesStore: TaggingSecretSourcesStore,
|
|
108
119
|
private capsuleStore: CapsuleStore,
|
|
120
|
+
private factStore: FactStore,
|
|
109
121
|
private privateEventStore: PrivateEventStore,
|
|
110
|
-
private jobId: string,
|
|
111
122
|
private nextBlockTimestamp: bigint,
|
|
112
123
|
private version: Fr,
|
|
113
124
|
private chainId: Fr,
|
|
114
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,
|
|
115
130
|
) {
|
|
116
131
|
this.logger = createLogger('txe:top_level_context');
|
|
117
132
|
this.logger.debug('Entering Top Level Context');
|
|
118
133
|
}
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
|
|
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.';
|
|
122
143
|
throw new Error(
|
|
123
|
-
`Incompatible
|
|
144
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
124
145
|
);
|
|
125
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;
|
|
126
153
|
}
|
|
127
154
|
|
|
128
155
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
129
156
|
// setup.
|
|
130
|
-
|
|
157
|
+
getRandomField(): Fr {
|
|
131
158
|
return Fr.random();
|
|
132
159
|
}
|
|
133
160
|
|
|
134
161
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
135
|
-
|
|
162
|
+
log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
136
163
|
if (!LogLevels[level]) {
|
|
137
|
-
throw new Error(`Invalid
|
|
164
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
138
165
|
}
|
|
139
166
|
const levelName = LogLevels[level];
|
|
140
167
|
|
|
141
168
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
169
|
+
return Promise.resolve();
|
|
142
170
|
}
|
|
143
171
|
|
|
144
|
-
|
|
172
|
+
getDefaultAddress(): AztecAddress {
|
|
145
173
|
return DEFAULT_ADDRESS;
|
|
146
174
|
}
|
|
147
175
|
|
|
148
|
-
async
|
|
176
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
149
177
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
150
178
|
}
|
|
151
179
|
|
|
152
|
-
|
|
180
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
153
181
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
154
182
|
}
|
|
155
183
|
|
|
156
|
-
async
|
|
157
|
-
return (await this.stateMachine.node.
|
|
184
|
+
async getLastBlockTimestamp() {
|
|
185
|
+
return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
|
|
158
186
|
}
|
|
159
187
|
|
|
160
|
-
async
|
|
188
|
+
async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
|
|
161
189
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
-
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
190
|
+
const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
|
|
163
191
|
|
|
164
192
|
if (block!.body.txEffects.length != 1) {
|
|
165
193
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,11 +196,40 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
196
|
|
|
169
197
|
const txEffects = block!.body.txEffects[0];
|
|
170
198
|
|
|
171
|
-
|
|
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
|
+
};
|
|
172
210
|
}
|
|
173
211
|
|
|
174
|
-
async
|
|
175
|
-
|
|
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
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
232
|
+
const events = (
|
|
176
233
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
177
234
|
contractAddress,
|
|
178
235
|
scopes: [scope],
|
|
@@ -180,9 +237,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
180
237
|
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
181
238
|
})
|
|
182
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;
|
|
183
249
|
}
|
|
184
250
|
|
|
185
|
-
async
|
|
251
|
+
async advanceBlocksBy(blocks: number) {
|
|
186
252
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
187
253
|
|
|
188
254
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -190,39 +256,76 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
190
256
|
}
|
|
191
257
|
}
|
|
192
258
|
|
|
193
|
-
|
|
259
|
+
advanceTimestampBy(duration: UInt64) {
|
|
194
260
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
195
261
|
this.nextBlockTimestamp += duration;
|
|
196
262
|
}
|
|
197
263
|
|
|
198
|
-
|
|
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
|
+
|
|
199
287
|
// Emit deployment nullifier
|
|
200
288
|
await this.mineBlock({
|
|
201
|
-
nullifiers: [
|
|
202
|
-
await siloNullifier(
|
|
203
|
-
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
204
|
-
instance.address.toField(),
|
|
205
|
-
),
|
|
206
|
-
],
|
|
289
|
+
nullifiers: [await this.deploymentNullifier(instance.address)],
|
|
207
290
|
});
|
|
208
291
|
|
|
209
292
|
if (!secret.equals(Fr.ZERO)) {
|
|
210
|
-
await this.
|
|
293
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
211
294
|
} else {
|
|
212
295
|
await this.contractStore.addContractInstance(instance);
|
|
213
|
-
await this.contractStore.addContractArtifact(
|
|
296
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
214
297
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
215
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
|
+
});
|
|
216
310
|
}
|
|
217
311
|
|
|
218
|
-
async
|
|
312
|
+
async addAccount(secret: Fr) {
|
|
313
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
314
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private async registerContractAndAddAccount(
|
|
318
|
+
artifact: ContractArtifact,
|
|
319
|
+
instance: ContractInstanceWithAddress,
|
|
320
|
+
secret: Fr,
|
|
321
|
+
) {
|
|
219
322
|
const partialAddress = await computePartialAddress(instance);
|
|
220
323
|
|
|
221
324
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
222
325
|
await this.contractStore.addContractInstance(instance);
|
|
223
|
-
await this.contractStore.addContractArtifact(
|
|
326
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
224
327
|
|
|
225
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
328
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
226
329
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
227
330
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
228
331
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -230,9 +333,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
230
333
|
return completeAddress;
|
|
231
334
|
}
|
|
232
335
|
|
|
233
|
-
async
|
|
336
|
+
async createAccount(secret: Fr) {
|
|
234
337
|
// This is a foot gun !
|
|
235
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
338
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
|
|
236
339
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
237
340
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
238
341
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -240,27 +343,52 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
240
343
|
return completeAddress;
|
|
241
344
|
}
|
|
242
345
|
|
|
243
|
-
async
|
|
346
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
244
347
|
const account = await this.accountStore.getAccount(address);
|
|
245
|
-
const
|
|
348
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
349
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
246
350
|
|
|
247
351
|
const schnorr = new Schnorr();
|
|
248
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
352
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
249
353
|
|
|
250
|
-
const authWitness = new AuthWitness(messageHash,
|
|
354
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
251
355
|
|
|
252
356
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
253
357
|
}
|
|
254
358
|
|
|
255
|
-
|
|
256
|
-
|
|
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();
|
|
257
385
|
|
|
258
386
|
const txEffect = TxEffect.empty();
|
|
259
387
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
260
388
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
261
389
|
|
|
262
390
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
263
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
391
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
264
392
|
|
|
265
393
|
const globals = makeGlobalVariables(undefined, {
|
|
266
394
|
blockNumber,
|
|
@@ -274,22 +402,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
274
402
|
|
|
275
403
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
276
404
|
|
|
277
|
-
await this.stateMachine.handleL2Block(block);
|
|
405
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
278
406
|
}
|
|
279
407
|
|
|
280
|
-
async
|
|
281
|
-
from: AztecAddress,
|
|
408
|
+
async privateCallNewFlow(
|
|
409
|
+
from: AztecAddress | undefined,
|
|
282
410
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
283
411
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
284
412
|
args: Fr[],
|
|
285
413
|
argsHash: Fr = Fr.zero(),
|
|
286
414
|
isStaticCall: boolean = false,
|
|
415
|
+
additionalScopes: AztecAddress[] = [],
|
|
416
|
+
jobId: string,
|
|
417
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
418
|
+
gasSettings: GasSettings,
|
|
287
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
|
+
|
|
288
427
|
this.logger.verbose(
|
|
289
|
-
`Executing external function ${await
|
|
428
|
+
`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
290
429
|
);
|
|
291
430
|
|
|
292
|
-
const artifact = await
|
|
431
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
293
432
|
if (!artifact) {
|
|
294
433
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
295
434
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -297,25 +436,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
297
436
|
throw new Error(message);
|
|
298
437
|
}
|
|
299
438
|
|
|
439
|
+
const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
|
|
440
|
+
|
|
300
441
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
301
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
302
|
-
await this.executeUtilityCall(call);
|
|
442
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
443
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
303
444
|
};
|
|
304
445
|
|
|
305
|
-
await
|
|
306
|
-
|
|
307
|
-
|
|
446
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
447
|
+
targetContractAddress,
|
|
448
|
+
functionSelector,
|
|
449
|
+
utilityExecutor,
|
|
450
|
+
blockHeader,
|
|
451
|
+
jobId,
|
|
452
|
+
scopes,
|
|
453
|
+
);
|
|
308
454
|
|
|
309
|
-
const
|
|
455
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
310
456
|
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
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);
|
|
314
459
|
|
|
315
460
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
316
461
|
|
|
317
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
318
|
-
|
|
319
462
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
320
463
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
321
464
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -327,42 +470,53 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
327
470
|
|
|
328
471
|
const simulator = new WASMSimulator();
|
|
329
472
|
|
|
330
|
-
const
|
|
473
|
+
const transientArrayService = new TransientArrayService();
|
|
474
|
+
const taggingSecretStrategy = this.taggingSecretStrategy;
|
|
475
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
331
476
|
argsHash,
|
|
332
477
|
txContext,
|
|
478
|
+
txRequestSalt: Fr.ZERO,
|
|
333
479
|
callContext,
|
|
334
|
-
|
|
335
|
-
blockHeader,
|
|
480
|
+
anchorBlockHeader: blockHeader,
|
|
336
481
|
utilityExecutor,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
[],
|
|
341
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
482
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
483
|
+
capsules: [],
|
|
484
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
342
485
|
noteCache,
|
|
343
486
|
taggingIndexCache,
|
|
344
|
-
|
|
345
|
-
this.noteStore,
|
|
346
|
-
this.keyStore,
|
|
347
|
-
this.addressStore,
|
|
348
|
-
this.stateMachine.node,
|
|
349
|
-
this.senderTaggingStore,
|
|
350
|
-
this.recipientTaggingStore,
|
|
351
|
-
this.
|
|
352
|
-
this.capsuleStore,
|
|
353
|
-
this.
|
|
354
|
-
this.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
from,
|
|
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
|
|
|
@@ -412,7 +566,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
412
566
|
globals.version = this.version;
|
|
413
567
|
globals.gasFees = GasFees.empty();
|
|
414
568
|
|
|
415
|
-
|
|
569
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
416
570
|
|
|
417
571
|
const bindings = this.logger.getBindings();
|
|
418
572
|
const contractsDB = new PublicContractsDB(
|
|
@@ -427,11 +581,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
427
581
|
collectStatistics: false,
|
|
428
582
|
collectCallMetadata: true,
|
|
429
583
|
});
|
|
584
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
585
|
+
const forkId = forkedWorldTrees.getRevision().forkId;
|
|
430
586
|
const processor = new PublicProcessor(
|
|
431
587
|
globals,
|
|
432
588
|
guardedMerkleTrees,
|
|
433
589
|
contractsDB,
|
|
434
|
-
new
|
|
590
|
+
new PublicTxSimulator(
|
|
591
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
592
|
+
globals,
|
|
593
|
+
contractsDB,
|
|
594
|
+
forkId,
|
|
595
|
+
config,
|
|
596
|
+
bindings,
|
|
597
|
+
),
|
|
435
598
|
new TestDateProvider(),
|
|
436
599
|
undefined,
|
|
437
600
|
createLogger('simulator:public-processor', bindings),
|
|
@@ -459,7 +622,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
459
622
|
} else if (!processedTx.revertCode.isOK()) {
|
|
460
623
|
if (processedTx.revertReason) {
|
|
461
624
|
try {
|
|
462
|
-
await enrichPublicSimulationError(
|
|
625
|
+
await enrichPublicSimulationError(
|
|
626
|
+
processedTx.revertReason,
|
|
627
|
+
this.contractStore,
|
|
628
|
+
this.stateMachine.contractClassService,
|
|
629
|
+
await this.stateMachine.anchorBlockStore.getBlockHeader(),
|
|
630
|
+
this.logger,
|
|
631
|
+
);
|
|
463
632
|
// eslint-disable-next-line no-empty
|
|
464
633
|
} catch {}
|
|
465
634
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -468,11 +637,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
468
637
|
}
|
|
469
638
|
}
|
|
470
639
|
|
|
640
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
641
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
642
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
643
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
644
|
+
const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
|
|
645
|
+
|
|
471
646
|
if (isStaticCall) {
|
|
472
647
|
await checkpoint!.revert();
|
|
473
|
-
|
|
474
|
-
await forkedWorldTrees.close();
|
|
475
|
-
return executionResult.returnValues ?? [];
|
|
648
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
476
649
|
}
|
|
477
650
|
|
|
478
651
|
const txEffect = TxEffect.empty();
|
|
@@ -492,33 +665,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
492
665
|
|
|
493
666
|
await this.stateMachine.handleL2Block(l2Block);
|
|
494
667
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
return executionResult.returnValues ?? [];
|
|
668
|
+
return { returnValues: executionResult.returnValues ?? [], offchainEffects };
|
|
498
669
|
}
|
|
499
670
|
|
|
500
|
-
async
|
|
501
|
-
from: AztecAddress,
|
|
671
|
+
async publicCallNewFlow(
|
|
672
|
+
from: AztecAddress | undefined,
|
|
502
673
|
targetContractAddress: AztecAddress,
|
|
503
674
|
calldata: Fr[],
|
|
504
675
|
isStaticCall: boolean,
|
|
676
|
+
gasSettings: GasSettings,
|
|
505
677
|
) {
|
|
506
|
-
this.
|
|
507
|
-
|
|
678
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
679
|
+
const anchoredContractData = new AnchoredContractData(
|
|
680
|
+
this.contractStore,
|
|
681
|
+
this.stateMachine.contractClassService,
|
|
682
|
+
anchorBlockHeader,
|
|
508
683
|
);
|
|
509
684
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
685
|
+
this.logger.verbose(
|
|
686
|
+
`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
687
|
+
);
|
|
515
688
|
|
|
516
|
-
const
|
|
689
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
517
690
|
|
|
518
691
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
519
692
|
|
|
520
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
521
|
-
|
|
522
693
|
const calldataHash = await computeCalldataHash(calldata);
|
|
523
694
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
524
695
|
|
|
@@ -529,7 +700,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
529
700
|
globals.version = this.version;
|
|
530
701
|
globals.gasFees = GasFees.empty();
|
|
531
702
|
|
|
532
|
-
|
|
703
|
+
await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
533
704
|
|
|
534
705
|
const bindings2 = this.logger.getBindings();
|
|
535
706
|
const contractsDB = new PublicContractsDB(
|
|
@@ -544,7 +715,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
544
715
|
collectStatistics: false,
|
|
545
716
|
collectCallMetadata: true,
|
|
546
717
|
});
|
|
547
|
-
|
|
718
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
719
|
+
const forkId2 = forkedWorldTrees.getRevision().forkId;
|
|
720
|
+
const simulator = new PublicTxSimulator(
|
|
721
|
+
this.stateMachine.synchronizer.avmSimulator,
|
|
722
|
+
globals,
|
|
723
|
+
contractsDB,
|
|
724
|
+
forkId2,
|
|
725
|
+
config,
|
|
726
|
+
bindings2,
|
|
727
|
+
);
|
|
548
728
|
const processor = new PublicProcessor(
|
|
549
729
|
globals,
|
|
550
730
|
guardedMerkleTrees,
|
|
@@ -566,7 +746,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
566
746
|
// may require producing reverts.
|
|
567
747
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
568
748
|
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
|
|
569
|
-
from,
|
|
749
|
+
from ?? AztecAddress.NULL_MSG_SENDER,
|
|
570
750
|
targetContractAddress,
|
|
571
751
|
isStaticCall,
|
|
572
752
|
calldataHash,
|
|
@@ -584,7 +764,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
584
764
|
constantData,
|
|
585
765
|
/*gasUsed=*/ new Gas(0, 0),
|
|
586
766
|
/*feePayer=*/ AztecAddress.zero(),
|
|
587
|
-
/*
|
|
767
|
+
/*expirationTimestamp=*/ 0n,
|
|
588
768
|
inputsForPublic,
|
|
589
769
|
undefined,
|
|
590
770
|
);
|
|
@@ -611,7 +791,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
611
791
|
} else if (!processedTx.revertCode.isOK()) {
|
|
612
792
|
if (processedTx.revertReason) {
|
|
613
793
|
try {
|
|
614
|
-
await enrichPublicSimulationError(
|
|
794
|
+
await enrichPublicSimulationError(
|
|
795
|
+
processedTx.revertReason,
|
|
796
|
+
this.contractStore,
|
|
797
|
+
this.stateMachine.contractClassService,
|
|
798
|
+
anchorBlockHeader,
|
|
799
|
+
this.logger,
|
|
800
|
+
);
|
|
615
801
|
// eslint-disable-next-line no-empty
|
|
616
802
|
} catch {}
|
|
617
803
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -624,9 +810,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
624
810
|
|
|
625
811
|
if (isStaticCall) {
|
|
626
812
|
await checkpoint!.revert();
|
|
627
|
-
|
|
628
|
-
await forkedWorldTrees.close();
|
|
629
|
-
|
|
630
813
|
return returnValues ?? [];
|
|
631
814
|
}
|
|
632
815
|
|
|
@@ -647,42 +830,80 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
647
830
|
|
|
648
831
|
await this.stateMachine.handleL2Block(l2Block);
|
|
649
832
|
|
|
650
|
-
await forkedWorldTrees.close();
|
|
651
|
-
|
|
652
833
|
return returnValues ?? [];
|
|
653
834
|
}
|
|
654
835
|
|
|
655
|
-
async
|
|
836
|
+
async executeUtilityFunction(
|
|
837
|
+
from: AztecAddress | undefined,
|
|
656
838
|
targetContractAddress: AztecAddress,
|
|
657
839
|
functionSelector: FunctionSelector,
|
|
658
840
|
args: Fr[],
|
|
841
|
+
jobId: string,
|
|
842
|
+
authorizedUtilityCallTargets: AztecAddress[],
|
|
659
843
|
) {
|
|
660
|
-
const
|
|
844
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
845
|
+
const anchoredContractData = new AnchoredContractData(
|
|
846
|
+
this.contractStore,
|
|
847
|
+
this.stateMachine.contractClassService,
|
|
848
|
+
blockHeader,
|
|
849
|
+
);
|
|
850
|
+
|
|
851
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
661
852
|
if (!artifact) {
|
|
662
853
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
663
854
|
}
|
|
664
855
|
|
|
665
856
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
666
|
-
await
|
|
667
|
-
await this.executeUtilityCall(call);
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
const call = new FunctionCall(
|
|
671
|
-
artifact.name,
|
|
857
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
672
858
|
targetContractAddress,
|
|
673
859
|
functionSelector,
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
860
|
+
async (call, execScopes) => {
|
|
861
|
+
await this.executeUtilityCall(call, { scopes: execScopes, jobId });
|
|
862
|
+
},
|
|
863
|
+
blockHeader,
|
|
864
|
+
jobId,
|
|
865
|
+
await this.keyStore.getAccounts(),
|
|
679
866
|
);
|
|
680
867
|
|
|
681
|
-
|
|
868
|
+
const call = FunctionCall.from({
|
|
869
|
+
name: artifact.name,
|
|
870
|
+
to: targetContractAddress,
|
|
871
|
+
selector: functionSelector,
|
|
872
|
+
type: FunctionType.UTILITY,
|
|
873
|
+
hideMsgSender: false,
|
|
874
|
+
isStatic: false,
|
|
875
|
+
args,
|
|
876
|
+
returnTypes: [],
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
return this.executeUtilityCall(call, {
|
|
880
|
+
from,
|
|
881
|
+
scopes: await this.keyStore.getAccounts(),
|
|
882
|
+
jobId,
|
|
883
|
+
authorizedUtilityCallTargets,
|
|
884
|
+
});
|
|
682
885
|
}
|
|
683
886
|
|
|
684
|
-
private async executeUtilityCall(
|
|
685
|
-
|
|
887
|
+
private async executeUtilityCall(
|
|
888
|
+
call: FunctionCall,
|
|
889
|
+
{
|
|
890
|
+
from = AztecAddress.NULL_MSG_SENDER,
|
|
891
|
+
scopes,
|
|
892
|
+
jobId,
|
|
893
|
+
authorizedUtilityCallTargets = [],
|
|
894
|
+
}: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
|
|
895
|
+
): Promise<Fr[]> {
|
|
896
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
897
|
+
const anchoredContractData = new AnchoredContractData(
|
|
898
|
+
this.contractStore,
|
|
899
|
+
this.stateMachine.contractClassService,
|
|
900
|
+
anchorBlockHeader,
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
904
|
+
if (!entryPointArtifact) {
|
|
905
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
906
|
+
}
|
|
686
907
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
687
908
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
688
909
|
}
|
|
@@ -693,25 +914,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
693
914
|
});
|
|
694
915
|
|
|
695
916
|
try {
|
|
696
|
-
const
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
917
|
+
const simulator = new WASMSimulator();
|
|
918
|
+
const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
|
|
919
|
+
await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
|
|
920
|
+
};
|
|
921
|
+
const oracle = new UtilityExecutionOracle({
|
|
922
|
+
callContext: CallContext.from({
|
|
923
|
+
msgSender: from,
|
|
924
|
+
contractAddress: call.to,
|
|
925
|
+
functionSelector: call.selector,
|
|
926
|
+
isStaticCall: true,
|
|
927
|
+
}),
|
|
928
|
+
authWitnesses: [],
|
|
929
|
+
capsules: [],
|
|
701
930
|
anchorBlockHeader,
|
|
702
|
-
|
|
703
|
-
this.noteStore,
|
|
704
|
-
this.keyStore,
|
|
705
|
-
this.addressStore,
|
|
706
|
-
this.stateMachine.node,
|
|
707
|
-
this.recipientTaggingStore,
|
|
708
|
-
this.
|
|
709
|
-
this.capsuleStore,
|
|
710
|
-
this.
|
|
711
|
-
this.
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
931
|
+
anchoredContractData,
|
|
932
|
+
noteStore: this.noteStore,
|
|
933
|
+
keyStore: this.keyStore,
|
|
934
|
+
addressStore: this.addressStore,
|
|
935
|
+
aztecNode: this.stateMachine.node,
|
|
936
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
937
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
938
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
939
|
+
factService: new FactService(this.factStore, scopes),
|
|
940
|
+
privateEventStore: this.privateEventStore,
|
|
941
|
+
txResolver: this.stateMachine.txResolver,
|
|
942
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
943
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
944
|
+
jobId,
|
|
945
|
+
scopes,
|
|
946
|
+
simulator,
|
|
947
|
+
hooks: composeHooks({
|
|
948
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
|
|
949
|
+
}),
|
|
950
|
+
utilityExecutor,
|
|
951
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
952
|
+
transientArrayService: new TransientArrayService(),
|
|
953
|
+
});
|
|
954
|
+
const acirExecutionResult = await simulator
|
|
955
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
|
|
715
956
|
.catch((err: Error) => {
|
|
716
957
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
717
958
|
throw new ExecutionError(
|
|
@@ -725,20 +966,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
725
966
|
);
|
|
726
967
|
});
|
|
727
968
|
|
|
728
|
-
this.logger.verbose(`Utility
|
|
969
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
729
970
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
730
971
|
} catch (err) {
|
|
731
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
972
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
732
973
|
}
|
|
733
974
|
}
|
|
734
975
|
|
|
735
|
-
close(): [bigint, Map<string, AuthWitness
|
|
976
|
+
close(): [bigint, Map<string, AuthWitness>, TaggingSecretStrategy | undefined] {
|
|
736
977
|
this.logger.debug('Exiting Top Level Context');
|
|
737
|
-
return [this.nextBlockTimestamp, this.authwits];
|
|
978
|
+
return [this.nextBlockTimestamp, this.authwits, this.taggingSecretStrategy];
|
|
738
979
|
}
|
|
739
980
|
|
|
740
981
|
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
741
|
-
const
|
|
742
|
-
return
|
|
982
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
983
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
private buildAuthorizeUtilityCallHook(
|
|
987
|
+
callerContext: 'private' | 'private view' | 'utility',
|
|
988
|
+
authorizedTargets: AztecAddress[],
|
|
989
|
+
): ExecutionHooks['authorizeUtilityCall'] | undefined {
|
|
990
|
+
if (authorizedTargets.length === 0) {
|
|
991
|
+
return undefined;
|
|
992
|
+
}
|
|
993
|
+
return req =>
|
|
994
|
+
Promise.resolve({
|
|
995
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
|
|
996
|
+
});
|
|
743
997
|
}
|
|
744
998
|
}
|