@aztec/archiver 0.0.0-test.1 → 0.0.1-commit.24de95ac

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 (102) hide show
  1. package/README.md +27 -6
  2. package/dest/archiver/archiver.d.ts +126 -46
  3. package/dest/archiver/archiver.d.ts.map +1 -1
  4. package/dest/archiver/archiver.js +683 -261
  5. package/dest/archiver/archiver_store.d.ts +84 -49
  6. package/dest/archiver/archiver_store.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  8. package/dest/archiver/archiver_store_test_suite.js +707 -213
  9. package/dest/archiver/config.d.ts +4 -20
  10. package/dest/archiver/config.d.ts.map +1 -1
  11. package/dest/archiver/config.js +16 -12
  12. package/dest/archiver/data_retrieval.d.ts +25 -20
  13. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  14. package/dest/archiver/data_retrieval.js +147 -68
  15. package/dest/archiver/errors.d.ts +8 -0
  16. package/dest/archiver/errors.d.ts.map +1 -1
  17. package/dest/archiver/errors.js +12 -0
  18. package/dest/archiver/index.d.ts +2 -3
  19. package/dest/archiver/index.d.ts.map +1 -1
  20. package/dest/archiver/index.js +1 -2
  21. package/dest/archiver/instrumentation.d.ts +9 -3
  22. package/dest/archiver/instrumentation.d.ts.map +1 -1
  23. package/dest/archiver/instrumentation.js +58 -17
  24. package/dest/archiver/kv_archiver_store/block_store.d.ts +47 -10
  25. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  26. package/dest/archiver/kv_archiver_store/block_store.js +216 -63
  27. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -2
  28. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  29. package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -18
  30. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +10 -7
  31. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
  32. package/dest/archiver/kv_archiver_store/contract_instance_store.js +30 -16
  33. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +49 -34
  34. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  35. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +88 -46
  36. package/dest/archiver/kv_archiver_store/log_store.d.ts +1 -1
  37. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  38. package/dest/archiver/kv_archiver_store/log_store.js +18 -46
  39. package/dest/archiver/kv_archiver_store/message_store.d.ts +22 -16
  40. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  41. package/dest/archiver/kv_archiver_store/message_store.js +150 -48
  42. package/dest/archiver/structs/inbox_message.d.ts +15 -0
  43. package/dest/archiver/structs/inbox_message.d.ts.map +1 -0
  44. package/dest/archiver/structs/inbox_message.js +38 -0
  45. package/dest/archiver/structs/published.d.ts +1 -10
  46. package/dest/archiver/structs/published.d.ts.map +1 -1
  47. package/dest/archiver/structs/published.js +1 -1
  48. package/dest/archiver/validation.d.ts +11 -0
  49. package/dest/archiver/validation.d.ts.map +1 -0
  50. package/dest/archiver/validation.js +90 -0
  51. package/dest/factory.d.ts +7 -12
  52. package/dest/factory.d.ts.map +1 -1
  53. package/dest/factory.js +18 -49
  54. package/dest/rpc/index.d.ts +1 -2
  55. package/dest/rpc/index.d.ts.map +1 -1
  56. package/dest/rpc/index.js +1 -4
  57. package/dest/test/mock_archiver.d.ts +1 -1
  58. package/dest/test/mock_l1_to_l2_message_source.d.ts +4 -2
  59. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  60. package/dest/test/mock_l1_to_l2_message_source.js +14 -1
  61. package/dest/test/mock_l2_block_source.d.ts +32 -5
  62. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  63. package/dest/test/mock_l2_block_source.js +118 -7
  64. package/dest/test/mock_structs.d.ts +9 -0
  65. package/dest/test/mock_structs.d.ts.map +1 -0
  66. package/dest/test/mock_structs.js +37 -0
  67. package/package.json +25 -27
  68. package/src/archiver/archiver.ts +858 -317
  69. package/src/archiver/archiver_store.ts +97 -55
  70. package/src/archiver/archiver_store_test_suite.ts +663 -210
  71. package/src/archiver/config.ts +23 -41
  72. package/src/archiver/data_retrieval.ts +215 -92
  73. package/src/archiver/errors.ts +21 -0
  74. package/src/archiver/index.ts +2 -3
  75. package/src/archiver/instrumentation.ts +75 -20
  76. package/src/archiver/kv_archiver_store/block_store.ts +270 -72
  77. package/src/archiver/kv_archiver_store/contract_class_store.ts +13 -23
  78. package/src/archiver/kv_archiver_store/contract_instance_store.ts +35 -27
  79. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +127 -63
  80. package/src/archiver/kv_archiver_store/log_store.ts +24 -62
  81. package/src/archiver/kv_archiver_store/message_store.ts +209 -53
  82. package/src/archiver/structs/inbox_message.ts +41 -0
  83. package/src/archiver/structs/published.ts +1 -11
  84. package/src/archiver/validation.ts +99 -0
  85. package/src/factory.ts +24 -66
  86. package/src/rpc/index.ts +1 -5
  87. package/src/test/mock_archiver.ts +1 -1
  88. package/src/test/mock_l1_to_l2_message_source.ts +14 -3
  89. package/src/test/mock_l2_block_source.ts +152 -8
  90. package/src/test/mock_structs.ts +49 -0
  91. package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +0 -12
  92. package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +0 -1
  93. package/dest/archiver/kv_archiver_store/nullifier_store.js +0 -73
  94. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +0 -23
  95. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +0 -1
  96. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +0 -49
  97. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +0 -175
  98. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +0 -1
  99. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +0 -636
  100. package/src/archiver/kv_archiver_store/nullifier_store.ts +0 -97
  101. package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +0 -61
  102. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +0 -801
