@aztec/txe 0.0.1-commit.5daedc8 → 0.0.1-commit.6201a7b05
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/constants.d.ts +3 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +2 -0
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +91 -56
- package/dest/oracle/interfaces.d.ts +36 -29
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +16 -16
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +20 -22
- package/dest/oracle/txe_oracle_top_level_context.d.ts +44 -27
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +245 -109
- package/dest/rpc_translator.d.ts +136 -78
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +545 -178
- package/dest/state_machine/archiver.d.ts +21 -52
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +67 -99
- package/dest/state_machine/dummy_p2p_client.d.ts +21 -15
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +45 -25
- package/dest/state_machine/global_variable_builder.d.ts +11 -5
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +21 -3
- package/dest/state_machine/index.d.ts +9 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +45 -24
- package/dest/state_machine/mock_epoch_cache.d.ts +26 -8
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +49 -9
- package/dest/state_machine/synchronizer.d.ts +6 -5
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +8 -7
- package/dest/txe_session.d.ts +71 -15
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +228 -57
- package/dest/util/encoding.d.ts +688 -19
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +5 -1
- package/dest/util/txe_account_store.d.ts +10 -0
- package/dest/util/txe_account_store.d.ts.map +1 -0
- package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
- package/dest/util/txe_public_contract_data_source.d.ts +8 -8
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +13 -32
- package/dest/utils/block_creation.d.ts +21 -6
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +38 -4
- package/dest/utils/tx_effect_creation.d.ts +3 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +4 -7
- package/package.json +18 -18
- package/src/constants.ts +3 -0
- package/src/index.ts +103 -63
- package/src/oracle/interfaces.ts +37 -33
- package/src/oracle/txe_oracle_public_context.ts +21 -28
- package/src/oracle/txe_oracle_top_level_context.ts +291 -151
- package/src/rpc_translator.ts +645 -206
- package/src/state_machine/archiver.ts +63 -117
- package/src/state_machine/dummy_p2p_client.ts +62 -33
- package/src/state_machine/global_variable_builder.ts +38 -6
- package/src/state_machine/index.ts +68 -22
- package/src/state_machine/mock_epoch_cache.ts +61 -14
- package/src/state_machine/synchronizer.ts +9 -8
- package/src/txe_session.ts +351 -105
- package/src/util/encoding.ts +6 -1
- package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
- package/src/util/txe_public_contract_data_source.ts +20 -47
- package/src/utils/block_creation.ts +49 -15
- package/src/utils/tx_effect_creation.ts +5 -12
- 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/src/util/txe_contract_data_provider.ts +0 -36
package/src/index.ts
CHANGED
|
@@ -9,10 +9,14 @@ import { Fr } from '@aztec/aztec.js/fields';
|
|
|
9
9
|
import { PublicKeys, deriveKeys } from '@aztec/aztec.js/keys';
|
|
10
10
|
import { createSafeJsonRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
11
11
|
import type { Logger } from '@aztec/foundation/log';
|
|
12
|
-
import {
|
|
12
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
13
|
+
import { protocolContractNames } from '@aztec/protocol-contracts';
|
|
13
14
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
15
|
+
import { ContractStore } from '@aztec/pxe/server';
|
|
14
16
|
import { computeArtifactHash } from '@aztec/stdlib/contract';
|
|
15
|
-
import type {
|
|
17
|
+
import type { ContractArtifactWithHash } from '@aztec/stdlib/contract';
|
|
18
|
+
import type { ApiSchemaFor } from '@aztec/stdlib/schemas';
|
|
19
|
+
import { zodFor } from '@aztec/stdlib/schemas';
|
|
16
20
|
|
|
17
21
|
import { createHash } from 'crypto';
|
|
18
22
|
import { createReadStream } from 'fs';
|
|
@@ -28,22 +32,29 @@ import {
|
|
|
28
32
|
type ForeignCallResult,
|
|
29
33
|
ForeignCallResultSchema,
|
|
30
34
|
type ForeignCallSingle,
|
|
35
|
+
addressFromSingle,
|
|
31
36
|
fromArray,
|
|
32
37
|
fromSingle,
|
|
33
38
|
toSingle,
|
|
34
39
|
} from './util/encoding.js';
|
|
35
|
-
import type { ContractArtifactWithHash } from './util/txe_contract_data_provider.js';
|
|
36
40
|
|
|
37
41
|
const sessions = new Map<number, TXESession>();
|
|
38
42
|
|
|
39
43
|
/*
|
|
40
44
|
* TXE typically has to load the same contract artifacts over and over again for multiple tests,
|
|
41
|
-
* so we cache them here to avoid
|
|
45
|
+
* so we cache them here to avoid loading from disk repeatedly.
|
|
46
|
+
*
|
|
47
|
+
* The in-flight map coalesces concurrent requests for the same cache key so that
|
|
48
|
+
* computeArtifactHash (very expensive) is only run once even under parallelism.
|
|
42
49
|
*/
|
|
43
50
|
const TXEArtifactsCache = new Map<
|
|
44
51
|
string,
|
|
45
52
|
{ artifact: ContractArtifactWithHash; instance: ContractInstanceWithAddress }
|
|
46
53
|
>();
|
|
54
|
+
const TXEArtifactsCacheInFlight = new Map<
|
|
55
|
+
string,
|
|
56
|
+
Promise<{ artifact: ContractArtifactWithHash; instance: ContractInstanceWithAddress }>
|
|
57
|
+
>();
|
|
47
58
|
|
|
48
59
|
type TXEForeignCallInput = {
|
|
49
60
|
session_id: number;
|
|
@@ -53,19 +64,21 @@ type TXEForeignCallInput = {
|
|
|
53
64
|
inputs: ForeignCallArgs;
|
|
54
65
|
};
|
|
55
66
|
|
|
56
|
-
const TXEForeignCallInputSchema =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
const TXEForeignCallInputSchema = zodFor<TXEForeignCallInput>()(
|
|
68
|
+
z.object({
|
|
69
|
+
// eslint-disable-next-line camelcase
|
|
70
|
+
session_id: z.number().int().nonnegative(),
|
|
71
|
+
function: z.string() as z.ZodType<TXEOracleFunctionName>,
|
|
72
|
+
// eslint-disable-next-line camelcase
|
|
73
|
+
root_path: z.string(),
|
|
74
|
+
// eslint-disable-next-line camelcase
|
|
75
|
+
package_name: z.string(),
|
|
76
|
+
inputs: ForeignCallArgsSchema,
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
66
79
|
|
|
67
80
|
class TXEDispatcher {
|
|
68
|
-
private
|
|
81
|
+
private contractStore!: ContractStore;
|
|
69
82
|
|
|
70
83
|
constructor(private logger: Logger) {}
|
|
71
84
|
|
|
@@ -93,6 +106,8 @@ class TXEDispatcher {
|
|
|
93
106
|
|
|
94
107
|
const decodedArgs = fromArray(inputs[3] as ForeignCallArray);
|
|
95
108
|
const secret = fromSingle(inputs[4] as ForeignCallSingle);
|
|
109
|
+
const salt = fromSingle(inputs[5] as ForeignCallSingle);
|
|
110
|
+
const deployer = addressFromSingle(inputs[6] as ForeignCallSingle);
|
|
96
111
|
const publicKeys = secret.equals(Fr.ZERO) ? PublicKeys.default() : (await deriveKeys(secret)).publicKeys;
|
|
97
112
|
const publicKeysHash = await publicKeys.hash();
|
|
98
113
|
|
|
@@ -123,7 +138,7 @@ class TXEDispatcher {
|
|
|
123
138
|
|
|
124
139
|
const cacheKey = `${contractDirectory ?? ''}-${contractFilename}-${initializer}-${decodedArgs
|
|
125
140
|
.map(arg => arg.toString())
|
|
126
|
-
.join('-')}-${publicKeysHash}-${fileHash}`;
|
|
141
|
+
.join('-')}-${publicKeysHash}-${salt}-${deployer}-${fileHash}`;
|
|
127
142
|
|
|
128
143
|
let instance;
|
|
129
144
|
let artifact: ContractArtifactWithHash;
|
|
@@ -132,29 +147,36 @@ class TXEDispatcher {
|
|
|
132
147
|
this.logger.debug(`Using cached artifact for ${cacheKey}`);
|
|
133
148
|
({ artifact, instance } = TXEArtifactsCache.get(cacheKey)!);
|
|
134
149
|
} else {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
150
|
+
if (!TXEArtifactsCacheInFlight.has(cacheKey)) {
|
|
151
|
+
this.logger.debug(`Loading compiled artifact ${artifactPath}`);
|
|
152
|
+
const compute = async () => {
|
|
153
|
+
const artifactJSON = JSON.parse(await readFile(artifactPath, 'utf-8')) as NoirCompiledContract;
|
|
154
|
+
const artifactWithoutHash = loadContractArtifact(artifactJSON);
|
|
155
|
+
const computedArtifact: ContractArtifactWithHash = {
|
|
156
|
+
...artifactWithoutHash,
|
|
157
|
+
// Artifact hash is *very* expensive to compute, so we do it here once
|
|
158
|
+
// and the TXE contract data provider can cache it
|
|
159
|
+
artifactHash: await computeArtifactHash(artifactWithoutHash),
|
|
160
|
+
};
|
|
161
|
+
this.logger.debug(
|
|
162
|
+
`Deploy ${computedArtifact.name} with initializer ${initializer}(${decodedArgs}) and public keys hash ${publicKeysHash.toString()}`,
|
|
163
|
+
);
|
|
164
|
+
const computedInstance = await getContractInstanceFromInstantiationParams(computedArtifact, {
|
|
165
|
+
constructorArgs: decodedArgs,
|
|
166
|
+
skipArgsDecoding: true,
|
|
167
|
+
salt,
|
|
168
|
+
publicKeys,
|
|
169
|
+
constructorArtifact: initializer ? initializer : undefined,
|
|
170
|
+
deployer,
|
|
171
|
+
});
|
|
172
|
+
const result = { artifact: computedArtifact, instance: computedInstance };
|
|
173
|
+
TXEArtifactsCache.set(cacheKey, result);
|
|
174
|
+
TXEArtifactsCacheInFlight.delete(cacheKey);
|
|
175
|
+
return result;
|
|
176
|
+
};
|
|
177
|
+
TXEArtifactsCacheInFlight.set(cacheKey, compute());
|
|
178
|
+
}
|
|
179
|
+
({ artifact, instance } = await TXEArtifactsCacheInFlight.get(cacheKey)!);
|
|
158
180
|
}
|
|
159
181
|
|
|
160
182
|
inputs.splice(0, 1, artifact, instance, toSingle(secret));
|
|
@@ -172,23 +194,35 @@ class TXEDispatcher {
|
|
|
172
194
|
this.logger.debug(`Using cached artifact for ${cacheKey}`);
|
|
173
195
|
({ artifact, instance } = TXEArtifactsCache.get(cacheKey)!);
|
|
174
196
|
} else {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
if (!TXEArtifactsCacheInFlight.has(cacheKey)) {
|
|
198
|
+
const compute = async () => {
|
|
199
|
+
const keys = await deriveKeys(secret);
|
|
200
|
+
const args = [
|
|
201
|
+
keys.publicKeys.masterIncomingViewingPublicKey.x,
|
|
202
|
+
keys.publicKeys.masterIncomingViewingPublicKey.y,
|
|
203
|
+
];
|
|
204
|
+
const computedArtifact: ContractArtifactWithHash = {
|
|
205
|
+
...SchnorrAccountContractArtifact,
|
|
206
|
+
// Artifact hash is *very* expensive to compute, so we do it here once
|
|
207
|
+
// and the TXE contract data provider can cache it
|
|
208
|
+
artifactHash: await computeArtifactHash(SchnorrAccountContractArtifact),
|
|
209
|
+
};
|
|
210
|
+
const computedInstance = await getContractInstanceFromInstantiationParams(computedArtifact, {
|
|
211
|
+
constructorArgs: args,
|
|
212
|
+
skipArgsDecoding: true,
|
|
213
|
+
salt: Fr.ONE,
|
|
214
|
+
publicKeys: keys.publicKeys,
|
|
215
|
+
constructorArtifact: 'constructor',
|
|
216
|
+
deployer: AztecAddress.ZERO,
|
|
217
|
+
});
|
|
218
|
+
const result = { artifact: computedArtifact, instance: computedInstance };
|
|
219
|
+
TXEArtifactsCache.set(cacheKey, result);
|
|
220
|
+
TXEArtifactsCacheInFlight.delete(cacheKey);
|
|
221
|
+
return result;
|
|
222
|
+
};
|
|
223
|
+
TXEArtifactsCacheInFlight.set(cacheKey, compute());
|
|
224
|
+
}
|
|
225
|
+
({ artifact, instance } = await TXEArtifactsCacheInFlight.get(cacheKey)!);
|
|
192
226
|
}
|
|
193
227
|
|
|
194
228
|
inputs.splice(0, 0, artifact, instance);
|
|
@@ -201,20 +235,26 @@ class TXEDispatcher {
|
|
|
201
235
|
|
|
202
236
|
if (!sessions.has(sessionId)) {
|
|
203
237
|
this.logger.debug(`Creating new session ${sessionId}`);
|
|
204
|
-
if (!this.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
);
|
|
238
|
+
if (!this.contractStore) {
|
|
239
|
+
const kvStore = await openTmpStore('txe-contracts');
|
|
240
|
+
this.contractStore = new ContractStore(kvStore);
|
|
241
|
+
const provider = new BundledProtocolContractsProvider();
|
|
242
|
+
for (const name of protocolContractNames) {
|
|
243
|
+
const { instance, artifact } = await provider.getProtocolContractArtifact(name);
|
|
244
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
245
|
+
await this.contractStore.addContractInstance(instance);
|
|
246
|
+
}
|
|
247
|
+
this.logger.debug('Registered protocol contracts in shared contract store');
|
|
208
248
|
}
|
|
209
|
-
sessions.set(sessionId, await TXESession.init(this.
|
|
249
|
+
sessions.set(sessionId, await TXESession.init(this.contractStore));
|
|
210
250
|
}
|
|
211
251
|
|
|
212
252
|
switch (functionName) {
|
|
213
|
-
case '
|
|
253
|
+
case 'aztec_txe_deploy': {
|
|
214
254
|
await this.#processDeployInputs(callData);
|
|
215
255
|
break;
|
|
216
256
|
}
|
|
217
|
-
case '
|
|
257
|
+
case 'aztec_txe_addAccount': {
|
|
218
258
|
await this.#processAddAccountInputs(callData);
|
|
219
259
|
break;
|
|
220
260
|
}
|
package/src/oracle/interfaces.ts
CHANGED
|
@@ -2,10 +2,11 @@ import type { ContractArtifact } from '@aztec/aztec.js/abi';
|
|
|
2
2
|
import { CompleteAddress } from '@aztec/aztec.js/addresses';
|
|
3
3
|
import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
|
|
4
4
|
import { TxHash } from '@aztec/aztec.js/tx';
|
|
5
|
-
import
|
|
6
|
-
import type {
|
|
5
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
6
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
7
|
+
import type { EventSelector, FunctionSelector } from '@aztec/stdlib/abi';
|
|
7
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
|
-
import type {
|
|
9
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
9
10
|
|
|
10
11
|
// These interfaces complement the ones defined in PXE, and combined with those contain the full list of oracles used by
|
|
11
12
|
// aztec-nr. In particular, these include the ones needed to run Brillig code associated to #[external("public")] functions that has
|
|
@@ -23,18 +24,18 @@ import type { UInt32, UInt64 } from '@aztec/stdlib/types';
|
|
|
23
24
|
export interface IAvmExecutionOracle {
|
|
24
25
|
isAvm: true;
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
address(): Promise<AztecAddress>;
|
|
28
|
+
sender(): Promise<AztecAddress>;
|
|
29
|
+
blockNumber(): Promise<BlockNumber>;
|
|
30
|
+
timestamp(): Promise<bigint>;
|
|
31
|
+
isStaticCall(): Promise<boolean>;
|
|
32
|
+
chainId(): Promise<Fr>;
|
|
33
|
+
version(): Promise<Fr>;
|
|
34
|
+
emitNullifier(nullifier: Fr): Promise<void>;
|
|
35
|
+
emitNoteHash(noteHash: Fr): Promise<void>;
|
|
36
|
+
nullifierExists(siloedNullifier: Fr): Promise<boolean>;
|
|
37
|
+
storageWrite(slot: Fr, value: Fr): Promise<void>;
|
|
38
|
+
storageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr>;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -43,41 +44,44 @@ export interface IAvmExecutionOracle {
|
|
|
43
44
|
export interface ITxeExecutionOracle {
|
|
44
45
|
isTxe: true;
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
): Promise<
|
|
57
|
-
txeAddAuthWitness(address: AztecAddress, messageHash: Fr): Promise<void>;
|
|
58
|
-
txeGetLastBlockTimestamp(): Promise<bigint>;
|
|
59
|
-
txeGetLastTxEffects(): Promise<{
|
|
47
|
+
getDefaultAddress(): AztecAddress;
|
|
48
|
+
getNextBlockNumber(): Promise<BlockNumber>;
|
|
49
|
+
getNextBlockTimestamp(): Promise<UInt64>;
|
|
50
|
+
advanceBlocksBy(blocks: number): Promise<void>;
|
|
51
|
+
advanceTimestampBy(duration: UInt64): void;
|
|
52
|
+
deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, foreignSecret: Fr): Promise<void>;
|
|
53
|
+
createAccount(secret: Fr): Promise<CompleteAddress>;
|
|
54
|
+
addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr): Promise<CompleteAddress>;
|
|
55
|
+
addAuthWitness(address: AztecAddress, messageHash: Fr): Promise<void>;
|
|
56
|
+
getLastBlockTimestamp(): Promise<bigint>;
|
|
57
|
+
getLastTxEffects(): Promise<{
|
|
60
58
|
txHash: TxHash;
|
|
61
59
|
noteHashes: Fr[];
|
|
62
60
|
nullifiers: Fr[];
|
|
63
61
|
}>;
|
|
64
|
-
|
|
62
|
+
getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress): Promise<Fr[][]>;
|
|
63
|
+
privateCallNewFlow(
|
|
65
64
|
from: AztecAddress,
|
|
66
65
|
targetContractAddress: AztecAddress,
|
|
67
66
|
functionSelector: FunctionSelector,
|
|
68
67
|
args: Fr[],
|
|
69
68
|
argsHash: Fr,
|
|
70
69
|
isStaticCall: boolean,
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
jobId: string,
|
|
71
|
+
): Promise<{ returnValues: Fr[]; offchainEffects: Fr[][] }>;
|
|
72
|
+
executeUtilityFunction(
|
|
73
73
|
targetContractAddress: AztecAddress,
|
|
74
74
|
functionSelector: FunctionSelector,
|
|
75
75
|
args: Fr[],
|
|
76
|
+
jobId: string,
|
|
76
77
|
): Promise<Fr[]>;
|
|
77
|
-
|
|
78
|
+
publicCallNewFlow(
|
|
78
79
|
from: AztecAddress,
|
|
79
80
|
targetContractAddress: AztecAddress,
|
|
80
81
|
calldata: Fr[],
|
|
81
82
|
isStaticCall: boolean,
|
|
82
83
|
): Promise<Fr[]>;
|
|
84
|
+
// TODO(F-335): Drop this from here as it's not a real oracle handler - it's only called from
|
|
85
|
+
// RPCTranslator::txeGetPrivateEvents and never from Noir.
|
|
86
|
+
syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string): Promise<void>;
|
|
83
87
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
4
|
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
4
5
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import {
|
|
6
|
+
import type { L2Block } from '@aztec/stdlib/block';
|
|
6
7
|
import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
7
|
-
import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
|
|
8
8
|
import {
|
|
9
9
|
MerkleTreeId,
|
|
10
10
|
type MerkleTreeWriteOperations,
|
|
@@ -12,9 +12,8 @@ import {
|
|
|
12
12
|
PublicDataTreeLeafPreimage,
|
|
13
13
|
} from '@aztec/stdlib/trees';
|
|
14
14
|
import { GlobalVariables, TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
15
|
-
import type { UInt32 } from '@aztec/stdlib/types';
|
|
16
15
|
|
|
17
|
-
import { insertTxEffectIntoWorldTrees,
|
|
16
|
+
import { insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
18
17
|
import type { IAvmExecutionOracle } from './interfaces.js';
|
|
19
18
|
|
|
20
19
|
export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
@@ -40,57 +39,55 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
40
39
|
});
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
address(): Promise<AztecAddress> {
|
|
44
43
|
return Promise.resolve(this.contractAddress);
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
sender(): Promise<AztecAddress> {
|
|
48
47
|
return Promise.resolve(AztecAddress.ZERO); // todo: change?
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
|
|
50
|
+
blockNumber(): Promise<BlockNumber> {
|
|
52
51
|
return Promise.resolve(this.globalVariables.blockNumber);
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
timestamp(): Promise<bigint> {
|
|
56
55
|
return Promise.resolve(this.globalVariables.timestamp);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
isStaticCall(): Promise<boolean> {
|
|
60
59
|
return Promise.resolve(false);
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
|
|
62
|
+
chainId(): Promise<Fr> {
|
|
64
63
|
return Promise.resolve(this.globalVariables.chainId);
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
|
|
66
|
+
version(): Promise<Fr> {
|
|
68
67
|
return Promise.resolve(this.globalVariables.version);
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
async
|
|
70
|
+
async emitNullifier(nullifier: Fr) {
|
|
72
71
|
const siloedNullifier = await siloNullifier(this.contractAddress, nullifier);
|
|
73
72
|
this.transientSiloedNullifiers.push(siloedNullifier);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
async
|
|
75
|
+
async emitNoteHash(noteHash: Fr) {
|
|
77
76
|
const siloedNoteHash = await siloNoteHash(this.contractAddress, noteHash);
|
|
78
77
|
// TODO: make the note hash unique - they are only siloed right now
|
|
79
78
|
this.transientUniqueNoteHashes.push(siloedNoteHash);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
async
|
|
83
|
-
const nullifier = await siloNullifier(targetAddress, innerNullifier!);
|
|
84
|
-
|
|
81
|
+
async nullifierExists(siloedNullifier: Fr): Promise<boolean> {
|
|
85
82
|
const treeIndex = (
|
|
86
|
-
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
83
|
+
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()])
|
|
87
84
|
)[0];
|
|
88
|
-
const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(
|
|
85
|
+
const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(siloedNullifier));
|
|
89
86
|
|
|
90
87
|
return treeIndex !== undefined || transientIndex !== undefined;
|
|
91
88
|
}
|
|
92
89
|
|
|
93
|
-
async
|
|
90
|
+
async storageWrite(slot: Fr, value: Fr) {
|
|
94
91
|
this.logger.debug('AVM storage write', { slot, value });
|
|
95
92
|
|
|
96
93
|
const dataWrite = new PublicDataWrite(await computePublicDataTreeLeafSlot(this.contractAddress, slot), value);
|
|
@@ -102,8 +99,8 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
102
99
|
]);
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
async
|
|
106
|
-
const leafSlot = await computePublicDataTreeLeafSlot(
|
|
102
|
+
async storageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr> {
|
|
103
|
+
const leafSlot = await computePublicDataTreeLeafSlot(contractAddress, slot);
|
|
107
104
|
|
|
108
105
|
const lowLeafResult = await this.forkedWorldTrees.getPreviousValueIndex(
|
|
109
106
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
@@ -120,7 +117,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
120
117
|
)) as PublicDataTreeLeafPreimage
|
|
121
118
|
).leaf.value;
|
|
122
119
|
|
|
123
|
-
this.logger.debug('AVM storage read', { slot, value });
|
|
120
|
+
this.logger.debug('AVM storage read', { slot, contractAddress, value });
|
|
124
121
|
|
|
125
122
|
return value;
|
|
126
123
|
}
|
|
@@ -133,11 +130,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
133
130
|
const txEffect = this.makeTxEffect();
|
|
134
131
|
await insertTxEffectIntoWorldTrees(txEffect, this.forkedWorldTrees);
|
|
135
132
|
|
|
136
|
-
const block =
|
|
137
|
-
makeAppendOnlyTreeSnapshot(),
|
|
138
|
-
await makeTXEBlockHeader(this.forkedWorldTrees, this.globalVariables),
|
|
139
|
-
new Body([txEffect]),
|
|
140
|
-
);
|
|
133
|
+
const block = await makeTXEBlock(this.forkedWorldTrees, this.globalVariables, [txEffect]);
|
|
141
134
|
|
|
142
135
|
await this.forkedWorldTrees.close();
|
|
143
136
|
|