@aztec/archiver 0.64.0 → 0.65.1

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.
Files changed (38) hide show
  1. package/dest/archiver/archiver.d.ts +2 -0
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +19 -6
  4. package/dest/archiver/archiver_store.d.ts +4 -2
  5. package/dest/archiver/archiver_store.d.ts.map +1 -1
  6. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.js +4 -4
  8. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  9. package/dest/archiver/data_retrieval.js +6 -6
  10. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  11. package/dest/archiver/kv_archiver_store/block_store.js +3 -3
  12. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -1
  13. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  14. package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -4
  15. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +5 -2
  16. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  17. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +22 -6
  18. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +5 -2
  19. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
  20. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +23 -5
  21. package/dest/factory.d.ts.map +1 -1
  22. package/dest/factory.js +6 -4
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +3 -2
  25. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  26. package/dest/test/mock_l2_block_source.js +3 -3
  27. package/package.json +11 -11
  28. package/src/archiver/archiver.ts +32 -4
  29. package/src/archiver/archiver_store.ts +9 -2
  30. package/src/archiver/archiver_store_test_suite.ts +11 -2
  31. package/src/archiver/data_retrieval.ts +18 -5
  32. package/src/archiver/kv_archiver_store/block_store.ts +2 -2
  33. package/src/archiver/kv_archiver_store/contract_class_store.ts +14 -1
  34. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +31 -6
  35. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +33 -4
  36. package/src/factory.ts +9 -3
  37. package/src/index.ts +2 -1
  38. package/src/test/mock_l2_block_source.ts +10 -2
@@ -15,22 +15,30 @@ import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
15
15
  */
