@aztec/txe 0.0.1-commit.a072138 → 0.0.1-commit.a4600f49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/AuthRegistry-HMC7WEOJ.js +3 -0
- package/dest/AuthRegistry-HMC7WEOJ.js.map +7 -0
- package/dest/ContractClassRegistry-TXCDCFNC.js +3 -0
- package/dest/ContractClassRegistry-TXCDCFNC.js.map +7 -0
- package/dest/ContractInstanceRegistry-2TZHWOTT.js +3 -0
- package/dest/ContractInstanceRegistry-2TZHWOTT.js.map +7 -0
- package/dest/FeeJuice-FDF3J2Q5.js +3 -0
- package/dest/FeeJuice-FDF3J2Q5.js.map +7 -0
- package/dest/HandshakeRegistry-C7JF4R54.js +3 -0
- package/dest/HandshakeRegistry-C7JF4R54.js.map +7 -0
- package/dest/MultiCallEntrypoint-IGLO227K.js +3 -0
- package/dest/MultiCallEntrypoint-IGLO227K.js.map +7 -0
- package/dest/SchnorrAccount-KCIHUCXS.js +3 -0
- package/dest/SchnorrAccount-KCIHUCXS.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-PVR6XUSN.js +3 -0
- package/dest/SchnorrInitializerlessAccount-PVR6XUSN.js.map +7 -0
- package/dest/bin/check_txe_oracle_version.d.ts +2 -0
- package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
- package/dest/bin/check_txe_oracle_version.js +61 -0
- package/dest/bin/index.js +3 -30
- package/dest/bin/index.js.map +7 -0
- package/dest/bin/oracle_test_server.d.ts +3 -0
- package/dest/bin/oracle_test_server.d.ts.map +1 -0
- package/dest/bin/oracle_test_server.js +41 -0
- package/dest/chunk-32UHX7YY.js +3 -0
- package/dest/chunk-32UHX7YY.js.map +7 -0
- package/dest/chunk-6AVNR3XX.js +304 -0
- package/dest/chunk-6AVNR3XX.js.map +7 -0
- package/dest/chunk-CJEH2W44.js +260 -0
- package/dest/chunk-CJEH2W44.js.map +7 -0
- package/dest/constants.d.ts +5 -1
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +9 -1
- package/dest/dispatcher_pool.d.ts +67 -0
- package/dest/dispatcher_pool.d.ts.map +1 -0
- package/dest/dispatcher_pool.js +286 -0
- package/dest/index.d.ts +51 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +73 -157
- package/dest/metafile.json +38497 -0
- package/dest/msgpackr_fr_extension.d.ts +2 -0
- package/dest/msgpackr_fr_extension.d.ts.map +1 -0
- package/dest/msgpackr_fr_extension.js +21 -0
- package/dest/oracle/interfaces.d.ts +61 -30
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/default_fixtures.js +207 -0
- package/dest/oracle/test-resolver/index.d.ts +9 -0
- package/dest/oracle/test-resolver/index.d.ts.map +1 -0
- package/dest/oracle/test-resolver/index.js +32 -0
- package/dest/oracle/test-resolver/resolver.d.ts +48 -0
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
- package/dest/oracle/test-resolver/resolver.js +181 -0
- package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +61 -13
- package/dest/oracle/txe_oracle_registry.d.ts +169 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +745 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +55 -29
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +582 -275
- package/dest/oracle/txe_oracle_version.d.ts +17 -0
- package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_version.js +14 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
- package/dest/oracle/txe_private_execution_oracle.js +15 -0
- package/dest/rpc_server.d.ts +14 -0
- package/dest/rpc_server.d.ts.map +1 -0
- package/dest/rpc_server.js +78 -0
- package/dest/rpc_translator.d.ts +112 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +877 -612
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +30 -20
- package/dest/state_machine/dummy_p2p_client.d.ts +29 -16
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +53 -20
- package/dest/state_machine/global_variable_builder.d.ts +10 -6
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +8 -5
- package/dest/state_machine/index.d.ts +13 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +60 -15
- package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +33 -2
- package/dest/state_machine/synchronizer.d.ts +14 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +22 -9
- package/dest/txe_session.d.ts +89 -16
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +370 -55
- package/dest/utils/block_creation.d.ts +2 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +5 -3
- package/dest/utils/encoding.d.ts +192 -0
- package/dest/utils/encoding.d.ts.map +1 -0
- package/dest/{util → utils}/encoding.js +7 -2
- package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
- package/dest/utils/expected_failure_error.d.ts.map +1 -0
- package/dest/utils/tx_effect_creation.d.ts +1 -1
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +0 -1
- package/dest/{util → utils}/txe_account_store.d.ts +1 -1
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.d.ts +37 -0
- package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.js +161 -0
- package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/utils/txe_public_contract_data_source.js +51 -0
- package/dest/worker.bundle.js +3 -0
- package/dest/worker.bundle.js.map +7 -0
- package/dest/worker.d.ts +2 -0
- package/dest/worker.d.ts.map +1 -0
- package/dest/worker.js +92 -0
- package/package.json +38 -21
- package/src/bin/check_txe_oracle_version.ts +70 -0
- package/src/bin/index.ts +11 -2
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +11 -1
- package/src/dispatcher_pool.ts +317 -0
- package/src/index.ts +99 -190
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +64 -35
- package/src/oracle/test-resolver/default_fixtures.ts +282 -0
- package/src/oracle/test-resolver/index.ts +44 -0
- package/src/oracle/test-resolver/resolver.ts +245 -0
- package/src/oracle/txe_oracle_public_context.ts +74 -12
- package/src/oracle/txe_oracle_registry.ts +536 -0
- package/src/oracle/txe_oracle_top_level_context.ts +429 -175
- package/src/oracle/txe_oracle_version.ts +17 -0
- package/src/oracle/txe_private_execution_oracle.ts +30 -0
- package/src/rpc_server.ts +87 -0
- package/src/rpc_translator.ts +1087 -995
- package/src/state_machine/archiver.ts +43 -20
- package/src/state_machine/dummy_p2p_client.ts +83 -32
- package/src/state_machine/global_variable_builder.ts +12 -11
- package/src/state_machine/index.ts +84 -33
- package/src/state_machine/mock_epoch_cache.ts +43 -3
- package/src/state_machine/synchronizer.ts +31 -10
- package/src/txe_session.ts +601 -114
- package/src/utils/block_creation.ts +5 -2
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/tx_effect_creation.ts +0 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/utils/txe_public_contract_data_source.ts +60 -0
- package/src/worker.ts +98 -0
- package/dest/util/encoding.d.ts +0 -720
- package/dest/util/encoding.d.ts.map +0 -1
- package/dest/util/expected_failure_error.d.ts.map +0 -1
- package/dest/util/txe_account_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.d.ts +0 -12
- package/dest/util/txe_contract_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.js +0 -22
- package/dest/util/txe_public_contract_data_source.d.ts +0 -21
- package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
- package/dest/util/txe_public_contract_data_source.js +0 -67
- package/src/util/txe_contract_store.ts +0 -36
- package/src/util/txe_public_contract_data_source.ts +0 -86
- /package/dest/{util → utils}/expected_failure_error.js +0 -0
- /package/dest/{util → utils}/txe_account_store.js +0 -0
- /package/src/{util → utils}/expected_failure_error.ts +0 -0
- /package/src/{util → utils}/txe_account_store.ts +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import type { ContractStore } from '@aztec/pxe/server';
|
|
4
5
|
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
5
6
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
7
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
8
|
+
import type { ContractInstancePreimageWithAddress } from '@aztec/stdlib/contract';
|
|
7
9
|
import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
8
10
|
import {
|
|
9
11
|
MerkleTreeId,
|
|
@@ -29,6 +31,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
29
31
|
private forkedWorldTrees: MerkleTreeWriteOperations,
|
|
30
32
|
private txRequestHash: Fr,
|
|
31
33
|
private globalVariables: GlobalVariables,
|
|
34
|
+
private contractStore: ContractStore,
|
|
32
35
|
) {
|
|
33
36
|
this.logger = createLogger('txe:public_context');
|
|
34
37
|
|
|
@@ -39,46 +42,46 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
39
42
|
});
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
address(): Promise<AztecAddress> {
|
|
43
46
|
return Promise.resolve(this.contractAddress);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
sender(): Promise<AztecAddress> {
|
|
47
50
|
return Promise.resolve(AztecAddress.ZERO); // todo: change?
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
blockNumber(): Promise<BlockNumber> {
|
|
51
54
|
return Promise.resolve(this.globalVariables.blockNumber);
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
timestamp(): Promise<bigint> {
|
|
55
58
|
return Promise.resolve(this.globalVariables.timestamp);
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
isStaticCall(): Promise<boolean> {
|
|
59
62
|
return Promise.resolve(false);
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
chainId(): Promise<Fr> {
|
|
63
66
|
return Promise.resolve(this.globalVariables.chainId);
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
version(): Promise<Fr> {
|
|
67
70
|
return Promise.resolve(this.globalVariables.version);
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
async
|
|
73
|
+
async emitNullifier(nullifier: Fr) {
|
|
71
74
|
const siloedNullifier = await siloNullifier(this.contractAddress, nullifier);
|
|
72
75
|
this.transientSiloedNullifiers.push(siloedNullifier);
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
async
|
|
78
|
+
async emitNoteHash(noteHash: Fr) {
|
|
76
79
|
const siloedNoteHash = await siloNoteHash(this.contractAddress, noteHash);
|
|
77
80
|
// TODO: make the note hash unique - they are only siloed right now
|
|
78
81
|
this.transientUniqueNoteHashes.push(siloedNoteHash);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
|
-
async
|
|
84
|
+
async nullifierExists(siloedNullifier: Fr): Promise<boolean> {
|
|
82
85
|
const treeIndex = (
|
|
83
86
|
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()])
|
|
84
87
|
)[0];
|
|
@@ -87,7 +90,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
87
90
|
return treeIndex !== undefined || transientIndex !== undefined;
|
|
88
91
|
}
|
|
89
92
|
|
|
90
|
-
async
|
|
93
|
+
async storageWrite(slot: Fr, value: Fr) {
|
|
91
94
|
this.logger.debug('AVM storage write', { slot, value });
|
|
92
95
|
|
|
93
96
|
const dataWrite = new PublicDataWrite(await computePublicDataTreeLeafSlot(this.contractAddress, slot), value);
|
|
@@ -99,7 +102,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
99
102
|
]);
|
|
100
103
|
}
|
|
101
104
|
|
|
102
|
-
async
|
|
105
|
+
async storageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr> {
|
|
103
106
|
const leafSlot = await computePublicDataTreeLeafSlot(contractAddress, slot);
|
|
104
107
|
|
|
105
108
|
const lowLeafResult = await this.forkedWorldTrees.getPreviousValueIndex(
|
|
@@ -122,6 +125,65 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
122
125
|
return value;
|
|
123
126
|
}
|
|
124
127
|
|
|
128
|
+
getContractInstanceDeployer(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]> {
|
|
129
|
+
return this.getContractInstanceMember(address, i => i.deployer.toField());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getContractInstanceClassId(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]> {
|
|
133
|
+
// TXE has no contract updates, so the current class always equals the original.
|
|
134
|
+
return this.getContractInstanceMember(address, i => i.originalContractClassId);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getContractInstanceInitializationHash(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]> {
|
|
138
|
+
return this.getContractInstanceMember(address, i => i.initializationHash);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
getContractInstanceImmutablesHash(address: AztecAddress): Promise<{ member: Fr; exists: boolean }[]> {
|
|
142
|
+
return this.getContractInstanceMember(address, i => i.immutablesHash);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// The one-element array mirrors the oracles' Noir return type, `[GetContractInstanceResult; 1]`.
|
|
146
|
+
private async getContractInstanceMember(
|
|
147
|
+
address: AztecAddress,
|
|
148
|
+
accessor: (instance: ContractInstancePreimageWithAddress) => Fr,
|
|
149
|
+
): Promise<{ member: Fr; exists: boolean }[]> {
|
|
150
|
+
const instance = await this.contractStore.getContractInstance(address);
|
|
151
|
+
if (!instance) {
|
|
152
|
+
return [{ member: Fr.ZERO, exists: false }];
|
|
153
|
+
}
|
|
154
|
+
return [{ member: accessor(instance), exists: true }];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
returndataSize(): Promise<number> {
|
|
158
|
+
throw new Error(
|
|
159
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
returndataCopy(_rdOffset: number, _copySize: number): Promise<Fr[]> {
|
|
164
|
+
throw new Error(
|
|
165
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
call(_l2Gas: number, _daGas: number, _address: AztecAddress, _argsLength: number, _args: Fr[]): Promise<void> {
|
|
170
|
+
throw new Error(
|
|
171
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
staticCall(_l2Gas: number, _daGas: number, _address: AztecAddress, _argsLength: number, _args: Fr[]): Promise<void> {
|
|
176
|
+
throw new Error(
|
|
177
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
successCopy(): Promise<boolean> {
|
|
182
|
+
throw new Error(
|
|
183
|
+
'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead',
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
125
187
|
async close(): Promise<L2Block> {
|
|
126
188
|
this.logger.debug('Exiting Public Context, building block with collected side effects', {
|
|
127
189
|
blockNumber: this.globalVariables.blockNumber,
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
import {
|
|
3
|
+
GAS_SETTINGS_LENGTH,
|
|
4
|
+
MAX_NOTE_HASHES_PER_TX,
|
|
5
|
+
MAX_NULLIFIERS_PER_TX,
|
|
6
|
+
MAX_PRIVATE_LOGS_PER_TX,
|
|
7
|
+
PRIVATE_CONTEXT_INPUTS_LENGTH,
|
|
8
|
+
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
9
|
+
} from '@aztec/constants';
|
|
10
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
11
|
+
import { Point } from '@aztec/foundation/curves/grumpkin';
|
|
12
|
+
import { withHexPrefix, withoutHexPrefix } from '@aztec/foundation/string';
|
|
13
|
+
import type { TaggingSecretStrategy } from '@aztec/pxe/server';
|
|
14
|
+
import {
|
|
15
|
+
ARRAY,
|
|
16
|
+
AZTEC_ADDRESS,
|
|
17
|
+
BIGINT,
|
|
18
|
+
BLOCK_NUMBER,
|
|
19
|
+
BOOL,
|
|
20
|
+
ETH_ADDRESS,
|
|
21
|
+
FIELD,
|
|
22
|
+
FIXED_ARRAY,
|
|
23
|
+
FUNCTION_SELECTOR,
|
|
24
|
+
type InputSlot,
|
|
25
|
+
type MaybePromise,
|
|
26
|
+
OPTION,
|
|
27
|
+
ORACLE_REGISTRY,
|
|
28
|
+
type OracleRegistryEntry,
|
|
29
|
+
type OutputSlot,
|
|
30
|
+
type ParamTypes,
|
|
31
|
+
STR,
|
|
32
|
+
STRUCT,
|
|
33
|
+
type SlotShape,
|
|
34
|
+
type TypeMapping,
|
|
35
|
+
U32,
|
|
36
|
+
buildACIRCallback,
|
|
37
|
+
makeEntry,
|
|
38
|
+
} from '@aztec/pxe/simulator';
|
|
39
|
+
import { EventSelector } from '@aztec/stdlib/abi';
|
|
40
|
+
import { CompleteAddress } from '@aztec/stdlib/contract';
|
|
41
|
+
import { GasSettings } from '@aztec/stdlib/gas';
|
|
42
|
+
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
43
|
+
import type { PrivateLog } from '@aztec/stdlib/logs';
|
|
44
|
+
import type { TxHash } from '@aztec/stdlib/tx';
|
|
45
|
+
|
|
46
|
+
import {
|
|
47
|
+
MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY,
|
|
48
|
+
MAX_OFFCHAIN_EFFECT_LEN,
|
|
49
|
+
MAX_PRIVATE_EVENTS_PER_TXE_QUERY,
|
|
50
|
+
MAX_PRIVATE_EVENT_LEN,
|
|
51
|
+
} from '../constants.js';
|
|
52
|
+
import type { ForeignCallArgs, ForeignCallResult } from '../utils/encoding.js';
|
|
53
|
+
|
|
54
|
+
// Spreading `ORACLE_REGISTRY` re-materializes its entries into `TXE_ORACLE_REGISTRY`'s inferred type, which names the
|
|
55
|
+
// protocol types below. Re-exporting them gives tsc a portable path to each instead of falling back to a deep
|
|
56
|
+
// node_modules path that breaks .d.ts portability (TS2742).
|
|
57
|
+
export type { ContractClassLogData, EmbeddedCurvePoint, TxEffectData } from '@aztec/pxe/simulator';
|
|
58
|
+
export type { BlockHash } from '@aztec/stdlib/block';
|
|
59
|
+
export type { MembershipWitness } from '@aztec/foundation/trees';
|
|
60
|
+
export type { NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
61
|
+
|
|
62
|
+
const GAS_SETTINGS: TypeMapping<GasSettings> = {
|
|
63
|
+
deserialization: {
|
|
64
|
+
fn: ([reader]) => GasSettings.fromFields(reader.readFieldArray(GAS_SETTINGS_LENGTH)),
|
|
65
|
+
},
|
|
66
|
+
shape: [{ len: GAS_SETTINGS_LENGTH }],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Tagging secret strategy discriminants. Must match the Noir test helper `TaggingSecretStrategy` in
|
|
70
|
+
// aztec-nr `test/helpers/tagging_secret_strategy.nr`. This is a test-only oracle (only `set_tagging_secret_strategy`
|
|
71
|
+
// reads it), so the mapping lives here on the TXE side rather than in the production oracle type mappings.
|
|
72
|
+
const STRATEGY_NON_INTERACTIVE_HANDSHAKE = 1;
|
|
73
|
+
const STRATEGY_ARBITRARY_SECRET = 2;
|
|
74
|
+
const STRATEGY_ADDRESS_DERIVED = 3;
|
|
75
|
+
const STRATEGY_INTERACTIVE_HANDSHAKE = 4;
|
|
76
|
+
|
|
77
|
+
const TAGGING_SECRET_STRATEGY: TypeMapping<TaggingSecretStrategy> = {
|
|
78
|
+
serialization: {
|
|
79
|
+
fn: strategy => {
|
|
80
|
+
switch (strategy.type) {
|
|
81
|
+
case 'non-interactive-handshake':
|
|
82
|
+
return [new Fr(STRATEGY_NON_INTERACTIVE_HANDSHAKE), Fr.ZERO, Fr.ZERO];
|
|
83
|
+
case 'interactive-handshake':
|
|
84
|
+
return [new Fr(STRATEGY_INTERACTIVE_HANDSHAKE), Fr.ZERO, Fr.ZERO];
|
|
85
|
+
case 'address-derived':
|
|
86
|
+
return [new Fr(STRATEGY_ADDRESS_DERIVED), Fr.ZERO, Fr.ZERO];
|
|
87
|
+
case 'arbitrary-secret':
|
|
88
|
+
return [new Fr(STRATEGY_ARBITRARY_SECRET), strategy.secret.x, strategy.secret.y];
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
deserialization: {
|
|
93
|
+
fn: ([kindReader, xReader, yReader]) => {
|
|
94
|
+
const kind = kindReader.readField().toNumber();
|
|
95
|
+
const [x, y] = [xReader.readField(), yReader.readField()];
|
|
96
|
+
switch (kind) {
|
|
97
|
+
case STRATEGY_NON_INTERACTIVE_HANDSHAKE:
|
|
98
|
+
return { type: 'non-interactive-handshake' };
|
|
99
|
+
case STRATEGY_INTERACTIVE_HANDSHAKE:
|
|
100
|
+
return { type: 'interactive-handshake' };
|
|
101
|
+
case STRATEGY_ADDRESS_DERIVED:
|
|
102
|
+
return { type: 'address-derived' };
|
|
103
|
+
case STRATEGY_ARBITRARY_SECRET:
|
|
104
|
+
return { type: 'arbitrary-secret', secret: Point.fromFields([x, y]) };
|
|
105
|
+
default:
|
|
106
|
+
throw new Error(`Unrecognized tagging secret strategy kind: ${kind}`);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
shape: ['scalar', 'scalar', 'scalar'],
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const PRIVATE_CONTEXT_INPUTS: TypeMapping<PrivateContextInputs> = {
|
|
114
|
+
serialization: { fn: v => v.toFields() },
|
|
115
|
+
shape: Array<SlotShape>(PRIVATE_CONTEXT_INPUTS_LENGTH).fill('scalar'),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const COMPLETE_ADDRESS: TypeMapping<CompleteAddress> = {
|
|
119
|
+
serialization: { fn: v => [v.address.toField(), ...v.publicKeys.toFields()] },
|
|
120
|
+
shape: Array<SlotShape>(8).fill('scalar'), // address + 7 public-key fields
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const TXE_TX_EFFECTS: TypeMapping<{
|
|
124
|
+
txHash: TxHash;
|
|
125
|
+
noteHashes: Fr[];
|
|
126
|
+
nullifiers: Fr[];
|
|
127
|
+
privateLogs: PrivateLog[];
|
|
128
|
+
}> = {
|
|
129
|
+
serialization: {
|
|
130
|
+
fn: ({ txHash, noteHashes, nullifiers, privateLogs }) => {
|
|
131
|
+
const emittedLogs = privateLogs.map(log => log.getEmittedFields());
|
|
132
|
+
const rawLogStorage = emittedLogs
|
|
133
|
+
.map(fields => fields.concat(Array(PRIVATE_LOG_SIZE_IN_FIELDS - fields.length).fill(Fr.ZERO)))
|
|
134
|
+
.concat(
|
|
135
|
+
Array(MAX_PRIVATE_LOGS_PER_TX - emittedLogs.length).fill(Array(PRIVATE_LOG_SIZE_IN_FIELDS).fill(Fr.ZERO)),
|
|
136
|
+
)
|
|
137
|
+
.flat();
|
|
138
|
+
const logLengths = emittedLogs
|
|
139
|
+
.map(fields => new Fr(fields.length))
|
|
140
|
+
.concat(Array(MAX_PRIVATE_LOGS_PER_TX - emittedLogs.length).fill(Fr.ZERO));
|
|
141
|
+
const paddedNoteHashes = noteHashes.concat(Array(MAX_NOTE_HASHES_PER_TX - noteHashes.length).fill(Fr.ZERO));
|
|
142
|
+
const paddedNullifiers = nullifiers.concat(Array(MAX_NULLIFIERS_PER_TX - nullifiers.length).fill(Fr.ZERO));
|
|
143
|
+
|
|
144
|
+
return [
|
|
145
|
+
txHash.hash,
|
|
146
|
+
paddedNoteHashes,
|
|
147
|
+
new Fr(noteHashes.length),
|
|
148
|
+
paddedNullifiers,
|
|
149
|
+
new Fr(nullifiers.length),
|
|
150
|
+
rawLogStorage,
|
|
151
|
+
logLengths,
|
|
152
|
+
new Fr(emittedLogs.length),
|
|
153
|
+
] as (Fr | Fr[])[];
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
// txHash, padded note hashes + count, padded nullifiers + count, flattened private-log storage + lengths + count.
|
|
157
|
+
shape: [
|
|
158
|
+
'scalar',
|
|
159
|
+
{ len: MAX_NOTE_HASHES_PER_TX },
|
|
160
|
+
'scalar',
|
|
161
|
+
{ len: MAX_NULLIFIERS_PER_TX },
|
|
162
|
+
'scalar',
|
|
163
|
+
{ len: MAX_PRIVATE_LOGS_PER_TX * PRIVATE_LOG_SIZE_IN_FIELDS },
|
|
164
|
+
{ len: MAX_PRIVATE_LOGS_PER_TX },
|
|
165
|
+
'scalar',
|
|
166
|
+
],
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const TXE_OFFCHAIN_EFFECTS: TypeMapping<{ effects: Fr[][] }> = {
|
|
170
|
+
serialization: {
|
|
171
|
+
fn: ({ effects }) => {
|
|
172
|
+
const rawArrayStorage = effects
|
|
173
|
+
.map(e => e.concat(Array(MAX_OFFCHAIN_EFFECT_LEN - e.length).fill(Fr.ZERO)))
|
|
174
|
+
.concat(
|
|
175
|
+
Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(Array(MAX_OFFCHAIN_EFFECT_LEN).fill(Fr.ZERO)),
|
|
176
|
+
)
|
|
177
|
+
.flat();
|
|
178
|
+
const effectLengths = effects
|
|
179
|
+
.map(e => new Fr(e.length))
|
|
180
|
+
.concat(Array(MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY - effects.length).fill(Fr.ZERO));
|
|
181
|
+
|
|
182
|
+
return [rawArrayStorage, effectLengths, new Fr(effects.length)] as (Fr | Fr[])[];
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
// Flattened effect storage, per-effect lengths, then the effect count.
|
|
186
|
+
shape: [
|
|
187
|
+
{ len: MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY * MAX_OFFCHAIN_EFFECT_LEN },
|
|
188
|
+
{ len: MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY },
|
|
189
|
+
'scalar',
|
|
190
|
+
],
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const TXE_CALL_CONTEXT: TypeMapping<{ txHash: Fr; anchorBlockTimestamp: bigint }> = {
|
|
194
|
+
serialization: {
|
|
195
|
+
fn: ({ txHash, anchorBlockTimestamp }) => {
|
|
196
|
+
const isSome = txHash.isZero() ? 0 : 1;
|
|
197
|
+
return [new Fr(isSome), txHash, new Fr(anchorBlockTimestamp)];
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
shape: ['scalar', 'scalar', 'scalar'], // discriminant, txHash, anchor block timestamp
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const CONTRACT_INSTANCE_MEMBER: TypeMapping<{ exists: boolean; member: Fr }[]> = FIXED_ARRAY(
|
|
204
|
+
STRUCT([
|
|
205
|
+
{ name: 'exists', type: BOOL },
|
|
206
|
+
{ name: 'member', type: FIELD },
|
|
207
|
+
]),
|
|
208
|
+
1,
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const EVENT_SELECTOR: TypeMapping<EventSelector> = {
|
|
212
|
+
serialization: { fn: v => [v.toField()] },
|
|
213
|
+
deserialization: { fn: ([reader]) => EventSelector.fromField(reader.readField()) },
|
|
214
|
+
shape: ['scalar'],
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const TXE_PRIVATE_EVENTS: TypeMapping<Fr[][]> = {
|
|
218
|
+
serialization: {
|
|
219
|
+
fn: events => {
|
|
220
|
+
const rawArrayStorage = events
|
|
221
|
+
.map(e => e.concat(Array(MAX_PRIVATE_EVENT_LEN - e.length).fill(Fr.ZERO)))
|
|
222
|
+
.concat(
|
|
223
|
+
Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_PRIVATE_EVENT_LEN).fill(Fr.ZERO)),
|
|
224
|
+
)
|
|
225
|
+
.flat();
|
|
226
|
+
const eventLengths = events
|
|
227
|
+
.map(e => new Fr(e.length))
|
|
228
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Fr.ZERO));
|
|
229
|
+
return [rawArrayStorage, eventLengths, new Fr(events.length)] as (Fr | Fr[])[];
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
// Flattened event storage, per-event lengths, then the event count.
|
|
233
|
+
shape: [
|
|
234
|
+
{ len: MAX_PRIVATE_EVENTS_PER_TXE_QUERY * MAX_PRIVATE_EVENT_LEN },
|
|
235
|
+
{ len: MAX_PRIVATE_EVENTS_PER_TXE_QUERY },
|
|
236
|
+
'scalar',
|
|
237
|
+
],
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export const TXE_ORACLE_REGISTRY = {
|
|
241
|
+
...ORACLE_REGISTRY,
|
|
242
|
+
|
|
243
|
+
aztec_txe_assertCompatibleOracleVersion: makeEntry({
|
|
244
|
+
params: [
|
|
245
|
+
{ name: 'major', type: U32 },
|
|
246
|
+
{ name: 'minor', type: U32 },
|
|
247
|
+
],
|
|
248
|
+
}),
|
|
249
|
+
|
|
250
|
+
aztec_txe_setTopLevelTXEContext: makeEntry(),
|
|
251
|
+
|
|
252
|
+
aztec_txe_setPrivateTXEContext: makeEntry({
|
|
253
|
+
params: [
|
|
254
|
+
{ name: 'contractAddress', type: OPTION(AZTEC_ADDRESS) },
|
|
255
|
+
{ name: 'anchorBlockNumber', type: OPTION(BLOCK_NUMBER) },
|
|
256
|
+
{ name: 'gasSettings', type: GAS_SETTINGS },
|
|
257
|
+
],
|
|
258
|
+
returnType: PRIVATE_CONTEXT_INPUTS,
|
|
259
|
+
}),
|
|
260
|
+
|
|
261
|
+
aztec_txe_setPublicTXEContext: makeEntry({
|
|
262
|
+
params: [{ name: 'contractAddress', type: OPTION(AZTEC_ADDRESS) }],
|
|
263
|
+
}),
|
|
264
|
+
|
|
265
|
+
aztec_txe_setUtilityTXEContext: makeEntry({
|
|
266
|
+
params: [{ name: 'contractAddress', type: OPTION(AZTEC_ADDRESS) }],
|
|
267
|
+
}),
|
|
268
|
+
|
|
269
|
+
aztec_txe_getDefaultAddress: makeEntry({ returnType: AZTEC_ADDRESS }),
|
|
270
|
+
|
|
271
|
+
aztec_txe_getNextBlockNumber: makeEntry({ returnType: BLOCK_NUMBER }),
|
|
272
|
+
|
|
273
|
+
aztec_txe_getNextBlockTimestamp: makeEntry({ returnType: BIGINT }),
|
|
274
|
+
|
|
275
|
+
aztec_txe_advanceBlocksBy: makeEntry({
|
|
276
|
+
params: [{ name: 'blocks', type: U32 }],
|
|
277
|
+
}),
|
|
278
|
+
|
|
279
|
+
aztec_txe_advanceTimestampBy: makeEntry({
|
|
280
|
+
params: [{ name: 'duration', type: BIGINT }],
|
|
281
|
+
}),
|
|
282
|
+
|
|
283
|
+
aztec_txe_deploy: makeEntry({
|
|
284
|
+
params: [
|
|
285
|
+
{ name: 'contractPath', type: STR },
|
|
286
|
+
{ name: 'initializer', type: STR },
|
|
287
|
+
{ name: 'argsLength', type: U32 },
|
|
288
|
+
{ name: 'args', type: ARRAY(FIELD) },
|
|
289
|
+
{ name: 'secret', type: FIELD },
|
|
290
|
+
{ name: 'salt', type: FIELD },
|
|
291
|
+
{ name: 'deployer', type: AZTEC_ADDRESS },
|
|
292
|
+
],
|
|
293
|
+
returnType: ARRAY(FIELD),
|
|
294
|
+
}),
|
|
295
|
+
|
|
296
|
+
aztec_txe_createAccount: makeEntry({
|
|
297
|
+
params: [{ name: 'secret', type: FIELD }],
|
|
298
|
+
returnType: COMPLETE_ADDRESS,
|
|
299
|
+
}),
|
|
300
|
+
|
|
301
|
+
aztec_txe_addAccount: makeEntry({
|
|
302
|
+
params: [{ name: 'secret', type: FIELD }],
|
|
303
|
+
returnType: COMPLETE_ADDRESS,
|
|
304
|
+
}),
|
|
305
|
+
|
|
306
|
+
aztec_txe_addAuthWitness: makeEntry({
|
|
307
|
+
params: [
|
|
308
|
+
{ name: 'address', type: AZTEC_ADDRESS },
|
|
309
|
+
{ name: 'messageHash', type: FIELD },
|
|
310
|
+
],
|
|
311
|
+
}),
|
|
312
|
+
|
|
313
|
+
aztec_txe_sendL1ToL2Message: makeEntry({
|
|
314
|
+
params: [
|
|
315
|
+
{ name: 'content', type: FIELD },
|
|
316
|
+
{ name: 'secretHash', type: FIELD },
|
|
317
|
+
{ name: 'sender', type: ETH_ADDRESS },
|
|
318
|
+
{ name: 'recipient', type: AZTEC_ADDRESS },
|
|
319
|
+
],
|
|
320
|
+
returnType: FIELD,
|
|
321
|
+
}),
|
|
322
|
+
|
|
323
|
+
aztec_txe_setTaggingSecretStrategy: makeEntry({
|
|
324
|
+
params: [{ name: 'strategy', type: OPTION(TAGGING_SECRET_STRATEGY) }],
|
|
325
|
+
}),
|
|
326
|
+
|
|
327
|
+
aztec_txe_getLastBlockTimestamp: makeEntry({
|
|
328
|
+
returnType: BIGINT,
|
|
329
|
+
}),
|
|
330
|
+
|
|
331
|
+
aztec_txe_getLastTxEffects: makeEntry({ returnType: TXE_TX_EFFECTS }),
|
|
332
|
+
aztec_txe_getLastCallOffchainEffects: makeEntry({ returnType: TXE_OFFCHAIN_EFFECTS }),
|
|
333
|
+
aztec_txe_getLastCallContext: makeEntry({ returnType: TXE_CALL_CONTEXT }),
|
|
334
|
+
|
|
335
|
+
aztec_txe_getPrivateEvents: makeEntry({
|
|
336
|
+
params: [
|
|
337
|
+
{ name: 'selector', type: EVENT_SELECTOR },
|
|
338
|
+
{ name: 'contractAddress', type: AZTEC_ADDRESS },
|
|
339
|
+
{ name: 'scope', type: AZTEC_ADDRESS },
|
|
340
|
+
],
|
|
341
|
+
returnType: TXE_PRIVATE_EVENTS,
|
|
342
|
+
}),
|
|
343
|
+
|
|
344
|
+
aztec_txe_privateCallNewFlow: makeEntry({
|
|
345
|
+
params: [
|
|
346
|
+
{ name: 'from', type: OPTION(AZTEC_ADDRESS) },
|
|
347
|
+
{ name: 'targetContractAddress', type: AZTEC_ADDRESS },
|
|
348
|
+
{ name: 'functionSelector', type: FUNCTION_SELECTOR },
|
|
349
|
+
{ name: 'args', type: ARRAY(FIELD) },
|
|
350
|
+
{ name: 'argsHash', type: FIELD },
|
|
351
|
+
{ name: 'isStaticCall', type: BOOL },
|
|
352
|
+
{ name: 'additionalScopes', type: ARRAY(AZTEC_ADDRESS) },
|
|
353
|
+
{ name: 'authorizedUtilityCallTargets', type: ARRAY(AZTEC_ADDRESS) },
|
|
354
|
+
{ name: 'gasSettings', type: GAS_SETTINGS },
|
|
355
|
+
],
|
|
356
|
+
returnType: ARRAY(FIELD),
|
|
357
|
+
}),
|
|
358
|
+
|
|
359
|
+
aztec_txe_executeUtilityFunction: makeEntry({
|
|
360
|
+
params: [
|
|
361
|
+
{ name: 'from', type: OPTION(AZTEC_ADDRESS) },
|
|
362
|
+
{ name: 'targetContractAddress', type: AZTEC_ADDRESS },
|
|
363
|
+
{ name: 'functionSelector', type: FUNCTION_SELECTOR },
|
|
364
|
+
{ name: 'args', type: ARRAY(FIELD) },
|
|
365
|
+
{ name: 'authorizedUtilityCallTargets', type: ARRAY(AZTEC_ADDRESS) },
|
|
366
|
+
],
|
|
367
|
+
returnType: ARRAY(FIELD),
|
|
368
|
+
}),
|
|
369
|
+
|
|
370
|
+
aztec_txe_publicCallNewFlow: makeEntry({
|
|
371
|
+
params: [
|
|
372
|
+
{ name: 'from', type: OPTION(AZTEC_ADDRESS) },
|
|
373
|
+
{ name: 'address', type: AZTEC_ADDRESS },
|
|
374
|
+
{ name: 'calldata', type: ARRAY(FIELD) },
|
|
375
|
+
{ name: 'isStaticCall', type: BOOL },
|
|
376
|
+
{ name: 'gasSettings', type: GAS_SETTINGS },
|
|
377
|
+
],
|
|
378
|
+
returnType: ARRAY(FIELD),
|
|
379
|
+
}),
|
|
380
|
+
|
|
381
|
+
aztec_avm_address: makeEntry({ returnType: AZTEC_ADDRESS }),
|
|
382
|
+
|
|
383
|
+
aztec_avm_sender: makeEntry({ returnType: AZTEC_ADDRESS }),
|
|
384
|
+
|
|
385
|
+
aztec_avm_blockNumber: makeEntry({ returnType: BLOCK_NUMBER }),
|
|
386
|
+
|
|
387
|
+
aztec_avm_timestamp: makeEntry({ returnType: BIGINT }),
|
|
388
|
+
|
|
389
|
+
aztec_avm_isStaticCall: makeEntry({ returnType: BOOL }),
|
|
390
|
+
|
|
391
|
+
aztec_avm_chainId: makeEntry({ returnType: FIELD }),
|
|
392
|
+
|
|
393
|
+
aztec_avm_version: makeEntry({ returnType: FIELD }),
|
|
394
|
+
|
|
395
|
+
aztec_avm_emitNullifier: makeEntry({
|
|
396
|
+
params: [{ name: 'nullifier', type: FIELD }],
|
|
397
|
+
}),
|
|
398
|
+
|
|
399
|
+
aztec_avm_emitNoteHash: makeEntry({
|
|
400
|
+
params: [{ name: 'noteHash', type: FIELD }],
|
|
401
|
+
}),
|
|
402
|
+
|
|
403
|
+
aztec_avm_nullifierExists: makeEntry({
|
|
404
|
+
params: [{ name: 'siloedNullifier', type: FIELD }],
|
|
405
|
+
returnType: BOOL,
|
|
406
|
+
}),
|
|
407
|
+
|
|
408
|
+
aztec_avm_storageRead: makeEntry({
|
|
409
|
+
params: [
|
|
410
|
+
{ name: 'slot', type: FIELD },
|
|
411
|
+
{ name: 'contractAddress', type: AZTEC_ADDRESS },
|
|
412
|
+
],
|
|
413
|
+
returnType: FIELD,
|
|
414
|
+
}),
|
|
415
|
+
|
|
416
|
+
aztec_avm_storageWrite: makeEntry({
|
|
417
|
+
params: [
|
|
418
|
+
{ name: 'slot', type: FIELD },
|
|
419
|
+
{ name: 'value', type: FIELD },
|
|
420
|
+
],
|
|
421
|
+
}),
|
|
422
|
+
|
|
423
|
+
aztec_avm_emitPublicLog: makeEntry({
|
|
424
|
+
params: [{ name: 'message', type: ARRAY(FIELD) }],
|
|
425
|
+
}),
|
|
426
|
+
|
|
427
|
+
aztec_avm_returndataSize: makeEntry({ returnType: U32 }),
|
|
428
|
+
|
|
429
|
+
aztec_avm_returndataCopy: makeEntry({
|
|
430
|
+
params: [
|
|
431
|
+
{ name: 'rdOffset', type: U32 },
|
|
432
|
+
{ name: 'copySize', type: U32 },
|
|
433
|
+
],
|
|
434
|
+
returnType: ARRAY(FIELD),
|
|
435
|
+
}),
|
|
436
|
+
|
|
437
|
+
aztec_avm_call: makeEntry({
|
|
438
|
+
params: [
|
|
439
|
+
{ name: 'l2Gas', type: U32 },
|
|
440
|
+
{ name: 'daGas', type: U32 },
|
|
441
|
+
{ name: 'address', type: AZTEC_ADDRESS },
|
|
442
|
+
{ name: 'argsLength', type: U32 },
|
|
443
|
+
{ name: 'args', type: ARRAY(FIELD) },
|
|
444
|
+
],
|
|
445
|
+
}),
|
|
446
|
+
|
|
447
|
+
aztec_avm_staticCall: makeEntry({
|
|
448
|
+
params: [
|
|
449
|
+
{ name: 'l2Gas', type: U32 },
|
|
450
|
+
{ name: 'daGas', type: U32 },
|
|
451
|
+
{ name: 'address', type: AZTEC_ADDRESS },
|
|
452
|
+
{ name: 'argsLength', type: U32 },
|
|
453
|
+
{ name: 'args', type: ARRAY(FIELD) },
|
|
454
|
+
],
|
|
455
|
+
}),
|
|
456
|
+
|
|
457
|
+
aztec_avm_successCopy: makeEntry({ returnType: BOOL }),
|
|
458
|
+
|
|
459
|
+
aztec_avm_getContractInstanceDeployer: makeEntry({
|
|
460
|
+
params: [{ name: 'address', type: AZTEC_ADDRESS }],
|
|
461
|
+
returnType: CONTRACT_INSTANCE_MEMBER,
|
|
462
|
+
}),
|
|
463
|
+
aztec_avm_getContractInstanceClassId: makeEntry({
|
|
464
|
+
params: [{ name: 'address', type: AZTEC_ADDRESS }],
|
|
465
|
+
returnType: CONTRACT_INSTANCE_MEMBER,
|
|
466
|
+
}),
|
|
467
|
+
aztec_avm_getContractInstanceInitializationHash: makeEntry({
|
|
468
|
+
params: [{ name: 'address', type: AZTEC_ADDRESS }],
|
|
469
|
+
returnType: CONTRACT_INSTANCE_MEMBER,
|
|
470
|
+
}),
|
|
471
|
+
aztec_avm_getContractInstanceImmutablesHash: makeEntry({
|
|
472
|
+
params: [{ name: 'address', type: AZTEC_ADDRESS }],
|
|
473
|
+
returnType: CONTRACT_INSTANCE_MEMBER,
|
|
474
|
+
}),
|
|
475
|
+
} satisfies Record<string, OracleRegistryEntry>;
|
|
476
|
+
|
|
477
|
+
export function toInputSlots(inputs: ForeignCallArgs): InputSlot[] {
|
|
478
|
+
// TXE foreign calls use bare hex strings, but Fr.fromString requires a 0x prefix to parse as hex.
|
|
479
|
+
return inputs.map(v => (Array.isArray(v) ? (v as string[]).map(withHexPrefix) : [withHexPrefix(v as string)]));
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Deserializes oracle inputs, calls the handler with typed params, serializes the result, and wraps
|
|
484
|
+
* it in a `ForeignCallResult`. Normalizes `ForeignCallArgs` (which may contain bare strings) into
|
|
485
|
+
* `InputSlot[]` (always arrays) before deserialization.
|
|
486
|
+
*/
|
|
487
|
+
export async function callTxeHandler<K extends keyof typeof TXE_ORACLE_REGISTRY>({
|
|
488
|
+
oracle,
|
|
489
|
+
inputs,
|
|
490
|
+
handler,
|
|
491
|
+
}: {
|
|
492
|
+
oracle: K;
|
|
493
|
+
inputs: ForeignCallArgs;
|
|
494
|
+
handler: (
|
|
495
|
+
params: ParamTypes<ReturnType<(typeof TXE_ORACLE_REGISTRY)[K]['deserializeParams']>>,
|
|
496
|
+
) => MaybePromise<Parameters<(typeof TXE_ORACLE_REGISTRY)[K]['serializeReturn']>[0]>;
|
|
497
|
+
}): Promise<ForeignCallResult> {
|
|
498
|
+
const entry = TXE_ORACLE_REGISTRY[oracle] as OracleRegistryEntry;
|
|
499
|
+
const named = entry.deserializeParams(toInputSlots(inputs));
|
|
500
|
+
const positional = named.map((p: { value: unknown }) => p.value);
|
|
501
|
+
const result = await handler(positional as any);
|
|
502
|
+
return outputSlotsToForeignCallResult(entry.serializeReturn(result));
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Dispatches an oracle that has been retired into the PXE legacy registry. TXE has no explicit handler method for such
|
|
507
|
+
* names; this runs them through the same `buildACIRCallback` legacy path that contract execution already uses, so
|
|
508
|
+
* TXE's top-level oracle path and its in-contract path treat the legacy registry identically.
|
|
509
|
+
*/
|
|
510
|
+
const legacyCallbacksByHandler = new WeakMap<object, ReturnType<typeof buildACIRCallback>>();
|
|
511
|
+
|
|
512
|
+
export async function callTxeLegacyHandler(
|
|
513
|
+
oracle: string,
|
|
514
|
+
inputs: ForeignCallArgs,
|
|
515
|
+
oracleHandler: Parameters<typeof buildACIRCallback>[0],
|
|
516
|
+
): Promise<ForeignCallResult> {
|
|
517
|
+
// `buildACIRCallback` materializes the whole real+legacy closure set, so memoize it per handler rather than
|
|
518
|
+
// rebuilding on every call (TXE routes one legacy oracle through here on each top-level discovery).
|
|
519
|
+
let callback = legacyCallbacksByHandler.get(oracleHandler);
|
|
520
|
+
if (!callback) {
|
|
521
|
+
callback = buildACIRCallback(oracleHandler);
|
|
522
|
+
legacyCallbacksByHandler.set(oracleHandler, callback);
|
|
523
|
+
}
|
|
524
|
+
const outputSlots = await callback[oracle](...toInputSlots(inputs));
|
|
525
|
+
return outputSlotsToForeignCallResult(outputSlots);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Strips the `0x` prefix from each serialized output slot (TXE foreign calls use bare hex strings) and wraps them in a
|
|
530
|
+
* `ForeignCallResult`.
|
|
531
|
+
*/
|
|
532
|
+
function outputSlotsToForeignCallResult(outputSlots: OutputSlot[]): ForeignCallResult {
|
|
533
|
+
return {
|
|
534
|
+
values: outputSlots.map(slot => (Array.isArray(slot) ? slot.map(withoutHexPrefix) : withoutHexPrefix(slot))),
|
|
535
|
+
};
|
|
536
|
+
}
|