@aztec/txe 0.0.1-commit.2ed92850 → 0.0.1-commit.3100065
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/AuthRegistry-FSRZIMX6.js +3 -0
- package/dest/AuthRegistry-FSRZIMX6.js.map +7 -0
- package/dest/ContractClassRegistry-N6NA3SFA.js +3 -0
- package/dest/ContractClassRegistry-N6NA3SFA.js.map +7 -0
- package/dest/ContractInstanceRegistry-NADDSLGL.js +3 -0
- package/dest/ContractInstanceRegistry-NADDSLGL.js.map +7 -0
- package/dest/FeeJuice-QBH5JWJV.js +3 -0
- package/dest/FeeJuice-QBH5JWJV.js.map +7 -0
- package/dest/HandshakeRegistry-KKUEU7XW.js +3 -0
- package/dest/HandshakeRegistry-KKUEU7XW.js.map +7 -0
- package/dest/MultiCallEntrypoint-TGICA67H.js +3 -0
- package/dest/MultiCallEntrypoint-TGICA67H.js.map +7 -0
- package/dest/SchnorrAccount-J5T6OKR3.js +3 -0
- package/dest/SchnorrAccount-J5T6OKR3.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js +3 -0
- package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js.map +7 -0
- package/dest/bin/check_txe_oracle_version.d.ts +2 -0
- package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
- package/dest/bin/check_txe_oracle_version.js +61 -0
- package/dest/bin/index.js +3 -30
- package/dest/bin/index.js.map +7 -0
- package/dest/bin/oracle_test_server.d.ts +3 -0
- package/dest/bin/oracle_test_server.d.ts.map +1 -0
- package/dest/bin/oracle_test_server.js +41 -0
- package/dest/chunk-BJVAAXNA.js +3 -0
- package/dest/chunk-BJVAAXNA.js.map +7 -0
- package/dest/chunk-PDOEF22H.js +304 -0
- package/dest/chunk-PDOEF22H.js.map +7 -0
- package/dest/chunk-YP4ODNMQ.js +268 -0
- package/dest/chunk-YP4ODNMQ.js.map +7 -0
- package/dest/constants.d.ts +5 -1
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +9 -1
- package/dest/dispatcher_pool.d.ts +67 -0
- package/dest/dispatcher_pool.d.ts.map +1 -0
- package/dest/dispatcher_pool.js +286 -0
- package/dest/index.d.ts +51 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +73 -157
- package/dest/metafile.json +39883 -0
- package/dest/msgpackr_fr_extension.d.ts +2 -0
- package/dest/msgpackr_fr_extension.d.ts.map +1 -0
- package/dest/msgpackr_fr_extension.js +21 -0
- package/dest/oracle/interfaces.d.ts +65 -30
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
- package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
- package/dest/oracle/tagging_secret_strategy.js +12 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/default_fixtures.js +207 -0
- package/dest/oracle/test-resolver/index.d.ts +9 -0
- package/dest/oracle/test-resolver/index.d.ts.map +1 -0
- package/dest/oracle/test-resolver/index.js +32 -0
- package/dest/oracle/test-resolver/resolver.d.ts +48 -0
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
- package/dest/oracle/test-resolver/resolver.js +181 -0
- package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +63 -16
- package/dest/oracle/txe_oracle_registry.d.ts +170 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +749 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +56 -29
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +330 -103
- package/dest/oracle/txe_oracle_version.d.ts +17 -0
- package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_version.js +14 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
- package/dest/oracle/txe_private_execution_oracle.js +15 -0
- package/dest/rpc_server.d.ts +14 -0
- package/dest/rpc_server.d.ts.map +1 -0
- package/dest/rpc_server.js +78 -0
- package/dest/rpc_translator.d.ts +113 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +885 -613
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +30 -20
- package/dest/state_machine/dummy_p2p_client.d.ts +29 -16
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +53 -20
- package/dest/state_machine/global_variable_builder.d.ts +10 -6
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +8 -5
- package/dest/state_machine/index.d.ts +13 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +60 -15
- package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +33 -2
- package/dest/state_machine/synchronizer.d.ts +9 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +10 -6
- package/dest/txe_session.d.ts +89 -16
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +363 -56
- package/dest/utils/block_creation.d.ts +2 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +5 -3
- package/dest/utils/encoding.d.ts +192 -0
- package/dest/utils/encoding.d.ts.map +1 -0
- package/dest/{util → utils}/encoding.js +7 -2
- package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
- package/dest/utils/expected_failure_error.d.ts.map +1 -0
- package/dest/utils/tx_effect_creation.d.ts +1 -1
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +0 -1
- package/dest/{util → utils}/txe_account_store.d.ts +1 -1
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.d.ts +37 -0
- package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.js +161 -0
- package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/utils/txe_public_contract_data_source.js +51 -0
- package/dest/worker.bundle.js +3 -0
- package/dest/worker.bundle.js.map +7 -0
- package/dest/worker.d.ts +2 -0
- package/dest/worker.d.ts.map +1 -0
- package/dest/worker.js +92 -0
- package/package.json +38 -21
- package/src/bin/check_txe_oracle_version.ts +70 -0
- package/src/bin/index.ts +11 -2
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +11 -1
- package/src/dispatcher_pool.ts +317 -0
- package/src/index.ts +99 -190
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +71 -35
- package/src/oracle/tagging_secret_strategy.ts +25 -0
- package/src/oracle/test-resolver/default_fixtures.ts +282 -0
- package/src/oracle/test-resolver/index.ts +44 -0
- package/src/oracle/test-resolver/resolver.ts +245 -0
- package/src/oracle/txe_oracle_public_context.ts +76 -16
- package/src/oracle/txe_oracle_registry.ts +539 -0
- package/src/oracle/txe_oracle_top_level_context.ts +440 -168
- package/src/oracle/txe_oracle_version.ts +17 -0
- package/src/oracle/txe_private_execution_oracle.ts +30 -0
- package/src/rpc_server.ts +87 -0
- package/src/rpc_translator.ts +1098 -988
- package/src/state_machine/archiver.ts +43 -20
- package/src/state_machine/dummy_p2p_client.ts +83 -32
- package/src/state_machine/global_variable_builder.ts +12 -11
- package/src/state_machine/index.ts +84 -33
- package/src/state_machine/mock_epoch_cache.ts +43 -3
- package/src/state_machine/synchronizer.ts +13 -7
- package/src/txe_session.ts +603 -128
- package/src/utils/block_creation.ts +5 -2
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/tx_effect_creation.ts +0 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/utils/txe_public_contract_data_source.ts +60 -0
- package/src/worker.ts +98 -0
- package/dest/util/encoding.d.ts +0 -720
- package/dest/util/encoding.d.ts.map +0 -1
- package/dest/util/expected_failure_error.d.ts.map +0 -1
- package/dest/util/txe_account_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.d.ts +0 -12
- package/dest/util/txe_contract_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.js +0 -22
- package/dest/util/txe_public_contract_data_source.d.ts +0 -21
- package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
- package/dest/util/txe_public_contract_data_source.js +0 -67
- package/src/util/txe_contract_store.ts +0 -36
- package/src/util/txe_public_contract_data_source.ts +0 -86
- /package/dest/{util → utils}/expected_failure_error.js +0 -0
- /package/dest/{util → utils}/txe_account_store.js +0 -0
- /package/src/{util → utils}/expected_failure_error.ts +0 -0
- /package/src/{util → utils}/txe_account_store.ts +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
|
|
1
|
+
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
7
|
-
import {
|
|
8
|
-
import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache,
|
|
7
|
+
import { AnchoredContractData, CapsuleService, FactService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
|
|
8
|
+
import { CONTRACT_INSTANCE, ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, PrivateExecutionOracle, TransientArrayService, UtilityExecutionOracle, buildACIRCallback, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
|
|
9
9
|
import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
|
|
10
10
|
import { CppPublicTxSimulator, GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor } from '@aztec/simulator/server';
|
|
11
11
|
import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
@@ -13,17 +13,21 @@ import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
|
13
13
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
14
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
15
|
import { computePartialAddress } from '@aztec/stdlib/contract';
|
|
16
|
-
import { Gas, GasFees
|
|
16
|
+
import { Gas, GasFees } from '@aztec/stdlib/gas';
|
|
17
17
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
18
18
|
import { PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, PrivateToPublicAccumulatedData, PublicCallRequest } from '@aztec/stdlib/kernel';
|
|
19
|
+
import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
|
|
20
|
+
import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
|
|
21
|
+
import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
19
22
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
20
23
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
21
24
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
22
25
|
import { CallContext, HashedValues, PrivateExecutionResult, Tx, TxConstantData, TxContext, TxEffect, TxHash, collectNested } from '@aztec/stdlib/tx';
|
|
23
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
24
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
25
|
-
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
26
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
27
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
26
28
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
29
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
30
|
+
import { makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
|
|
27
31
|
export class TXEOracleTopLevelContext {
|
|
28
32
|
stateMachine;
|
|
29
33
|
contractStore;
|
|
@@ -33,18 +37,22 @@ export class TXEOracleTopLevelContext {
|
|
|
33
37
|
accountStore;
|
|
34
38
|
senderTaggingStore;
|
|
35
39
|
recipientTaggingStore;
|
|
36
|
-
|
|
40
|
+
taggingSecretSourcesStore;
|
|
37
41
|
capsuleStore;
|
|
42
|
+
factStore;
|
|
38
43
|
privateEventStore;
|
|
39
|
-
jobId;
|
|
40
44
|
nextBlockTimestamp;
|
|
41
45
|
version;
|
|
42
46
|
chainId;
|
|
43
47
|
authwits;
|
|
48
|
+
taggingSecretStrategies;
|
|
49
|
+
artifactResolver;
|
|
50
|
+
rootPath;
|
|
51
|
+
packageName;
|
|
44
52
|
isMisc;
|
|
45
53
|
isTxe;
|
|
46
54
|
logger;
|
|
47
|
-
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore,
|
|
55
|
+
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, artifactResolver, rootPath, packageName){
|
|
48
56
|
this.stateMachine = stateMachine;
|
|
49
57
|
this.contractStore = contractStore;
|
|
50
58
|
this.noteStore = noteStore;
|
|
@@ -53,67 +61,104 @@ export class TXEOracleTopLevelContext {
|
|
|
53
61
|
this.accountStore = accountStore;
|
|
54
62
|
this.senderTaggingStore = senderTaggingStore;
|
|
55
63
|
this.recipientTaggingStore = recipientTaggingStore;
|
|
56
|
-
this.
|
|
64
|
+
this.taggingSecretSourcesStore = taggingSecretSourcesStore;
|
|
57
65
|
this.capsuleStore = capsuleStore;
|
|
66
|
+
this.factStore = factStore;
|
|
58
67
|
this.privateEventStore = privateEventStore;
|
|
59
|
-
this.jobId = jobId;
|
|
60
68
|
this.nextBlockTimestamp = nextBlockTimestamp;
|
|
61
69
|
this.version = version;
|
|
62
70
|
this.chainId = chainId;
|
|
63
71
|
this.authwits = authwits;
|
|
72
|
+
this.taggingSecretStrategies = taggingSecretStrategies;
|
|
73
|
+
this.artifactResolver = artifactResolver;
|
|
74
|
+
this.rootPath = rootPath;
|
|
75
|
+
this.packageName = packageName;
|
|
64
76
|
this.isMisc = true;
|
|
65
77
|
this.isTxe = true;
|
|
66
78
|
this.logger = createLogger('txe:top_level_context');
|
|
67
79
|
this.logger.debug('Entering Top Level Context');
|
|
68
80
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
contractOracleVersion;
|
|
82
|
+
assertCompatibleOracleVersion(major, minor) {
|
|
83
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
84
|
+
const hint = major > ORACLE_VERSION_MAJOR ? '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.' : '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.';
|
|
85
|
+
throw new Error(`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`);
|
|
72
86
|
}
|
|
87
|
+
this.contractOracleVersion = {
|
|
88
|
+
major,
|
|
89
|
+
minor
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
93
|
+
nonOracleFunctionGetContractOracleVersion() {
|
|
94
|
+
return this.contractOracleVersion;
|
|
73
95
|
}
|
|
74
96
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
75
97
|
// setup.
|
|
76
|
-
|
|
98
|
+
getRandomField() {
|
|
77
99
|
return Fr.random();
|
|
78
100
|
}
|
|
79
101
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
80
|
-
|
|
102
|
+
log(level, message, _fieldsSize, fields) {
|
|
81
103
|
if (!LogLevels[level]) {
|
|
82
|
-
throw new Error(`Invalid
|
|
104
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
83
105
|
}
|
|
84
106
|
const levelName = LogLevels[level];
|
|
85
107
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, {
|
|
86
108
|
module: `${this.logger.module}:debug_log`
|
|
87
109
|
});
|
|
110
|
+
return Promise.resolve();
|
|
88
111
|
}
|
|
89
|
-
|
|
112
|
+
getDefaultAddress() {
|
|
90
113
|
return DEFAULT_ADDRESS;
|
|
91
114
|
}
|
|
92
|
-
async
|
|
115
|
+
async getNextBlockNumber() {
|
|
93
116
|
return BlockNumber(await this.getLastBlockNumber() + 1);
|
|
94
117
|
}
|
|
95
|
-
|
|
118
|
+
getNextBlockTimestamp() {
|
|
96
119
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
97
120
|
}
|
|
98
|
-
async
|
|
99
|
-
return (await this.stateMachine.node.
|
|
121
|
+
async getLastBlockTimestamp() {
|
|
122
|
+
return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
|
|
100
123
|
}
|
|
101
|
-
async
|
|
124
|
+
async getLastTxEffects() {
|
|
102
125
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
103
|
-
const block = await this.stateMachine.archiver.getBlock(
|
|
126
|
+
const block = await this.stateMachine.archiver.getBlock({
|
|
127
|
+
number: latestBlockNumber
|
|
128
|
+
});
|
|
104
129
|
if (block.body.txEffects.length != 1) {
|
|
105
130
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
106
131
|
throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
|
|
107
132
|
}
|
|
108
133
|
const txEffects = block.body.txEffects[0];
|
|
134
|
+
const privateLogs = txEffects.privateLogs;
|
|
135
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
136
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
137
|
+
}
|
|
109
138
|
return {
|
|
110
139
|
txHash: txEffects.txHash,
|
|
111
140
|
noteHashes: txEffects.noteHashes,
|
|
112
|
-
nullifiers: txEffects.nullifiers
|
|
141
|
+
nullifiers: txEffects.nullifiers,
|
|
142
|
+
privateLogs
|
|
113
143
|
};
|
|
114
144
|
}
|
|
115
|
-
async
|
|
116
|
-
|
|
145
|
+
async syncContractNonOracleMethod(contractAddress, scope, jobId) {
|
|
146
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
147
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
151
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
|
|
152
|
+
await this.executeUtilityCall(call, {
|
|
153
|
+
scopes: execScopes,
|
|
154
|
+
jobId
|
|
155
|
+
});
|
|
156
|
+
}, blockHeader, jobId, [
|
|
157
|
+
scope
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
async getPrivateEvents(selector, contractAddress, scope) {
|
|
161
|
+
const events = (await this.privateEventStore.getPrivateEvents(selector, {
|
|
117
162
|
contractAddress,
|
|
118
163
|
scopes: [
|
|
119
164
|
scope
|
|
@@ -121,63 +166,117 @@ export class TXEOracleTopLevelContext {
|
|
|
121
166
|
fromBlock: 0,
|
|
122
167
|
toBlock: await this.getLastBlockNumber() + 1
|
|
123
168
|
})).map((e)=>e.packedEvent);
|
|
169
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
170
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
171
|
+
}
|
|
172
|
+
if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
173
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
174
|
+
}
|
|
175
|
+
return events;
|
|
124
176
|
}
|
|
125
|
-
async
|
|
177
|
+
async advanceBlocksBy(blocks) {
|
|
126
178
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
127
179
|
for(let i = 0; i < blocks; i++){
|
|
128
180
|
await this.mineBlock();
|
|
129
181
|
}
|
|
130
182
|
}
|
|
131
|
-
|
|
183
|
+
advanceTimestampBy(duration) {
|
|
132
184
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
133
185
|
this.nextBlockTimestamp += duration;
|
|
134
186
|
}
|
|
135
|
-
|
|
187
|
+
deploymentNullifier(address) {
|
|
188
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
189
|
+
}
|
|
190
|
+
async deploy(contractPath, initializer, args, secret, salt, deployer) {
|
|
191
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
192
|
+
rootPath: this.rootPath,
|
|
193
|
+
packageName: this.packageName,
|
|
194
|
+
contractPath,
|
|
195
|
+
initializer,
|
|
196
|
+
args,
|
|
197
|
+
secret,
|
|
198
|
+
salt,
|
|
199
|
+
deployer
|
|
200
|
+
});
|
|
136
201
|
// Emit deployment nullifier
|
|
137
202
|
await this.mineBlock({
|
|
138
203
|
nullifiers: [
|
|
139
|
-
await
|
|
204
|
+
await this.deploymentNullifier(instance.address)
|
|
140
205
|
]
|
|
141
206
|
});
|
|
142
207
|
if (!secret.equals(Fr.ZERO)) {
|
|
143
|
-
await this.
|
|
208
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
144
209
|
} else {
|
|
145
210
|
await this.contractStore.addContractInstance(instance);
|
|
146
|
-
await this.contractStore.addContractArtifact(
|
|
211
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
147
212
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
148
213
|
}
|
|
214
|
+
return CONTRACT_INSTANCE.serialization.fn(instance).flat();
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
218
|
+
*/ async mineDeploymentNullifiers(addresses) {
|
|
219
|
+
await this.mineBlock({
|
|
220
|
+
nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async addAccount(secret) {
|
|
224
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
225
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
149
226
|
}
|
|
150
|
-
async
|
|
227
|
+
async registerContractAndAddAccount(artifact, instance, secret) {
|
|
151
228
|
const partialAddress = await computePartialAddress(instance);
|
|
152
229
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
153
230
|
await this.contractStore.addContractInstance(instance);
|
|
154
|
-
await this.contractStore.addContractArtifact(
|
|
155
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
231
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
232
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
156
233
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
157
234
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
158
235
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
159
236
|
return completeAddress;
|
|
160
237
|
}
|
|
161
|
-
async
|
|
238
|
+
async createAccount(secret) {
|
|
162
239
|
// This is a foot gun !
|
|
163
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
240
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
|
|
164
241
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
165
242
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
166
243
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
167
244
|
return completeAddress;
|
|
168
245
|
}
|
|
169
|
-
async
|
|
246
|
+
async addAuthWitness(address, messageHash) {
|
|
170
247
|
const account = await this.accountStore.getAccount(address);
|
|
171
|
-
const
|
|
248
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
249
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
172
250
|
const schnorr = new Schnorr();
|
|
173
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
174
|
-
const authWitness = new AuthWitness(messageHash,
|
|
175
|
-
...signature.toBuffer()
|
|
176
|
-
]);
|
|
251
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
252
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
177
253
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
178
254
|
}
|
|
255
|
+
setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
|
|
256
|
+
const apply = (mode, strategy)=>{
|
|
257
|
+
if (strategy.isSome()) {
|
|
258
|
+
this.taggingSecretStrategies.set(mode, strategy.value);
|
|
259
|
+
} else {
|
|
260
|
+
this.taggingSecretStrategies.delete(mode);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
|
|
264
|
+
apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
|
|
265
|
+
}
|
|
266
|
+
async sendL1ToL2Message(content, secretHash, sender, recipient) {
|
|
267
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
268
|
+
const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
269
|
+
const leafIndex = new Fr(size);
|
|
270
|
+
const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
|
|
271
|
+
await this.mineBlock({
|
|
272
|
+
l1ToL2Messages: [
|
|
273
|
+
message.hash()
|
|
274
|
+
]
|
|
275
|
+
});
|
|
276
|
+
return leafIndex;
|
|
277
|
+
}
|
|
179
278
|
async mineBlock(options = {}) {
|
|
180
|
-
const blockNumber = await this.
|
|
279
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
181
280
|
const txEffect = TxEffect.empty();
|
|
182
281
|
txEffect.nullifiers = [
|
|
183
282
|
getSingleTxBlockRequestHash(blockNumber),
|
|
@@ -185,7 +284,7 @@ export class TXEOracleTopLevelContext {
|
|
|
185
284
|
];
|
|
186
285
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
187
286
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
188
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
287
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
189
288
|
const globals = makeGlobalVariables(undefined, {
|
|
190
289
|
blockNumber,
|
|
191
290
|
timestamp: this.nextBlockTimestamp,
|
|
@@ -197,27 +296,33 @@ export class TXEOracleTopLevelContext {
|
|
|
197
296
|
]);
|
|
198
297
|
await forkedWorldTrees.close();
|
|
199
298
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
200
|
-
await this.stateMachine.handleL2Block(block);
|
|
299
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
201
300
|
}
|
|
202
|
-
async
|
|
203
|
-
|
|
204
|
-
const
|
|
301
|
+
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
302
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
303
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
304
|
+
this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
305
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
205
306
|
if (!artifact) {
|
|
206
307
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)')) ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.' : 'Function Artifact does not exist';
|
|
207
308
|
throw new Error(message);
|
|
208
309
|
}
|
|
310
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
311
|
+
from,
|
|
312
|
+
...additionalScopes
|
|
313
|
+
];
|
|
209
314
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
210
|
-
const utilityExecutor = async (call)=>{
|
|
211
|
-
await this.executeUtilityCall(call
|
|
315
|
+
const utilityExecutor = async (call, execScopes)=>{
|
|
316
|
+
await this.executeUtilityCall(call, {
|
|
317
|
+
scopes: execScopes,
|
|
318
|
+
jobId
|
|
319
|
+
});
|
|
212
320
|
};
|
|
213
|
-
await
|
|
214
|
-
const blockNumber = await this.
|
|
215
|
-
const
|
|
216
|
-
const
|
|
217
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
218
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
321
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
322
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
323
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
324
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
219
325
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
220
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
221
326
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
222
327
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
223
328
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -227,12 +332,50 @@ export class TXEOracleTopLevelContext {
|
|
|
227
332
|
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
228
333
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
229
334
|
const simulator = new WASMSimulator();
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
335
|
+
const transientArrayService = new TransientArrayService();
|
|
336
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
337
|
+
argsHash,
|
|
338
|
+
txContext,
|
|
339
|
+
// The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
|
|
340
|
+
txRequestSalt: Fr.ZERO,
|
|
341
|
+
callContext,
|
|
342
|
+
anchorBlockHeader: blockHeader,
|
|
343
|
+
utilityExecutor,
|
|
344
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
345
|
+
capsules: [],
|
|
346
|
+
executionCache: HashedValuesCache.create([
|
|
347
|
+
new HashedValues(args, argsHash)
|
|
348
|
+
]),
|
|
349
|
+
noteCache,
|
|
350
|
+
taggingIndexCache,
|
|
351
|
+
anchoredContractData,
|
|
352
|
+
noteStore: this.noteStore,
|
|
353
|
+
keyStore: this.keyStore,
|
|
354
|
+
addressStore: this.addressStore,
|
|
355
|
+
aztecNode: this.stateMachine.node,
|
|
356
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
357
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
358
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
359
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
360
|
+
factService: new FactService(this.factStore, scopes),
|
|
361
|
+
privateEventStore: this.privateEventStore,
|
|
362
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
363
|
+
jobId,
|
|
364
|
+
totalPublicCalldataCount: 0,
|
|
365
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
366
|
+
scopes,
|
|
367
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
368
|
+
// contract would perform, including setting senderForTags.
|
|
369
|
+
senderForTags: from,
|
|
370
|
+
simulator,
|
|
371
|
+
txResolver: this.stateMachine.txResolver,
|
|
372
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
373
|
+
hooks: composeHooks({
|
|
374
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
|
|
375
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
|
|
376
|
+
}),
|
|
377
|
+
transientArrayService
|
|
378
|
+
});
|
|
236
379
|
// 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.
|
|
237
380
|
let result;
|
|
238
381
|
let executionResult;
|
|
@@ -244,10 +387,9 @@ export class TXEOracleTopLevelContext {
|
|
|
244
387
|
r.publicInputs.publicTeardownCallRequest
|
|
245
388
|
]));
|
|
246
389
|
const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
|
|
247
|
-
const calldata = await privateExecutionOracle.
|
|
390
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
248
391
|
return new HashedValues(calldata, r.calldataHash);
|
|
249
392
|
}));
|
|
250
|
-
noteCache.finish();
|
|
251
393
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
252
394
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
253
395
|
} catch (err) {
|
|
@@ -256,7 +398,7 @@ export class TXEOracleTopLevelContext {
|
|
|
256
398
|
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
257
399
|
// the nonce generator for the note hashes.
|
|
258
400
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
259
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, this.
|
|
401
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
260
402
|
const globals = makeGlobalVariables();
|
|
261
403
|
globals.blockNumber = blockNumber;
|
|
262
404
|
globals.timestamp = this.nextBlockTimestamp;
|
|
@@ -264,7 +406,8 @@ export class TXEOracleTopLevelContext {
|
|
|
264
406
|
globals.version = this.version;
|
|
265
407
|
globals.gasFees = GasFees.empty();
|
|
266
408
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
267
|
-
const
|
|
409
|
+
const bindings = this.logger.getBindings();
|
|
410
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
|
|
268
411
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
269
412
|
const config = PublicSimulatorConfig.from({
|
|
270
413
|
skipFeeEnforcement: true,
|
|
@@ -273,7 +416,7 @@ export class TXEOracleTopLevelContext {
|
|
|
273
416
|
collectStatistics: false,
|
|
274
417
|
collectCallMetadata: true
|
|
275
418
|
});
|
|
276
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config), new TestDateProvider());
|
|
419
|
+
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
|
|
277
420
|
const tx = await Tx.create({
|
|
278
421
|
data: publicInputs,
|
|
279
422
|
chonkProof: ChonkProof.empty(),
|
|
@@ -294,7 +437,7 @@ export class TXEOracleTopLevelContext {
|
|
|
294
437
|
} else if (!processedTx.revertCode.isOK()) {
|
|
295
438
|
if (processedTx.revertReason) {
|
|
296
439
|
try {
|
|
297
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
440
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
|
|
298
441
|
// eslint-disable-next-line no-empty
|
|
299
442
|
} catch {}
|
|
300
443
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -302,10 +445,20 @@ export class TXEOracleTopLevelContext {
|
|
|
302
445
|
throw new Error('Contract execution has reverted');
|
|
303
446
|
}
|
|
304
447
|
}
|
|
448
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
449
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
450
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
451
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
452
|
+
const offchainEffects = collectNested([
|
|
453
|
+
executionResult
|
|
454
|
+
], (r)=>r.offchainEffects.map((e)=>e.data));
|
|
305
455
|
if (isStaticCall) {
|
|
306
456
|
await checkpoint.revert();
|
|
307
457
|
await forkedWorldTrees.close();
|
|
308
|
-
return
|
|
458
|
+
return {
|
|
459
|
+
returnValues: executionResult.returnValues ?? [],
|
|
460
|
+
offchainEffects
|
|
461
|
+
};
|
|
309
462
|
}
|
|
310
463
|
const txEffect = TxEffect.empty();
|
|
311
464
|
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
@@ -321,16 +474,17 @@ export class TXEOracleTopLevelContext {
|
|
|
321
474
|
]);
|
|
322
475
|
await this.stateMachine.handleL2Block(l2Block);
|
|
323
476
|
await forkedWorldTrees.close();
|
|
324
|
-
return
|
|
477
|
+
return {
|
|
478
|
+
returnValues: executionResult.returnValues ?? [],
|
|
479
|
+
offchainEffects
|
|
480
|
+
};
|
|
325
481
|
}
|
|
326
|
-
async
|
|
327
|
-
this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
328
|
-
const blockNumber = await this.txeGetNextBlockNumber();
|
|
329
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
330
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
331
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
332
|
-
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
482
|
+
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
333
483
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
484
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
485
|
+
this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
486
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
487
|
+
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
334
488
|
const calldataHash = await computeCalldataHash(calldata);
|
|
335
489
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
336
490
|
const globals = makeGlobalVariables();
|
|
@@ -340,7 +494,8 @@ export class TXEOracleTopLevelContext {
|
|
|
340
494
|
globals.version = this.version;
|
|
341
495
|
globals.gasFees = GasFees.empty();
|
|
342
496
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
343
|
-
const
|
|
497
|
+
const bindings2 = this.logger.getBindings();
|
|
498
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
|
|
344
499
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
345
500
|
const config = PublicSimulatorConfig.from({
|
|
346
501
|
skipFeeEnforcement: true,
|
|
@@ -349,8 +504,8 @@ export class TXEOracleTopLevelContext {
|
|
|
349
504
|
collectStatistics: false,
|
|
350
505
|
collectCallMetadata: true
|
|
351
506
|
});
|
|
352
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
353
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
|
|
507
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
508
|
+
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
|
|
354
509
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
355
510
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
356
511
|
// side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
|
|
@@ -360,10 +515,10 @@ export class TXEOracleTopLevelContext {
|
|
|
360
515
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
361
516
|
// may require producing reverts.
|
|
362
517
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
363
|
-
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
|
|
518
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
364
519
|
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
365
520
|
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
366
|
-
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*
|
|
521
|
+
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
367
522
|
const tx = await Tx.create({
|
|
368
523
|
data: txData,
|
|
369
524
|
chonkProof: ChonkProof.empty(),
|
|
@@ -386,7 +541,7 @@ export class TXEOracleTopLevelContext {
|
|
|
386
541
|
} else if (!processedTx.revertCode.isOK()) {
|
|
387
542
|
if (processedTx.revertReason) {
|
|
388
543
|
try {
|
|
389
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
544
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
390
545
|
// eslint-disable-next-line no-empty
|
|
391
546
|
} catch {}
|
|
392
547
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -416,20 +571,44 @@ export class TXEOracleTopLevelContext {
|
|
|
416
571
|
await forkedWorldTrees.close();
|
|
417
572
|
return returnValues ?? [];
|
|
418
573
|
}
|
|
419
|
-
async
|
|
420
|
-
const
|
|
574
|
+
async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
575
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
576
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
577
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
421
578
|
if (!artifact) {
|
|
422
579
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
423
580
|
}
|
|
424
581
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
425
|
-
await
|
|
426
|
-
await this.executeUtilityCall(call
|
|
582
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
|
|
583
|
+
await this.executeUtilityCall(call, {
|
|
584
|
+
scopes: execScopes,
|
|
585
|
+
jobId
|
|
586
|
+
});
|
|
587
|
+
}, blockHeader, jobId, await this.keyStore.getAccounts());
|
|
588
|
+
const call = FunctionCall.from({
|
|
589
|
+
name: artifact.name,
|
|
590
|
+
to: targetContractAddress,
|
|
591
|
+
selector: functionSelector,
|
|
592
|
+
type: FunctionType.UTILITY,
|
|
593
|
+
hideMsgSender: false,
|
|
594
|
+
isStatic: false,
|
|
595
|
+
args,
|
|
596
|
+
returnTypes: []
|
|
597
|
+
});
|
|
598
|
+
return this.executeUtilityCall(call, {
|
|
599
|
+
from,
|
|
600
|
+
scopes: await this.keyStore.getAccounts(),
|
|
601
|
+
jobId,
|
|
602
|
+
authorizedUtilityCallTargets
|
|
427
603
|
});
|
|
428
|
-
const call = new FunctionCall(artifact.name, targetContractAddress, functionSelector, FunctionType.UTILITY, false, false, args, []);
|
|
429
|
-
return this.executeUtilityCall(call);
|
|
430
604
|
}
|
|
431
|
-
async executeUtilityCall(call) {
|
|
432
|
-
const
|
|
605
|
+
async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
|
|
606
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
607
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
608
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
609
|
+
if (!entryPointArtifact) {
|
|
610
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
611
|
+
}
|
|
433
612
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
434
613
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
435
614
|
}
|
|
@@ -438,9 +617,48 @@ export class TXEOracleTopLevelContext {
|
|
|
438
617
|
selector: call.selector
|
|
439
618
|
});
|
|
440
619
|
try {
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
|
|
620
|
+
const simulator = new WASMSimulator();
|
|
621
|
+
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
622
|
+
await this.executeUtilityCall(syncCall, {
|
|
623
|
+
scopes: execScopes,
|
|
624
|
+
jobId,
|
|
625
|
+
authorizedUtilityCallTargets
|
|
626
|
+
});
|
|
627
|
+
};
|
|
628
|
+
const oracle = new UtilityExecutionOracle({
|
|
629
|
+
callContext: CallContext.from({
|
|
630
|
+
msgSender: from,
|
|
631
|
+
contractAddress: call.to,
|
|
632
|
+
functionSelector: call.selector,
|
|
633
|
+
isStaticCall: true
|
|
634
|
+
}),
|
|
635
|
+
authWitnesses: [],
|
|
636
|
+
capsules: [],
|
|
637
|
+
anchorBlockHeader,
|
|
638
|
+
anchoredContractData,
|
|
639
|
+
noteStore: this.noteStore,
|
|
640
|
+
keyStore: this.keyStore,
|
|
641
|
+
addressStore: this.addressStore,
|
|
642
|
+
aztecNode: this.stateMachine.node,
|
|
643
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
644
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
645
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
646
|
+
factService: new FactService(this.factStore, scopes),
|
|
647
|
+
privateEventStore: this.privateEventStore,
|
|
648
|
+
txResolver: this.stateMachine.txResolver,
|
|
649
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
650
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
651
|
+
jobId,
|
|
652
|
+
scopes,
|
|
653
|
+
simulator,
|
|
654
|
+
utilityExecutor,
|
|
655
|
+
hooks: composeHooks({
|
|
656
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
657
|
+
}),
|
|
658
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
659
|
+
transientArrayService: new TransientArrayService()
|
|
660
|
+
});
|
|
661
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
|
|
444
662
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
445
663
|
throw new ExecutionError(err.message, {
|
|
446
664
|
contractAddress: call.to,
|
|
@@ -449,21 +667,30 @@ export class TXEOracleTopLevelContext {
|
|
|
449
667
|
cause: err
|
|
450
668
|
});
|
|
451
669
|
});
|
|
452
|
-
this.logger.verbose(`Utility
|
|
670
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
453
671
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
454
672
|
} catch (err) {
|
|
455
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
673
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
456
674
|
}
|
|
457
675
|
}
|
|
458
676
|
close() {
|
|
459
677
|
this.logger.debug('Exiting Top Level Context');
|
|
460
678
|
return [
|
|
461
679
|
this.nextBlockTimestamp,
|
|
462
|
-
this.authwits
|
|
680
|
+
this.authwits,
|
|
681
|
+
this.taggingSecretStrategies
|
|
463
682
|
];
|
|
464
683
|
}
|
|
465
684
|
async getLastBlockNumber() {
|
|
466
|
-
const
|
|
467
|
-
return
|
|
685
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
686
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
687
|
+
}
|
|
688
|
+
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
689
|
+
if (authorizedTargets.length === 0) {
|
|
690
|
+
return undefined;
|
|
691
|
+
}
|
|
692
|
+
return (req)=>Promise.resolve({
|
|
693
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
|
|
694
|
+
});
|
|
468
695
|
}
|
|
469
696
|
}
|