16
16
  export class ContractClassStore {
17
17
  #contractClasses: AztecMap<string, Buffer>;
18
+ #bytecodeCommitments: AztecMap<string, Buffer>;
18
19
 
19
20
  constructor(private db: AztecKVStore) {
20
21
  this.#contractClasses = db.openMap('archiver_contract_classes');
22
+ this.#bytecodeCommitments = db.openMap('archiver_bytecode_commitments');
21
23
  }
22
24
 
23
- async addContractClass(contractClass: ContractClassPublic, blockNumber: number): Promise<void> {
25
+ async addContractClass(
26
+ contractClass: ContractClassPublic,
27
+ bytecodeCommitment: Fr,
28
+ blockNumber: number,
29
+ ): Promise<void> {
24
30
  await this.#contractClasses.setIfNotExists(
25
31
  contractClass.id.toString(),
26
32
  serializeContractClassPublic({ ...contractClass, l2BlockNumber: blockNumber }),
27
33
  );
34
+ await this.#bytecodeCommitments.setIfNotExists(contractClass.id.toString(), bytecodeCommitment.toBuffer());
28
35
  }
29
36
 
30
37
  async deleteContractClasses(contractClass: ContractClassPublic, blockNumber: number): Promise<void> {
31
38
  const restoredContractClass = this.#contractClasses.get(contractClass.id.toString());
32
39
  if (restoredContractClass && deserializeContractClassPublic(restoredContractClass).l2BlockNumber >= blockNumber) {
33
40
  await this.#contractClasses.delete(contractClass.id.toString());
41
+ await this.#bytecodeCommitments.delete(contractClass.id.toString());
34
42
  }
35
43
  }
36
44
 
@@ -39,6 +47,11 @@ export class ContractClassStore {
39
47
  return contractClass && { ...deserializeContractClassPublic(contractClass), id };
40
48
  }
41
49
 
50
+ getBytecodeCommitment(id: Fr): Fr | undefined {
51
+ const value = this.#bytecodeCommitments.get(id.toString());
52
+ return value === undefined ? undefined : Fr.fromBuffer(value);
53
+ }
54
+
42
55
  getContractClassIds(): Fr[] {
43
56
  return Array.from(this.#contractClasses.keys()).map(key => Fr.fromString(key));
44
57
  }
@@ -19,7 +19,7 @@ import {
19
19
  type Header,
20
20
  type UnconstrainedFunctionWithMembershipProof,
21
21
  } from '@aztec/circuits.js';
22
- import { type ContractArtifact } from '@aztec/foundation/abi';
22
+ import { type ContractArtifact, FunctionSelector } from '@aztec/foundation/abi';
23
23
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
24
24
  import { createDebugLogger } from '@aztec/foundation/log';
25
25
  import { type AztecKVStore } from '@aztec/kv-store';
@@ -46,6 +46,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
46
46
  #contractClassStore: ContractClassStore;
47
47
  #contractInstanceStore: ContractInstanceStore;
48
48
  #contractArtifactStore: ContractArtifactsStore;
49
+ private functionNames = new Map<string, string>();
49
50
 
50
51
  #log = createDebugLogger('aztec:archiver:data-store');
51
52
 
@@ -63,8 +64,19 @@ export class KVArchiverDataStore implements ArchiverDataStore {
63
64
  return Promise.resolve(this.#contractArtifactStore.getContractArtifact(address));
64
65
  }
65
66
 
66
- addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
67
- return this.#contractArtifactStore.addContractArtifact(address, contract);
67
+ // TODO: These function names are in memory only as they are for development/debugging. They require the full contract
68
+ // artifact supplied to the node out of band. This should be reviewed and potentially removed as part of
69
+ // the node api cleanup process.
70
+ getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
71
+ return Promise.resolve(this.functionNames.get(selector.toString()));
72
+ }
73
+
74
+ async addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
75
+ await this.#contractArtifactStore.addContractArtifact(address, contract);
76
+ // Building tup this map of selectors to function names save expensive re-hydration of contract artifacts later
77
+ contract.functions.forEach(f => {
78
+ this.functionNames.set(FunctionSelector.fromNameAndParameters(f.name, f.parameters).toString(), f.name);
79
+ });
68
80
  }
69
81
 
70
82
  getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
@@ -76,11 +88,20 @@ export class KVArchiverDataStore implements ArchiverDataStore {
76
88
  }
77
89
 
78
90
  getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
79
- return Promise.resolve(this.#contractInstanceStore.getContractInstance(address));
91
+ const contract = this.#contractInstanceStore.getContractInstance(address);
92
+ return Promise.resolve(contract);
80
93
  }
81
94
 
82
- async addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
83
- return (await Promise.all(data.map(c => this.#contractClassStore.addContractClass(c, blockNumber)))).every(Boolean);
95
+ async addContractClasses(
96
+ data: ContractClassPublic[],
97
+ bytecodeCommitments: Fr[],
98
+ blockNumber: number,
99
+ ): Promise<boolean> {
100
+ return (
101
+ await Promise.all(
102
+ data.map((c, i) => this.#contractClassStore.addContractClass(c, bytecodeCommitments[i], blockNumber)),
103
+ )
104
+ ).every(Boolean);
84
105
  }
85
106
 
86
107
  async deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
@@ -89,6 +110,10 @@ export class KVArchiverDataStore implements ArchiverDataStore {
89
110
  );
90
111
  }
91
112
 
113
+ getBytecodeCommitment(contractClassId: Fr): Promise<Fr | undefined> {
114
+ return Promise.resolve(this.#contractClassStore.getBytecodeCommitment(contractClassId));
115
+ }
116
+
92
117
  addFunctions(
93
118
  contractClassId: Fr,
94
119
  privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
@@ -9,6 +9,7 @@ import {
9
9
  type InBlock,
10
10
  type InboxLeaf,
11
11
  type L2Block,
12
+ L2BlockHash,
12
13
  type L2BlockL2Logs,
13
14
  type LogFilter,
14
15
  LogId,
@@ -32,7 +33,7 @@ import {
32
33
  MAX_NULLIFIERS_PER_TX,
33
34
  type UnconstrainedFunctionWithMembershipProof,
34
35
  } from '@aztec/circuits.js';
35
- import { type ContractArtifact } from '@aztec/foundation/abi';
36
+ import { type ContractArtifact, FunctionSelector } from '@aztec/foundation/abi';
36
37
  import { type AztecAddress } from '@aztec/foundation/aztec-address';
37
38
  import { createDebugLogger } from '@aztec/foundation/log';
38
39
 
@@ -78,6 +79,8 @@ export class MemoryArchiverStore implements ArchiverDataStore {
78
79
 
79
80
  private contractClasses: Map<string, ContractClassPublicWithBlockNumber> = new Map();
80
81
 
82
+ private bytecodeCommitments: Map<string, Fr> = new Map();
83
+
81
84
  private privateFunctions: Map<string, ExecutablePrivateFunctionWithMembershipProof[]> = new Map();
82
85
 
83
86
  private unconstrainedFunctions: Map<string, UnconstrainedFunctionWithMembershipProof[]> = new Map();
@@ -116,6 +119,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
116
119
  return Promise.resolve(this.contractInstances.get(address.toString()));
117
120
  }
118
121
 
122
+ public getBytecodeCommitment(contractClassId: Fr): Promise<Fr | undefined> {
123
+ return Promise.resolve(this.bytecodeCommitments.get(contractClassId.toString()));
124
+ }
125
+
119
126
  public addFunctions(
120
127
  contractClassId: Fr,
121
128
  newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
@@ -138,14 +145,22 @@ export class MemoryArchiverStore implements ArchiverDataStore {
138
145
  return Promise.resolve(true);
139
146
  }
140
147
 
141
- public addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
142
- for (const contractClass of data) {
148
+ public addContractClasses(
149
+ data: ContractClassPublic[],
150
+ bytecodeCommitments: Fr[],
151
+ blockNumber: number,
152
+ ): Promise<boolean> {
153
+ for (let i = 0; i < data.length; i++) {
154
+ const contractClass = data[i];
143
155
  if (!this.contractClasses.has(contractClass.id.toString())) {
144
156
  this.contractClasses.set(contractClass.id.toString(), {
145
157
  ...contractClass,
146
158
  l2BlockNumber: blockNumber,
147
159
  });
148
160
  }
161
+ if (!this.bytecodeCommitments.has(contractClass.id.toString())) {
162
+ this.bytecodeCommitments.set(contractClass.id.toString(), bytecodeCommitments[i]);
163
+ }
149
164
  }
150
165
  return Promise.resolve(true);
151
166
  }
@@ -155,6 +170,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
155
170
  const restored = this.contractClasses.get(contractClass.id.toString());
156
171
  if (restored && restored.l2BlockNumber >= blockNumber) {
157
172
  this.contractClasses.delete(contractClass.id.toString());
173
+ this.bytecodeCommitments.delete(contractClass.id.toString());
158
174
  }
159
175
  }
160
176
  return Promise.resolve(true);
@@ -435,7 +451,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
435
451
  TxReceipt.statusFromRevertCode(txEffect.revertCode),
436
452
  '',
437
453
  txEffect.transactionFee.toBigInt(),
438
- block.data.hash().toBuffer(),
454
+ L2BlockHash.fromField(block.data.hash()),
439
455
  block.data.number,
440
456
  ),
441
457
  );
@@ -737,6 +753,19 @@ export class MemoryArchiverStore implements ArchiverDataStore {
737
753
  return Promise.resolve(this.contractArtifacts.get(address.toString()));
738
754
  }
739
755
 
756
+ async getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
757
+ const artifact = await this.getContractArtifact(address);
758
+
759
+ if (!artifact) {
760
+ return undefined;
761
+ }
762
+
763
+ const func = artifact.functions.find(f =>
764
+ FunctionSelector.fromNameAndParameters({ name: f.name, parameters: f.parameters }).equals(selector),
765
+ );
766
+ return Promise.resolve(func?.name);
767
+ }
768
+
740
769
  public estimateSize(): { mappingSize: number; actualSize: number; numItems: number } {
741
770
  return { mappingSize: 0, actualSize: 0, numItems: 0 };
742
771
  }
package/src/factory.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { type ArchiverApi, type Service } from '@aztec/circuit-types';
2
- import { type ContractClassPublic, getContractClassFromArtifact } from '@aztec/circuits.js';
2
+ import {
3
+ type ContractClassPublic,
4
+ computePublicBytecodeCommitment,
5
+ getContractClassFromArtifact,
6
+ } from '@aztec/circuits.js';
3
7
  import { createDebugLogger } from '@aztec/foundation/log';
4
8
  import { type Maybe } from '@aztec/foundation/types';
5
9
  import { type DataStoreConfig } from '@aztec/kv-store/config';
@@ -40,7 +44,8 @@ async function registerProtocolContracts(store: KVArchiverDataStore) {
40
44
  unconstrainedFunctions: [],
41
45
  };
42
46
  await store.addContractArtifact(contract.address, contract.artifact);
43
- await store.addContractClasses([contractClassPublic], blockNumber);
47
+ const bytecodeCommitment = computePublicBytecodeCommitment(contractClassPublic.packedBytecode);
48
+ await store.addContractClasses([contractClassPublic], [bytecodeCommitment], blockNumber);
44
49
  await store.addContractInstances([contract.instance], blockNumber);
45
50
  }
46
51
  }
@@ -58,5 +63,6 @@ async function registerCommonContracts(store: KVArchiverDataStore) {
58
63
  privateFunctions: [],
59
64
  unconstrainedFunctions: [],
60
65
  }));
61
- await store.addContractClasses(classes, blockNumber);
66
+ const bytecodeCommitments = classes.map(x => computePublicBytecodeCommitment(x.packedBytecode));
67
+ await store.addContractClasses(classes, bytecodeCommitments, blockNumber);
62
68
  }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { jsonStringify } from '@aztec/foundation/json-rpc';
