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