@@ -7,7 +7,7 @@ import type {
7
7
  ContractClassPublic,
8
8
  ContractClassPublicWithBlockNumber,
9
9
  ExecutablePrivateFunctionWithMembershipProof,
10
- UnconstrainedFunctionWithMembershipProof,
10
+ UtilityFunctionWithMembershipProof,
11
11
  } from '@aztec/stdlib/contract';
12
12
  import { Vector } from '@aztec/stdlib/types';
13
13
 
@@ -60,7 +60,7 @@ export class ContractClassStore {
60
60
  async addFunctions(
61
61
  contractClassId: Fr,
62
62
  newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
63
- newUnconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[],
63
+ newUtilityFunctions: UtilityFunctionWithMembershipProof[],
64
64
  ): Promise<boolean> {
65
65
  await this.db.transactionAsync(async () => {
66
66
  const existingClassBuffer = await this.#contractClasses.getAsync(contractClassId.toString());
@@ -69,7 +69,7 @@ export class ContractClassStore {
69
69
  }
70
70
 
71
71
  const existingClass = deserializeContractClassPublic(existingClassBuffer);
72
- const { privateFunctions: existingPrivateFns, unconstrainedFunctions: existingUnconstrainedFns } = existingClass;
72
+ const { privateFunctions: existingPrivateFns, utilityFunctions: existingUtilityFns } = existingClass;
73
73
 
74
74
  const updatedClass: Omit<ContractClassPublicWithBlockNumber, 'id'> = {
75
75
  ...existingClass,
@@ -77,11 +77,9 @@ export class ContractClassStore {
77
77
  ...existingPrivateFns,
78
78
  ...newPrivateFunctions.filter(newFn => !existingPrivateFns.some(f => f.selector.equals(newFn.selector))),
79
79
  ],
80
- unconstrainedFunctions: [
81
- ...existingUnconstrainedFns,
82
- ...newUnconstrainedFunctions.filter(
83
- newFn => !existingUnconstrainedFns.some(f => f.selector.equals(newFn.selector)),
84
- ),
80
+ utilityFunctions: [
81
+ ...existingUtilityFns,
82
+ ...newUtilityFunctions.filter(newFn => !existingUtilityFns.some(f => f.selector.equals(newFn.selector))),
85
83
  ],
86
84
  };
87
85
  await this.#contractClasses.set(contractClassId.toString(), serializeContractClassPublic(updatedClass));
@@ -96,12 +94,10 @@ function serializeContractClassPublic(contractClass: Omit<ContractClassPublicWit
96
94
  contractClass.l2BlockNumber,
97
95
  numToUInt8(contractClass.version),
98
96
  contractClass.artifactHash,
99
- contractClass.publicFunctions.length,
100
- contractClass.publicFunctions?.map(f => serializeToBuffer(f.selector, f.bytecode.length, f.bytecode)) ?? [],
101
97
  contractClass.privateFunctions.length,
102
98
  contractClass.privateFunctions.map(serializePrivateFunction),
103
- contractClass.unconstrainedFunctions.length,
104
- contractClass.unconstrainedFunctions.map(serializeUnconstrainedFunction),
99
+ contractClass.utilityFunctions.length,
100
+ contractClass.utilityFunctions.map(serializeUtilityFunction),
105
101
  contractClass.packedBytecode.length,
106
102
  contractClass.packedBytecode,
107
103
  contractClass.privateFunctionsRoot,
@@ -116,7 +112,7 @@ function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipPro
116
112
  fn.bytecode,
117
113
  fn.functionMetadataHash,
118
114
  fn.artifactMetadataHash,
119
- fn.unconstrainedFunctionsArtifactTreeRoot,
115
+ fn.utilityFunctionsTreeRoot,
120
116
  new Vector(fn.privateFunctionTreeSiblingPath),
121
117
  fn.privateFunctionTreeLeafIndex,
122
118
  new Vector(fn.artifactTreeSiblingPath),
@@ -124,7 +120,7 @@ function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipPro
124
120
  );
125
121
  }
126
122
 
127
- function serializeUnconstrainedFunction(fn: UnconstrainedFunctionWithMembershipProof): Buffer {
123
+ function serializeUtilityFunction(fn: UtilityFunctionWithMembershipProof): Buffer {
128
124
  return serializeToBuffer(
129
125
  fn.selector,
130
126
  fn.bytecode.length,
@@ -143,14 +139,8 @@ function deserializeContractClassPublic(buffer: Buffer): Omit<ContractClassPubli
143
139
  l2BlockNumber: reader.readNumber(),
144
140
  version: reader.readUInt8() as 1,
145
141
  artifactHash: reader.readObject(Fr),
146
- publicFunctions: reader.readVector({
147
- fromBuffer: reader => ({
148
- selector: reader.readObject(FunctionSelector),
149
- bytecode: reader.readBuffer(),
150
- }),
151
- }),
152
142
  privateFunctions: reader.readVector({ fromBuffer: deserializePrivateFunction }),
153
- unconstrainedFunctions: reader.readVector({ fromBuffer: deserializeUnconstrainedFunction }),
143
+ utilityFunctions: reader.readVector({ fromBuffer: deserializeUtilityFunction }),
154
144
  packedBytecode: reader.readBuffer(),
155
145
  privateFunctionsRoot: reader.readObject(Fr),
156
146
  };
@@ -164,7 +154,7 @@ function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePr
164
154
  bytecode: reader.readBuffer(),
165
155
  functionMetadataHash: reader.readObject(Fr),
166
156
  artifactMetadataHash: reader.readObject(Fr),
167
- unconstrainedFunctionsArtifactTreeRoot: reader.readObject(Fr),
157
+ utilityFunctionsTreeRoot: reader.readObject(Fr),
168
158
  privateFunctionTreeSiblingPath: reader.readVector(Fr),
169
159
  privateFunctionTreeLeafIndex: reader.readNumber(),
170
160
  artifactTreeSiblingPath: reader.readVector(Fr),
@@ -172,7 +162,7 @@ function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePr
172
162
  };
173
163
  }
174
164
 
175
- function deserializeUnconstrainedFunction(buffer: Buffer | BufferReader): UnconstrainedFunctionWithMembershipProof {
165
+ function deserializeUtilityFunction(buffer: Buffer | BufferReader): UtilityFunctionWithMembershipProof {
176
166
  const reader = BufferReader.asReader(buffer);
177
167
  return {
178
168
  selector: reader.readObject(FunctionSelector),
@@ -7,71 +7,75 @@ import {
7
7
  SerializableContractInstance,
8
8
  SerializableContractInstanceUpdate,
9
9
  } from '@aztec/stdlib/contract';
10
+ import type { UInt64 } from '@aztec/stdlib/types';
10
11
 
11
- type ContractInstanceUpdateKey = [string, number] | [string, number, number];
12
+ type ContractInstanceUpdateKey = [string, string] | [string, string, number];
12
13
 
13
14
  /**
14
15
  * LMDB implementation of the ArchiverDataStore interface.
15
16
  */
16
17
  export class ContractInstanceStore {
17
18
  #contractInstances: AztecAsyncMap<string, Buffer>;
19
+ #contractInstancePublishedAt: AztecAsyncMap<string, number>;
18
20
  #contractInstanceUpdates: AztecAsyncMap<ContractInstanceUpdateKey, Buffer>;
19
21
 
20
- constructor(db: AztecAsyncKVStore) {
22
+ constructor(private db: AztecAsyncKVStore) {
21
23
  this.#contractInstances = db.openMap('archiver_contract_instances');
24
+ this.#contractInstancePublishedAt = db.openMap('archiver_contract_instances_publication_block_number');
22
25
  this.#contractInstanceUpdates = db.openMap('archiver_contract_instance_updates');
23
26
  }
24
27
 
25
- addContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void> {
26
- return this.#contractInstances.set(
27
- contractInstance.address.toString(),
28
- new SerializableContractInstance(contractInstance).toBuffer(),
29
- );
28
+ addContractInstance(contractInstance: ContractInstanceWithAddress, blockNumber: number): Promise<void> {
29
+ return this.db.transactionAsync(async () => {
30
+ await this.#contractInstances.set(
31
+ contractInstance.address.toString(),
32
+ new SerializableContractInstance(contractInstance).toBuffer(),
33
+ );
34
+ await this.#contractInstancePublishedAt.set(contractInstance.address.toString(), blockNumber);
35
+ });
30
36
  }
31
37
 
32
38
  deleteContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void> {
33
- return this.#contractInstances.delete(contractInstance.address.toString());
39
+ return this.db.transactionAsync(async () => {
40
+ await this.#contractInstances.delete(contractInstance.address.toString());
41
+ await this.#contractInstancePublishedAt.delete(contractInstance.address.toString());
42
+ });
34
43
  }
35
44
 
36
- getUpdateKey(contractAddress: AztecAddress, blockNumber: number, logIndex?: number): ContractInstanceUpdateKey {
45
+ getUpdateKey(contractAddress: AztecAddress, timestamp: UInt64, logIndex?: number): ContractInstanceUpdateKey {
37
46
  if (logIndex === undefined) {
38
- return [contractAddress.toString(), blockNumber];
47
+ return [contractAddress.toString(), timestamp.toString()];
39
48
  } else {
40
- return [contractAddress.toString(), blockNumber, logIndex];
49
+ return [contractAddress.toString(), timestamp.toString(), logIndex];
41
50
  }
42
51
  }
43
52
 
44
53
  addContractInstanceUpdate(
45
54
  contractInstanceUpdate: ContractInstanceUpdateWithAddress,
46
- blockNumber: number,
55
+ timestamp: UInt64,
47
56
  logIndex: number,
48
57
  ): Promise<void> {
49
58
  return this.#contractInstanceUpdates.set(
50
- this.getUpdateKey(contractInstanceUpdate.address, blockNumber, logIndex),
59
+ this.getUpdateKey(contractInstanceUpdate.address, timestamp, logIndex),
51
60
  new SerializableContractInstanceUpdate(contractInstanceUpdate).toBuffer(),
52
61
  );
53
62
  }
54
63
 
55
64
  deleteContractInstanceUpdate(
56
65
  contractInstanceUpdate: ContractInstanceUpdateWithAddress,
57
- blockNumber: number,
66
+ timestamp: UInt64,
58
67
  logIndex: number,
59
68
  ): Promise<void> {
60
- return this.#contractInstanceUpdates.delete(
61
- this.getUpdateKey(contractInstanceUpdate.address, blockNumber, logIndex),
62
- );
69
+ return this.#contractInstanceUpdates.delete(this.getUpdateKey(contractInstanceUpdate.address, timestamp, logIndex));
63
70
  }
64
71
 
65
- async getCurrentContractInstanceClassId(
66
- address: AztecAddress,
67
- blockNumber: number,
68
- originalClassId: Fr,
69
- ): Promise<Fr> {
70
- // We need to find the last update before the given block number
72
+ async getCurrentContractInstanceClassId(address: AztecAddress, timestamp: UInt64, originalClassId: Fr): Promise<Fr> {
73
+ // We need to find the last update before the given timestamp
71
74
  const queryResult = await this.#contractInstanceUpdates
72
75
  .valuesAsync({
73
76
  reverse: true,
74
- end: this.getUpdateKey(address, blockNumber + 1), // No update can match this key since it doesn't have a log index. We want the highest key <= blockNumber
77
+ start: this.getUpdateKey(address, 0n), // Make sure we only look at updates for this contract
78
+ end: this.getUpdateKey(address, timestamp + 1n), // No update can match this key since it doesn't have a log index. We want the highest key <= timestamp
75
79
  limit: 1,
76
80
  })
77
81
  .next();
@@ -81,7 +85,7 @@ export class ContractInstanceStore {
81
85
 
82
86
  const serializedUpdate = queryResult.value;
83
87
  const update = SerializableContractInstanceUpdate.fromBuffer(serializedUpdate);
84
- if (blockNumber < update.blockOfChange) {
88
+ if (timestamp < update.timestampOfChange) {
85
89
  return update.prevContractClassId.isZero() ? originalClassId : update.prevContractClassId;
86
90
  }
87
91
  return update.newContractClassId;
@@ -89,7 +93,7 @@ export class ContractInstanceStore {
89
93
 
90
94
  async getContractInstance(
91
95
  address: AztecAddress,
92
- blockNumber: number,
96
+ timestamp: UInt64,
93
97
  ): Promise<ContractInstanceWithAddress | undefined> {
94
98
  const contractInstance = await this.#contractInstances.getAsync(address.toString());
95
99
  if (!contractInstance) {
@@ -99,9 +103,13 @@ export class ContractInstanceStore {
99
103
  const instance = SerializableContractInstance.fromBuffer(contractInstance).withAddress(address);
100
104
  instance.currentContractClassId = await this.getCurrentContractInstanceClassId(
101
105
  address,
102
- blockNumber,
106
+ timestamp,
103
107
  instance.originalContractClassId,
104
108
  );
105
109
  return instance;
106
110
  }
111
+
112
+ getContractInstanceDeploymentBlockNumber(address: AztecAddress): Promise<number | undefined> {
113
+ return this.#contractInstancePublishedAt.getAsync(address.toString());
114
+ }
107
115
  }
@@ -1,69 +1,104 @@
1
+ import type { L1BlockId } from '@aztec/ethereum';
1
2
  import type { Fr } from '@aztec/foundation/fields';
2
3
  import { toArray } from '@aztec/foundation/iterable';
3
4
  import { createLogger } from '@aztec/foundation/log';
4
- import type { AztecAsyncKVStore, StoreSize } from '@aztec/kv-store';
5
+ import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
5
6
  import { FunctionSelector } from '@aztec/stdlib/abi';
6
7
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
- import type { InBlock, L2Block } from '@aztec/stdlib/block';
8
+ import { type L2Block, L2BlockHash, type ValidateBlockResult } from '@aztec/stdlib/block';
8
9
  import type {
9
10
  ContractClassPublic,
11
+ ContractDataSource,
10
12
  ContractInstanceUpdateWithAddress,
11
13
  ContractInstanceWithAddress,
12
14
  ExecutablePrivateFunctionWithMembershipProof,
13
- UnconstrainedFunctionWithMembershipProof,
15
+ UtilityFunctionWithMembershipProof,
14
16
  } from '@aztec/stdlib/contract';
15
17
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
16
18
  import { type LogFilter, PrivateLog, type TxScopedL2Log } from '@aztec/stdlib/logs';
17
- import type { InboxLeaf } from '@aztec/stdlib/messaging';
18
19
  import type { BlockHeader, TxHash, TxReceipt } from '@aztec/stdlib/tx';
20
+ import type { UInt64 } from '@aztec/stdlib/types';
21
+
22
+ import { join } from 'path';
19
23
 
20
24
  import type { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
21
- import type { DataRetrieval } from '../structs/data_retrieval.js';
22
- import type { L1Published } from '../structs/published.js';
25
+ import type { InboxMessage } from '../structs/inbox_message.js';
26
+ import type { PublishedL2Block } from '../structs/published.js';
23
27
  import { BlockStore } from './block_store.js';
24
28
  import { ContractClassStore } from './contract_class_store.js';
25
29
  import { ContractInstanceStore } from './contract_instance_store.js';
26
30
  import { LogStore } from './log_store.js';
27
31
  import { MessageStore } from './message_store.js';
28
- import { NullifierStore } from './nullifier_store.js';
32
+
33
+ export const ARCHIVER_DB_VERSION = 3;
34
+ export const MAX_FUNCTION_SIGNATURES = 1000;
35
+ export const MAX_FUNCTION_NAME_LEN = 256;
29
36
 
30
37
  /**
31
38
  * LMDB implementation of the ArchiverDataStore interface.
32
39
  */
33
- export class KVArchiverDataStore implements ArchiverDataStore {
34
- public static readonly SCHEMA_VERSION = 1;
40
+ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSource {
41
+ public static readonly SCHEMA_VERSION = ARCHIVER_DB_VERSION;
35
42
 
36
43
  #blockStore: BlockStore;
37
44
  #logStore: LogStore;
38
- #nullifierStore: NullifierStore;
39
45
  #messageStore: MessageStore;
40
46
  #contractClassStore: ContractClassStore;
41
47
  #contractInstanceStore: ContractInstanceStore;
48
+
42
49
  private functionNames = new Map<string, string>();
43
50
 
44
51
  #log = createLogger('archiver:data-store');
45
52
 
46
- constructor(private db: AztecAsyncKVStore, logsMaxPageSize: number = 1000) {
53
+ constructor(
54
+ private db: AztecAsyncKVStore,
55
+ logsMaxPageSize: number = 1000,
56
+ ) {
47
57
  this.#blockStore = new BlockStore(db);
48
58
  this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
49
59
  this.#messageStore = new MessageStore(db);
50
60
  this.#contractClassStore = new ContractClassStore(db);
51
61
  this.#contractInstanceStore = new ContractInstanceStore(db);
52
- this.#nullifierStore = new NullifierStore(db);
53
62
  }
54
63
 
55
- // TODO: These function names are in memory only as they are for development/debugging. They require the full contract
56
- // artifact supplied to the node out of band. This should be reviewed and potentially removed as part of
57
- // the node api cleanup process.
58
- getContractFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
64
+ public transactionAsync<T>(callback: () => Promise<T>): Promise<T> {
65
+ return this.db.transactionAsync(callback);
66
+ }
67
+
68
+ public getBlockNumber(): Promise<number> {
69
+ return this.getSynchedL2BlockNumber();
70
+ }
71
+
72
+ public async getContract(
73
+ address: AztecAddress,
74
+ maybeTimestamp?: UInt64,
75
+ ): Promise<ContractInstanceWithAddress | undefined> {
76
+ const [header] = await this.getBlockHeaders(await this.getBlockNumber(), 1);
77
+ const timestamp = maybeTimestamp ?? header!.globalVariables.timestamp;
78
+ return this.getContractInstance(address, timestamp);
79
+ }
80
+
81
+ public async backupTo(path: string, compress = true): Promise<string> {
82
+ await this.db.backupTo(path, compress);
83
+ return join(path, 'data.mdb');
84
+ }
85
+
86
+ public close() {
87
+ return this.db.close();
88
+ }
89
+
90
+ getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
59
91
  return Promise.resolve(this.functionNames.get(selector.toString()));
60
92
  }
61
93
 
62
- async registerContractFunctionSignatures(_address: AztecAddress, signatures: string[]): Promise<void> {
94
+ async registerContractFunctionSignatures(signatures: string[]): Promise<void> {
63
95
  for (const sig of signatures) {
96
+ if (this.functionNames.size > MAX_FUNCTION_SIGNATURES) {
97
+ return;
98
+ }
64
99
  try {
65
100
  const selector = await FunctionSelector.fromSignature(sig);
66
- this.functionNames.set(selector.toString(), sig.slice(0, sig.indexOf('(')));
101
+ this.functionNames.set(selector.toString(), sig.slice(0, sig.indexOf('(')).slice(0, MAX_FUNCTION_NAME_LEN));
67
102
  } catch {
68
103
  this.#log.warn(`Failed to parse signature: ${sig}. Ignoring`);
69
104
  }
@@ -78,9 +113,12 @@ export class KVArchiverDataStore implements ArchiverDataStore {
78
113
  return this.#contractClassStore.getContractClassIds();
79
114
  }
80
115
 
81
- async getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
82
- const contract = this.#contractInstanceStore.getContractInstance(address, await this.getSynchedL2BlockNumber());
83
- return contract;
116
+ getContractInstance(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined> {
117
+ return this.#contractInstanceStore.getContractInstance(address, timestamp);
118
+ }
119
+
120
+ getContractInstanceDeploymentBlockNumber(address: AztecAddress): Promise<number | undefined> {
121
+ return this.#contractInstanceStore.getContractInstanceDeploymentBlockNumber(address);
84
122
  }
85
123
 
86
124
  async addContractClasses(
@@ -108,36 +146,35 @@ export class KVArchiverDataStore implements ArchiverDataStore {
108
146
  addFunctions(
109
147
  contractClassId: Fr,
110
148
  privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
111
- unconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[],
149
+ utilityFunctions: UtilityFunctionWithMembershipProof[],
112
150
  ): Promise<boolean> {
113
- return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, unconstrainedFunctions);
151
+ return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
114
152
  }
115
153
 
116
- async addContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
117
- return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c)))).every(Boolean);
154
+ async addContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean> {
155
+ return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c, blockNumber)))).every(
156
+ Boolean,
157
+ );
118
158
  }
119
159
 
120
160
  async deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
121
161
  return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
122
162
  }
123
163
 
124
- async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], blockNumber: number): Promise<boolean> {
164
+ async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], timestamp: UInt64): Promise<boolean> {
125
165
  return (
126
166
  await Promise.all(
127
167
  data.map((update, logIndex) =>
128
- this.#contractInstanceStore.addContractInstanceUpdate(update, blockNumber, logIndex),
168
+ this.#contractInstanceStore.addContractInstanceUpdate(update, timestamp, logIndex),
129
169
  ),
130
170
  )
131
171
  ).every(Boolean);
132
172
  }
133
- async deleteContractInstanceUpdates(
134
- data: ContractInstanceUpdateWithAddress[],
135
- blockNumber: number,
136
- ): Promise<boolean> {
173
+ async deleteContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], timestamp: UInt64): Promise<boolean> {
137
174
  return (
138
175
  await Promise.all(
139
176
  data.map((update, logIndex) =>
140
- this.#contractInstanceStore.deleteContractInstanceUpdate(update, blockNumber, logIndex),
177
+ this.#contractInstanceStore.deleteContractInstanceUpdate(update, timestamp, logIndex),
141
178
  ),
142
179
  )
143
180
  ).every(Boolean);
@@ -148,8 +185,8 @@ export class KVArchiverDataStore implements ArchiverDataStore {
148
185
  * @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
149
186
  * @returns True if the operation is successful.
150
187
  */
151
- addBlocks(blocks: L1Published<L2Block>[]): Promise<boolean> {
152
- return this.#blockStore.addBlocks(blocks);
188
+ addBlocks(blocks: PublishedL2Block[], opts: { force?: boolean } = {}): Promise<boolean> {
189
+ return this.#blockStore.addBlocks(blocks, opts);
153
190
  }
154
191
 
155
192
  /**
@@ -163,6 +200,18 @@ export class KVArchiverDataStore implements ArchiverDataStore {
163
200
  return this.#blockStore.unwindBlocks(from, blocksToUnwind);
164
201
  }
165
202
 
203
+ getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
204
+ return this.#blockStore.getBlock(number);
205
+ }
206
+
207
+ getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
208
+ return this.#blockStore.getBlockByHash(L2BlockHash.fromField(blockHash));
209
+ }
210
+
211
+ getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
212
+ return this.#blockStore.getBlockByArchive(archive);
213
+ }
214
+
166
215
  /**
167
216
  * Gets up to `limit` amount of L2 blocks starting from `from`.
168
217
  *
@@ -170,7 +219,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
170
219
  * @param limit - The number of blocks to return.
171
220
  * @returns The requested L2 blocks
172
221
  */
173
- getBlocks(start: number, limit: number): Promise<L1Published<L2Block>[]> {
222
+ getPublishedBlocks(start: number, limit: number): Promise<PublishedL2Block[]> {
174
223
  return toArray(this.#blockStore.getBlocks(start, limit));
175
224
  }
176
225
 
@@ -185,10 +234,18 @@ export class KVArchiverDataStore implements ArchiverDataStore {
185
234
  return toArray(this.#blockStore.getBlockHeaders(start, limit));
186
235
  }
187
236
 
237
+ getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
238
+ return this.#blockStore.getBlockHeaderByHash(L2BlockHash.fromField(blockHash));
239
+ }
240
+
241
+ getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
242
+ return this.#blockStore.getBlockHeaderByArchive(archive);
243
+ }
244
+
188
245
  /**
189
246
  * Gets a tx effect.
190
- * @param txHash - The txHash of the tx corresponding to the tx effect.
191
- * @returns The requested tx effect (or undefined if not found).
247
+ * @param txHash - The hash of the tx corresponding to the tx effect.
248
+ * @returns The requested tx effect with block info (or undefined if not found).
192
249
  */
193
250
  getTxEffect(txHash: TxHash) {
194
251
  return this.#blockStore.getTxEffect(txHash);
@@ -216,33 +273,19 @@ export class KVArchiverDataStore implements ArchiverDataStore {
216
273
  return this.#logStore.deleteLogs(blocks);
217
274
  }
218
275
 
219
- /**
220
- * Append new nullifiers to the store's list.
221
- * @param blocks - The blocks for which to add the nullifiers.
222
- * @returns True if the operation is successful.
223
- */
224
- addNullifiers(blocks: L2Block[]): Promise<boolean> {
225
- return this.#nullifierStore.addNullifiers(blocks);
226
- }
227
-
228
- deleteNullifiers(blocks: L2Block[]): Promise<boolean> {
229
- return this.#nullifierStore.deleteNullifiers(blocks);
230
- }
231
-
232
- findNullifiersIndexesWithBlock(blockNumber: number, nullifiers: Fr[]): Promise<(InBlock<bigint> | undefined)[]> {
233
- return this.#nullifierStore.findNullifiersIndexesWithBlock(blockNumber, nullifiers);
234
- }
235
-
236
276
  getTotalL1ToL2MessageCount(): Promise<bigint> {
237
277
  return this.#messageStore.getTotalL1ToL2MessageCount();
238
278
  }
239
279
 
280
+ getLastL1ToL2Message(): Promise<InboxMessage | undefined> {
281
+ return this.#messageStore.getLastMessage();
282
+ }
283
+
240
284
  /**
241
285
  * Append L1 to L2 messages to the store.
242
- * @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
243
- * @returns True if the operation is successful.
286
+ * @param messages - The L1 to L2 messages to be added to the store.
244
287
  */
245
- addL1ToL2Messages(messages: DataRetrieval<InboxLeaf>): Promise<boolean> {
288
+ addL1ToL2Messages(messages: InboxMessage[]): Promise<void> {
246
289
  return this.#messageStore.addL1ToL2Messages(messages);
247
290
  }
248
291
 
@@ -260,7 +303,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
260
303
  * @param blockNumber - L2 block number to get messages for.
261
304
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
262
305
  */
263
- getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
306
+ getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
264
307
  return this.#messageStore.getL1ToL2Messages(blockNumber);
265
308
  }
266
309
 
@@ -277,12 +320,13 @@ export class KVArchiverDataStore implements ArchiverDataStore {
277
320
  /**
278
321
  * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
279
322
  * @param tags - The tags to filter the logs by.
323
+ * @param logsPerTag - How many logs to return per tag. Default returns everything
280
324
  * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
281
325
  * that tag.
282
326
  */
283
- getLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]> {
327
+ getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
284
328
  try {
285
- return this.#logStore.getLogsByTags(tags);
329
+ return this.#logStore.getLogsByTags(tags, logsPerTag);
286
330
  } catch (err) {
287
331
  return Promise.reject(err);
288
332
  }
@@ -334,8 +378,8 @@ export class KVArchiverDataStore implements ArchiverDataStore {
334
378
  await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
335
379
  }
336
380
 
337
- async setMessageSynchedL1BlockNumber(l1BlockNumber: bigint) {
338
- await this.#messageStore.setSynchedL1BlockNumber(l1BlockNumber);
381
+ async setMessageSynchedL1Block(l1Block: L1BlockId) {
382
+ await this.#messageStore.setSynchedL1Block(l1Block);
339
383
  }
340
384
 
341
385
  /**
@@ -344,7 +388,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
344
388
  async getSynchPoint(): Promise<ArchiverL1SynchPoint> {
345
389
  const [blocksSynchedTo, messagesSynchedTo] = await Promise.all([
346
390
  this.#blockStore.getSynchedL1BlockNumber(),
347
- this.#messageStore.getSynchedL1BlockNumber(),
391
+ this.#messageStore.getSynchedL1Block(),
348
392
  ]);
349
393
  return {
350
394
  blocksSynchedTo,
@@ -355,4 +399,24 @@ export class KVArchiverDataStore implements ArchiverDataStore {
355
399
  public estimateSize(): Promise<StoreSize> {
356
400
  return this.db.estimateSize();
357
401
  }
402
+
403
+ public rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number): Promise<void> {
404
+ return this.#messageStore.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
405
+ }
406
+
407
+ public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
408
+ return this.#messageStore.iterateL1ToL2Messages(range);
409
+ }
410
+
411
+ public removeL1ToL2Messages(startIndex: bigint): Promise<void> {
412
+ return this.#messageStore.removeL1ToL2Messages(startIndex);
413
+ }
414
+
415
+ public getPendingChainValidationStatus(): Promise<ValidateBlockResult | undefined> {
416
+ return this.#blockStore.getPendingChainValidationStatus();
417
+ }
418
+
419
+ public setPendingChainValidationStatus(status: ValidateBlockResult | undefined): Promise<void> {
420
+ return this.#blockStore.setPendingChainValidationStatus(status);
421
+ }
358
422
  }