1
2
  import { createDebugLogger } from '@aztec/foundation/log';
2
3
  import { fileURLToPath } from '@aztec/foundation/url';
3
4
  import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
@@ -25,7 +26,7 @@ async function main() {
25
26
  const config = getArchiverConfigFromEnv();
26
27
  const { l1RpcUrl: rpcUrl, l1Contracts } = config;
27
28
 
28
- log.info(`Starting archiver in main(): ${JSON.stringify(config)}`);
29
+ log.info(`Starting archiver in main(): ${jsonStringify(config)}`);
29
30
  const publicClient = createPublicClient({
30
31
  chain: localhost,
31
32
  transport: http(rpcUrl),
@@ -1,4 +1,12 @@
1
- import { L2Block, type L2BlockSource, type L2Tips, type TxHash, TxReceipt, TxStatus } from '@aztec/circuit-types';
1
+ import {
2
+ L2Block,
3
+ L2BlockHash,
4
+ type L2BlockSource,
5
+ type L2Tips,
6
+ type TxHash,
7
+ TxReceipt,
8
+ TxStatus,
9
+ } from '@aztec/circuit-types';
2
10
  import { EthAddress, type Header } from '@aztec/circuits.js';
3
11
  import { DefaultL1ContractsConfig } from '@aztec/ethereum';
4
12
  import { createDebugLogger } from '@aztec/foundation/log';
@@ -144,7 +152,7 @@ export class MockL2BlockSource implements L2BlockSource {
144
152
  TxStatus.SUCCESS,
145
153
  '',
146
154
  txEffect.transactionFee.toBigInt(),
147
- block.hash().toBuffer(),
155
+ L2BlockHash.fromField(block.hash()),
148
156
  block.number,
149
157
  ),
150
158
  );