@aztec/txe 0.71.0 → 0.73.0

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.
@@ -1,10 +1,9 @@
1
1
  import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
2
- import { L2Block, MerkleTreeId, SimulationError } from '@aztec/circuit-types';
2
+ import { MerkleTreeId, SimulationError } from '@aztec/circuit-types';
3
3
  import {
4
- BlockHeader,
5
4
  Fr,
6
5
  FunctionSelector,
7
- PublicDataTreeLeaf,
6
+ PublicDataWrite,
8
7
  PublicKeys,
9
8
  computePartialAddress,
10
9
  getContractInstanceFromDeployParams,
@@ -20,8 +19,7 @@ import { getCanonicalProtocolContract } from '@aztec/protocol-contracts/bundle';
20
19
  import { enrichPublicSimulationError } from '@aztec/pxe';
21
20
  import { type TypedOracle } from '@aztec/simulator/client';
22
21
  import { HashedValuesCache } from '@aztec/simulator/server';
23
- import { getTelemetryClient } from '@aztec/telemetry-client';
24
- import { MerkleTrees } from '@aztec/world-state';
22
+ import { NativeWorldStateService } from '@aztec/world-state';
25
23
 
26
24
  import { TXE } from '../oracle/txe_oracle.js';
27
25
  import {
@@ -42,18 +40,20 @@ export class TXEService {
42
40
 
43
41
  static async init(logger: Logger) {
44
42
  const store = openTmpStore(true);
45
- const trees = await MerkleTrees.new(store, getTelemetryClient(), logger);
46
43
  const executionCache = new HashedValuesCache();
44
+ const nativeWorldStateService = await NativeWorldStateService.tmp();
45
+ const baseFork = await nativeWorldStateService.fork();
46
+
47
47
  const keyStore = new KeyStore(store);
48
48
  const txeDatabase = new TXEDatabase(store);
49
49
  // Register protocol contracts.
50
50
  for (const name of protocolContractNames) {
51
- const { contractClass, instance, artifact } = getCanonicalProtocolContract(name);
51
+ const { contractClass, instance, artifact } = await getCanonicalProtocolContract(name);
52
52
  await txeDatabase.addContractArtifact(contractClass.id, artifact);
53
53
  await txeDatabase.addContractInstance(instance);
54
54
  }
55
55
  logger.debug(`TXE service initialized`);
56
- const txe = new TXE(logger, trees, executionCache, keyStore, txeDatabase);
56
+ const txe = await TXE.create(logger, executionCache, keyStore, txeDatabase, nativeWorldStateService, baseFork);
57
57
  const service = new TXEService(logger, txe);
58
58
  await service.advanceBlocksBy(toSingle(new Fr(1n)));
59
59
  return service;
@@ -69,21 +69,10 @@ export class TXEService {
69
69
  async advanceBlocksBy(blocks: ForeignCallSingle) {
70
70
  const nBlocks = fromSingle(blocks).toNumber();
71
71
  this.logger.debug(`time traveling ${nBlocks} blocks`);
72
- const trees = (this.typedOracle as TXE).getTrees();
73
-
74
- await (this.typedOracle as TXE).commitState();
75
72
 
76
73
  for (let i = 0; i < nBlocks; i++) {
77
74
  const blockNumber = await this.typedOracle.getBlockNumber();
78
- const header = BlockHeader.empty();
79
- const l2Block = L2Block.empty();
80
- header.state = await trees.getStateReference(true);
81
- header.globalVariables.blockNumber = new Fr(blockNumber);
82
- await trees.appendLeaves(MerkleTreeId.ARCHIVE, [header.hash()]);
83
- l2Block.archive.root = Fr.fromBuffer((await trees.getTreeInfo(MerkleTreeId.ARCHIVE, true)).root);
84
- l2Block.header = header;
85
- this.logger.debug(`Block ${blockNumber} created, header hash ${header.hash().toString()}`);
86
- await trees.handleL2BlockAndMessages(l2Block, []);
75
+ await (this.typedOracle as TXE).commitState();
87
76
  (this.typedOracle as TXE).setBlockNumber(blockNumber + 1);
88
77
  }
89
78
  return toForeignCallResult([]);
@@ -95,8 +84,8 @@ export class TXEService {
95
84
  return toForeignCallResult([]);
96
85
  }
97
86
 
98
- deriveKeys(secret: ForeignCallSingle) {
99
- const keys = (this.typedOracle as TXE).deriveKeys(fromSingle(secret));
87
+ async deriveKeys(secret: ForeignCallSingle) {
88
+ const keys = await (this.typedOracle as TXE).deriveKeys(fromSingle(secret));
100
89
  return toForeignCallResult(keys.publicKeys.toFields().map(toSingle));
101
90
  }
102
91
 
@@ -116,7 +105,7 @@ export class TXEService {
116
105
  `Deploy ${artifact.name} with initializer ${initializerStr}(${decodedArgs}) and public keys hash ${publicKeysHashFr}`,
117
106
  );
118
107
 
119
- const instance = getContractInstanceFromDeployParams(artifact, {
108
+ const instance = await getContractInstanceFromDeployParams(artifact, {
120
109
  constructorArgs: decodedArgs,
121
110
  skipArgsDecoding: true,
122
111
  salt: Fr.ONE,
@@ -145,22 +134,20 @@ export class TXEService {
145
134
  startStorageSlot: ForeignCallSingle,
146
135
  values: ForeignCallArray,
147
136
  ) {
148
- const trees = (this.typedOracle as TXE).getTrees();
149
137
  const startStorageSlotFr = fromSingle(startStorageSlot);
150
138
  const valuesFr = fromArray(values);
151
139
  const contractAddressFr = addressFromSingle(contractAddress);
152
- const db = await trees.getLatest();
153
140
 
154
- const publicDataWrites = valuesFr.map((value, i) => {
155
- const storageSlot = startStorageSlotFr.add(new Fr(i));
156
- this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
157
- return new PublicDataTreeLeaf(computePublicDataTreeLeafSlot(contractAddressFr, storageSlot), value);
158
- });
159
- await db.batchInsert(
160
- MerkleTreeId.PUBLIC_DATA_TREE,
161
- publicDataWrites.map(write => write.toBuffer()),
162
- 0,
141
+ const publicDataWrites = await Promise.all(
142
+ valuesFr.map(async (value, i) => {
143
+ const storageSlot = startStorageSlotFr.add(new Fr(i));
144
+ this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
145
+ return new PublicDataWrite(await computePublicDataTreeLeafSlot(contractAddressFr, storageSlot), value);
146
+ }),
163
147
  );
148
+
149
+ await (this.typedOracle as TXE).addPublicDataWrites(publicDataWrites);
150
+
164
151
  return toForeignCallResult([toArray(publicDataWrites.map(write => write.value))]);
165
152
  }
166
153
 
@@ -177,10 +164,10 @@ export class TXEService {
177
164
  }
178
165
 
179
166
  async addAccount(secret: ForeignCallSingle) {
180
- const keys = (this.typedOracle as TXE).deriveKeys(fromSingle(secret));
167
+ const keys = await (this.typedOracle as TXE).deriveKeys(fromSingle(secret));
181
168
  const args = [keys.publicKeys.masterIncomingViewingPublicKey.x, keys.publicKeys.masterIncomingViewingPublicKey.y];
182
169
  const artifact = SchnorrAccountContractArtifact;
183
- const instance = getContractInstanceFromDeployParams(artifact, {
170
+ const instance = await getContractInstanceFromDeployParams(artifact, {
184
171
  constructorArgs: args,
185
172
  skipArgsDecoding: true,
186
173
  salt: Fr.ONE,
@@ -194,7 +181,7 @@ export class TXEService {
194
181
  await (this.typedOracle as TXE).addContractArtifact(artifact);
195
182
 
196
183
  const keyStore = (this.typedOracle as TXE).getKeyStore();
197
- const completeAddress = await keyStore.addAccount(fromSingle(secret), computePartialAddress(instance));
184
+ const completeAddress = await keyStore.addAccount(fromSingle(secret), await computePartialAddress(instance));
198
185
  const accountStore = (this.typedOracle as TXE).getTXEDatabase();
199
186
  await accountStore.setAccount(completeAddress.address, completeAddress);
200
187
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -271,11 +258,6 @@ export class TXEService {
271
258
  return toForeignCallResult([toSingle(new Fr(blockNumber))]);
272
259
  }
273
260
 
274
- async storeArrayInExecutionCache(args: ForeignCallArray) {
275
- const hash = await this.typedOracle.storeArrayInExecutionCache(fromArray(args));
276
- return toForeignCallResult([toSingle(hash)]);
277
- }
278
-
279
261
  // Since the argument is a slice, noir automatically adds a length field to oracle call.
280
262
  async storeInExecutionCache(_length: ForeignCallSingle, values: ForeignCallArray) {
281
263
  const returnsHash = await this.typedOracle.storeInExecutionCache(fromArray(values));
@@ -534,16 +516,6 @@ export class TXEService {
534
516
  return toForeignCallResult([toSingle(await this.typedOracle.getVersion())]);
535
517
  }
536
518
 
537
- async addNullifiers(contractAddress: ForeignCallSingle, _length: ForeignCallSingle, nullifiers: ForeignCallArray) {
538
- await (this.typedOracle as TXE).addNullifiers(addressFromSingle(contractAddress), fromArray(nullifiers));
539
- return toForeignCallResult([]);
540
- }
541
-
542
- async addNoteHashes(contractAddress: ForeignCallSingle, _length: ForeignCallSingle, noteHashes: ForeignCallArray) {
543
- await (this.typedOracle as TXE).addNoteHashes(addressFromSingle(contractAddress), fromArray(noteHashes));
544
- return toForeignCallResult([]);
545
- }
546
-
547
519
  async getBlockHeader(blockNumber: ForeignCallSingle) {
548
520
  const header = await this.typedOracle.getBlockHeader(fromSingle(blockNumber).toNumber());
549
521
  if (!header) {
@@ -32,8 +32,8 @@ export class TXEPublicContractDataSource implements ContractDataSource {
32
32
  async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
33
33
  const contractClass = await this.txeOracle.getContractDataOracle().getContractClass(id);
34
34
  const artifact = await this.txeOracle.getContractDataOracle().getContractArtifact(id);
35
- const tree = new PrivateFunctionsTree(artifact);
36
- const privateFunctionsRoot = tree.getFunctionTreeRoot();
35
+ const tree = await PrivateFunctionsTree.create(artifact);
36
+ const privateFunctionsRoot = await tree.getFunctionTreeRoot();
37
37
 
38
38
  const publicFunctions: PublicFunction[] = [];
39
39
  if (contractClass!.packedBytecode.length > 0) {
@@ -57,7 +57,7 @@ export class TXEPublicContractDataSource implements ContractDataSource {
57
57
 
58
58
  async getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
59
59
  const contractClass = await this.txeOracle.getContractDataOracle().getContractClass(id);
60
- return Promise.resolve(computePublicBytecodeCommitment(contractClass.packedBytecode));
60
+ return computePublicBytecodeCommitment(contractClass.packedBytecode);
61
61
  }
62
62
 
63
63
  async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
@@ -79,9 +79,14 @@ export class TXEPublicContractDataSource implements ContractDataSource {
79
79
  if (!artifact) {
80
80
  return undefined;
81
81
  }
82
- const func = artifact.functions.find(f =>
83
- FunctionSelector.fromNameAndParameters({ name: f.name, parameters: f.parameters }).equals(selector),
82
+ const functionSelectorsAndNames = await Promise.all(
83
+ artifact.functions.map(async f => ({
84
+ name: f.name,
85
+ selector: await FunctionSelector.fromNameAndParameters({ name: f.name, parameters: f.parameters }),
86
+ })),
84
87
  );
88
+ const func = functionSelectorsAndNames.find(f => f.selector.equals(selector));
89
+
85
90
  return Promise.resolve(func?.name);
86
91
  }
87
92
 
@@ -3,19 +3,21 @@ import {
3
3
  type AztecAddress,
4
4
  type ContractDataSource,
5
5
  Fr,
6
- PublicDataTreeLeaf,
7
6
  type PublicDataTreeLeafPreimage,
7
+ PublicDataWrite,
8
8
  } from '@aztec/circuits.js';
9
9
  import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
10
10
  import { WorldStateDB } from '@aztec/simulator/server';
11
11
 
12
+ import { type TXE } from '../oracle/txe_oracle.js';
13
+
12
14
  export class TXEWorldStateDB extends WorldStateDB {
13
- constructor(private merkleDb: MerkleTreeWriteOperations, dataSource: ContractDataSource) {
15
+ constructor(private merkleDb: MerkleTreeWriteOperations, dataSource: ContractDataSource, private txe: TXE) {
14
16
  super(merkleDb, dataSource);
15
17
  }
16
18
 
17
19
  override async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
18
- const leafSlot = computePublicDataTreeLeafSlot(contract, slot).toBigInt();
20
+ const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
19
21
 
20
22
  const lowLeafResult = await this.merkleDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
21
23
 
@@ -31,11 +33,10 @@ export class TXEWorldStateDB extends WorldStateDB {
31
33
  }
32
34
 
33
35
  override async storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<bigint> {
34
- await this.merkleDb.batchInsert(
35
- MerkleTreeId.PUBLIC_DATA_TREE,
36
- [new PublicDataTreeLeaf(computePublicDataTreeLeafSlot(contract, slot), newValue).toBuffer()],
37
- 0,
38
- );
36
+ await this.txe.addPublicDataWrites([
37
+ new PublicDataWrite(await computePublicDataTreeLeafSlot(contract, slot), newValue),
38
+ ]);
39
+
39
40
  return newValue.toBigInt();
40
41
  }
41
42