@aztec/archiver 0.0.0-test.1 → 0.0.1-commit.5476d83

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 (110) hide show
  1. package/README.md +27 -6
  2. package/dest/archiver/archiver.d.ts +147 -57
  3. package/dest/archiver/archiver.d.ts.map +1 -1
  4. package/dest/archiver/archiver.js +841 -333
  5. package/dest/archiver/archiver_store.d.ts +85 -50
  6. package/dest/archiver/archiver_store.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
  8. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  9. package/dest/archiver/archiver_store_test_suite.js +708 -213
  10. package/dest/archiver/config.d.ts +5 -21
  11. package/dest/archiver/config.d.ts.map +1 -1
  12. package/dest/archiver/config.js +21 -12
  13. package/dest/archiver/data_retrieval.d.ts +32 -27
  14. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  15. package/dest/archiver/data_retrieval.js +197 -94
  16. package/dest/archiver/errors.d.ts +9 -1
  17. package/dest/archiver/errors.d.ts.map +1 -1
  18. package/dest/archiver/errors.js +12 -0
  19. package/dest/archiver/index.d.ts +3 -4
  20. package/dest/archiver/index.d.ts.map +1 -1
  21. package/dest/archiver/index.js +1 -2
  22. package/dest/archiver/instrumentation.d.ts +12 -6
  23. package/dest/archiver/instrumentation.d.ts.map +1 -1
  24. package/dest/archiver/instrumentation.js +58 -17
  25. package/dest/archiver/kv_archiver_store/block_store.d.ts +48 -11
  26. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  27. package/dest/archiver/kv_archiver_store/block_store.js +216 -63
  28. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +3 -3
  29. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  30. package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -18
  31. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +11 -8
  32. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
  33. package/dest/archiver/kv_archiver_store/contract_instance_store.js +30 -16
  34. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +50 -35
  35. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  36. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +88 -46
  37. package/dest/archiver/kv_archiver_store/log_store.d.ts +2 -2
  38. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  39. package/dest/archiver/kv_archiver_store/log_store.js +18 -46
  40. package/dest/archiver/kv_archiver_store/message_store.d.ts +23 -17
  41. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  42. package/dest/archiver/kv_archiver_store/message_store.js +150 -48
  43. package/dest/archiver/structs/data_retrieval.d.ts +1 -1
  44. package/dest/archiver/structs/inbox_message.d.ts +15 -0
  45. package/dest/archiver/structs/inbox_message.d.ts.map +1 -0
  46. package/dest/archiver/structs/inbox_message.js +38 -0
  47. package/dest/archiver/structs/published.d.ts +3 -11
  48. package/dest/archiver/structs/published.d.ts.map +1 -1
  49. package/dest/archiver/structs/published.js +1 -1
  50. package/dest/archiver/validation.d.ts +17 -0
  51. package/dest/archiver/validation.d.ts.map +1 -0
  52. package/dest/archiver/validation.js +98 -0
  53. package/dest/factory.d.ts +8 -13
  54. package/dest/factory.d.ts.map +1 -1
  55. package/dest/factory.js +18 -49
  56. package/dest/index.d.ts +2 -2
  57. package/dest/index.d.ts.map +1 -1
  58. package/dest/index.js +1 -1
  59. package/dest/rpc/index.d.ts +2 -3
  60. package/dest/rpc/index.d.ts.map +1 -1
  61. package/dest/rpc/index.js +1 -4
  62. package/dest/test/index.d.ts +1 -1
  63. package/dest/test/mock_archiver.d.ts +2 -2
  64. package/dest/test/mock_archiver.d.ts.map +1 -1
  65. package/dest/test/mock_l1_to_l2_message_source.d.ts +5 -3
  66. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  67. package/dest/test/mock_l1_to_l2_message_source.js +14 -1
  68. package/dest/test/mock_l2_block_source.d.ts +38 -10
  69. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  70. package/dest/test/mock_l2_block_source.js +119 -8
  71. package/dest/test/mock_structs.d.ts +9 -0
  72. package/dest/test/mock_structs.d.ts.map +1 -0
  73. package/dest/test/mock_structs.js +37 -0
  74. package/package.json +28 -30
  75. package/src/archiver/archiver.ts +1087 -410
  76. package/src/archiver/archiver_store.ts +97 -55
  77. package/src/archiver/archiver_store_test_suite.ts +664 -210
  78. package/src/archiver/config.ts +28 -41
  79. package/src/archiver/data_retrieval.ts +279 -125
  80. package/src/archiver/errors.ts +21 -0
  81. package/src/archiver/index.ts +2 -3
  82. package/src/archiver/instrumentation.ts +77 -22
  83. package/src/archiver/kv_archiver_store/block_store.ts +270 -72
  84. package/src/archiver/kv_archiver_store/contract_class_store.ts +13 -23
  85. package/src/archiver/kv_archiver_store/contract_instance_store.ts +35 -27
  86. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +127 -63
  87. package/src/archiver/kv_archiver_store/log_store.ts +24 -62
  88. package/src/archiver/kv_archiver_store/message_store.ts +209 -53
  89. package/src/archiver/structs/inbox_message.ts +41 -0
  90. package/src/archiver/structs/published.ts +2 -11
  91. package/src/archiver/validation.ts +124 -0
  92. package/src/factory.ts +24 -66
  93. package/src/index.ts +1 -1
  94. package/src/rpc/index.ts +1 -5
  95. package/src/test/mock_archiver.ts +1 -1
  96. package/src/test/mock_l1_to_l2_message_source.ts +14 -3
  97. package/src/test/mock_l2_block_source.ts +158 -13
  98. package/src/test/mock_structs.ts +49 -0
  99. package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +0 -12
  100. package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +0 -1
  101. package/dest/archiver/kv_archiver_store/nullifier_store.js +0 -73
  102. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +0 -23
  103. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +0 -1
  104. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +0 -49
  105. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +0 -175
  106. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +0 -1
  107. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +0 -636
  108. package/src/archiver/kv_archiver_store/nullifier_store.ts +0 -97
  109. package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +0 -61
  110. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +0 -801
@@ -1,20 +1,23 @@
1
1
  import { toArray } from '@aztec/foundation/iterable';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { FunctionSelector } from '@aztec/stdlib/abi';
4
+ import { L2BlockHash } from '@aztec/stdlib/block';
5
+ import { join } from 'path';
4
6
  import { BlockStore } from './block_store.js';
5
7
  import { ContractClassStore } from './contract_class_store.js';
6
8
  import { ContractInstanceStore } from './contract_instance_store.js';
7
9
  import { LogStore } from './log_store.js';
8
10
  import { MessageStore } from './message_store.js';
9
- import { NullifierStore } from './nullifier_store.js';
11
+ export const ARCHIVER_DB_VERSION = 3;
12
+ export const MAX_FUNCTION_SIGNATURES = 1000;
13
+ export const MAX_FUNCTION_NAME_LEN = 256;
10
14
  /**
11
15
  * LMDB implementation of the ArchiverDataStore interface.
12
16
  */ export class KVArchiverDataStore {
13
17
  db;
14
- static SCHEMA_VERSION = 1;
18
+ static SCHEMA_VERSION = ARCHIVER_DB_VERSION;
15
19
  #blockStore;
16
20
  #logStore;
17
- #nullifierStore;
18
21
  #messageStore;
19
22
  #contractClassStore;
20
23
  #contractInstanceStore;
@@ -29,19 +32,36 @@ import { NullifierStore } from './nullifier_store.js';
29
32
  this.#messageStore = new MessageStore(db);
30
33
  this.#contractClassStore = new ContractClassStore(db);
31
34
  this.#contractInstanceStore = new ContractInstanceStore(db);
32
- this.#nullifierStore = new NullifierStore(db);
33
35
  }
34
- // TODO: These function names are in memory only as they are for development/debugging. They require the full contract
35
- // artifact supplied to the node out of band. This should be reviewed and potentially removed as part of
36
- // the node api cleanup process.
37
- getContractFunctionName(_address, selector) {
36
+ transactionAsync(callback) {
37
+ return this.db.transactionAsync(callback);
38
+ }
39
+ getBlockNumber() {
40
+ return this.getSynchedL2BlockNumber();
41
+ }
42
+ async getContract(address, maybeTimestamp) {
43
+ const [header] = await this.getBlockHeaders(await this.getBlockNumber(), 1);
44
+ const timestamp = maybeTimestamp ?? header.globalVariables.timestamp;
45
+ return this.getContractInstance(address, timestamp);
46
+ }
47
+ async backupTo(path, compress = true) {
48
+ await this.db.backupTo(path, compress);
49
+ return join(path, 'data.mdb');
50
+ }
51
+ close() {
52
+ return this.db.close();
53
+ }
54
+ getDebugFunctionName(_address, selector) {
38
55
  return Promise.resolve(this.functionNames.get(selector.toString()));
39
56
  }
40
- async registerContractFunctionSignatures(_address, signatures) {
57
+ async registerContractFunctionSignatures(signatures) {
41
58
  for (const sig of signatures){
59
+ if (this.functionNames.size > MAX_FUNCTION_SIGNATURES) {
60
+ return;
61
+ }
42
62
  try {
43
63
  const selector = await FunctionSelector.fromSignature(sig);
44
- this.functionNames.set(selector.toString(), sig.slice(0, sig.indexOf('(')));
64
+ this.functionNames.set(selector.toString(), sig.slice(0, sig.indexOf('(')).slice(0, MAX_FUNCTION_NAME_LEN));
45
65
  } catch {
46
66
  this.#log.warn(`Failed to parse signature: ${sig}. Ignoring`);
47
67
  }
@@ -53,9 +73,11 @@ import { NullifierStore } from './nullifier_store.js';
53
73
  getContractClassIds() {
54
74
  return this.#contractClassStore.getContractClassIds();
55
75
  }
56
- async getContractInstance(address) {
57
- const contract = this.#contractInstanceStore.getContractInstance(address, await this.getSynchedL2BlockNumber());
58
- return contract;
76
+ getContractInstance(address, timestamp) {
77
+ return this.#contractInstanceStore.getContractInstance(address, timestamp);
78
+ }
79
+ getContractInstanceDeploymentBlockNumber(address) {
80
+ return this.#contractInstanceStore.getContractInstanceDeploymentBlockNumber(address);
59
81
  }
60
82
  async addContractClasses(data, bytecodeCommitments, blockNumber) {
61
83
  return (await Promise.all(data.map((c, i)=>this.#contractClassStore.addContractClass(c, bytecodeCommitments[i], blockNumber)))).every(Boolean);
@@ -66,27 +88,27 @@ import { NullifierStore } from './nullifier_store.js';
66
88
  getBytecodeCommitment(contractClassId) {
67
89
  return this.#contractClassStore.getBytecodeCommitment(contractClassId);
68
90
  }
69
- addFunctions(contractClassId, privateFunctions, unconstrainedFunctions) {
70
- return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, unconstrainedFunctions);
91
+ addFunctions(contractClassId, privateFunctions, utilityFunctions) {
92
+ return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
71
93
  }
72
- async addContractInstances(data, _blockNumber) {
73
- return (await Promise.all(data.map((c)=>this.#contractInstanceStore.addContractInstance(c)))).every(Boolean);
94
+ async addContractInstances(data, blockNumber) {
95
+ return (await Promise.all(data.map((c)=>this.#contractInstanceStore.addContractInstance(c, blockNumber)))).every(Boolean);
74
96
  }
75
97
  async deleteContractInstances(data, _blockNumber) {
76
98
  return (await Promise.all(data.map((c)=>this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
77
99
  }
78
- async addContractInstanceUpdates(data, blockNumber) {
79
- return (await Promise.all(data.map((update, logIndex)=>this.#contractInstanceStore.addContractInstanceUpdate(update, blockNumber, logIndex)))).every(Boolean);
100
+ async addContractInstanceUpdates(data, timestamp) {
101
+ return (await Promise.all(data.map((update, logIndex)=>this.#contractInstanceStore.addContractInstanceUpdate(update, timestamp, logIndex)))).every(Boolean);
80
102
  }
81
- async deleteContractInstanceUpdates(data, blockNumber) {
82
- return (await Promise.all(data.map((update, logIndex)=>this.#contractInstanceStore.deleteContractInstanceUpdate(update, blockNumber, logIndex)))).every(Boolean);
103
+ async deleteContractInstanceUpdates(data, timestamp) {
104
+ return (await Promise.all(data.map((update, logIndex)=>this.#contractInstanceStore.deleteContractInstanceUpdate(update, timestamp, logIndex)))).every(Boolean);
83
105
  }
84
106
  /**
85
107
  * Append new blocks to the store's list.
86
108
  * @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
87
109
  * @returns True if the operation is successful.
88
- */ addBlocks(blocks) {
89
- return this.#blockStore.addBlocks(blocks);
110
+ */ addBlocks(blocks, opts = {}) {
111
+ return this.#blockStore.addBlocks(blocks, opts);
90
112
  }
91
113
  /**
92
114
  * Unwinds blocks from the database
@@ -97,13 +119,22 @@ import { NullifierStore } from './nullifier_store.js';
97
119
  */ unwindBlocks(from, blocksToUnwind) {
98
120
  return this.#blockStore.unwindBlocks(from, blocksToUnwind);
99
121
  }
122
+ getPublishedBlock(number) {
123
+ return this.#blockStore.getBlock(number);
124
+ }
125
+ getPublishedBlockByHash(blockHash) {
126
+ return this.#blockStore.getBlockByHash(L2BlockHash.fromField(blockHash));
127
+ }
128
+ getPublishedBlockByArchive(archive) {
129
+ return this.#blockStore.getBlockByArchive(archive);
130
+ }
100
131
  /**
101
132
  * Gets up to `limit` amount of L2 blocks starting from `from`.
102
133
  *
103
134
  * @param start - Number of the first block to return (inclusive).
104
135
  * @param limit - The number of blocks to return.
105
136
  * @returns The requested L2 blocks
106
- */ getBlocks(start, limit) {
137
+ */ getPublishedBlocks(start, limit) {
107
138
  return toArray(this.#blockStore.getBlocks(start, limit));
108
139
  }
109
140
  /**
@@ -115,10 +146,16 @@ import { NullifierStore } from './nullifier_store.js';
115
146
  */ getBlockHeaders(start, limit) {
116
147
  return toArray(this.#blockStore.getBlockHeaders(start, limit));
117
148
  }
149
+ getBlockHeaderByHash(blockHash) {
150
+ return this.#blockStore.getBlockHeaderByHash(L2BlockHash.fromField(blockHash));
151
+ }
152
+ getBlockHeaderByArchive(archive) {
153
+ return this.#blockStore.getBlockHeaderByArchive(archive);
154
+ }
118
155
  /**
119
156
  * Gets a tx effect.
120
- * @param txHash - The txHash of the tx corresponding to the tx effect.
121
- * @returns The requested tx effect (or undefined if not found).
157
+ * @param txHash - The hash of the tx corresponding to the tx effect.
158
+ * @returns The requested tx effect with block info (or undefined if not found).
122
159
  */ getTxEffect(txHash) {
123
160
  return this.#blockStore.getTxEffect(txHash);
124
161
  }
@@ -139,26 +176,15 @@ import { NullifierStore } from './nullifier_store.js';
139
176
  deleteLogs(blocks) {
140
177
  return this.#logStore.deleteLogs(blocks);
141
178
  }
142
- /**
143
- * Append new nullifiers to the store's list.
144
- * @param blocks - The blocks for which to add the nullifiers.
145
- * @returns True if the operation is successful.
146
- */ addNullifiers(blocks) {
147
- return this.#nullifierStore.addNullifiers(blocks);
148
- }
149
- deleteNullifiers(blocks) {
150
- return this.#nullifierStore.deleteNullifiers(blocks);
151
- }
152
- findNullifiersIndexesWithBlock(blockNumber, nullifiers) {
153
- return this.#nullifierStore.findNullifiersIndexesWithBlock(blockNumber, nullifiers);
154
- }
155
179
  getTotalL1ToL2MessageCount() {
156
180
  return this.#messageStore.getTotalL1ToL2MessageCount();
157
181
  }
182
+ getLastL1ToL2Message() {
183
+ return this.#messageStore.getLastMessage();
184
+ }
158
185
  /**
159
186
  * Append L1 to L2 messages to the store.
160
- * @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
161
- * @returns True if the operation is successful.
187
+ * @param messages - The L1 to L2 messages to be added to the store.
162
188
  */ addL1ToL2Messages(messages) {
163
189
  return this.#messageStore.addL1ToL2Messages(messages);
164
190
  }
@@ -187,11 +213,12 @@ import { NullifierStore } from './nullifier_store.js';
187
213
  /**
188
214
  * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
189
215
  * @param tags - The tags to filter the logs by.
216
+ * @param logsPerTag - How many logs to return per tag. Default returns everything
190
217
  * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
191
218
  * that tag.
192
- */ getLogsByTags(tags) {
219
+ */ getLogsByTags(tags, logsPerTag) {
193
220
  try {
194
- return this.#logStore.getLogsByTags(tags);
221
+ return this.#logStore.getLogsByTags(tags, logsPerTag);
195
222
  } catch (err) {
196
223
  return Promise.reject(err);
197
224
  }
@@ -233,15 +260,15 @@ import { NullifierStore } from './nullifier_store.js';
233
260
  async setBlockSynchedL1BlockNumber(l1BlockNumber) {
234
261
  await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
235
262
  }
236
- async setMessageSynchedL1BlockNumber(l1BlockNumber) {
237
- await this.#messageStore.setSynchedL1BlockNumber(l1BlockNumber);
263
+ async setMessageSynchedL1Block(l1Block) {
264
+ await this.#messageStore.setSynchedL1Block(l1Block);
238
265
  }
239
266
  /**
240
267
  * Gets the last L1 block number processed by the archiver
241
268
  */ async getSynchPoint() {
242
269
  const [blocksSynchedTo, messagesSynchedTo] = await Promise.all([
243
270
  this.#blockStore.getSynchedL1BlockNumber(),
244
- this.#messageStore.getSynchedL1BlockNumber()
271
+ this.#messageStore.getSynchedL1Block()
245
272
  ]);
246
273
  return {
247
274
  blocksSynchedTo,
@@ -251,4 +278,19 @@ import { NullifierStore } from './nullifier_store.js';
251
278
  estimateSize() {
252
279
  return this.db.estimateSize();
253
280
  }
281
+ rollbackL1ToL2MessagesToL2Block(targetBlockNumber) {
282
+ return this.#messageStore.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
283
+ }
284
+ iterateL1ToL2Messages(range = {}) {
285
+ return this.#messageStore.iterateL1ToL2Messages(range);
286
+ }
287
+ removeL1ToL2Messages(startIndex) {
288
+ return this.#messageStore.removeL1ToL2Messages(startIndex);
289
+ }
290
+ getPendingChainValidationStatus() {
291
+ return this.#blockStore.getPendingChainValidationStatus();
292
+ }
293
+ setPendingChainValidationStatus(status) {
294
+ return this.#blockStore.setPendingChainValidationStatus(status);
295
+ }
254
296
  }
@@ -32,7 +32,7 @@ export declare class LogStore {
32
32
  * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
33
33
  * that tag.
34
34
  */
35
- getLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]>;
35
+ getLogsByTags(tags: Fr[], limitPerTag?: number): Promise<TxScopedL2Log[][]>;
36
36
  /**
37
37
  * Gets public logs based on the provided filter.
38
38
  * @param filter - The filter to apply to the logs.
@@ -46,4 +46,4 @@ export declare class LogStore {
46
46
  */
47
47
  getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse>;
48
48
  }
49
- //# sourceMappingURL=log_store.d.ts.map
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nX3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXJjaGl2ZXIva3ZfYXJjaGl2ZXJfc3RvcmUvbG9nX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR25ELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sS0FBSyxFQUFFLDRCQUE0QixFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDM0csT0FBTyxFQUlMLEtBQUssU0FBUyxFQUVkLFVBQVUsRUFFVixhQUFhLEVBQ2QsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVuRDs7R0FFRztBQUNILHFCQUFhLFFBQVE7O0lBVWpCLE9BQU8sQ0FBQyxFQUFFO0lBQ1YsT0FBTyxDQUFDLFVBQVU7SUFGcEIsWUFDVSxFQUFFLEVBQUUsaUJBQWlCLEVBQ3JCLFVBQVUsRUFBRSxVQUFVLEVBQzlCLGVBQWUsR0FBRSxNQUFhLEVBUy9CO0lBZ0NEOzs7O09BSUc7SUFDSCxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FnRTNDO0lBRUQsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBeUI5QztJQUVEOzs7OztPQUtHO0lBQ0csY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FTeEU7SUFFRDs7Ozs7T0FLRztJQUNHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsV0FBVyxDQUFDLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBUWhGO0lBRUQ7Ozs7T0FJRztJQUNILGFBQWEsQ0FBQyxNQUFNLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQVEvRDtJQXVFRDs7OztPQUlHO0lBQ0gsb0JBQW9CLENBQUMsTUFBTSxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsNEJBQTRCLENBQUMsQ0FRN0U7Q0FxR0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"log_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/log_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC3G,OAAO,EAIL,KAAK,SAAS,EAEd,UAAU,EAEV,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,QAAQ;;IASP,OAAO,CAAC,EAAE;IAAqB,OAAO,CAAC,UAAU;gBAAzC,EAAE,EAAE,iBAAiB,EAAU,UAAU,EAAE,UAAU,EAAE,eAAe,GAAE,MAAa;IAsFzG;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAkE5C,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IA0B/C;;;;;OAKG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAWzE;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;IAO3D;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA+EhE;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,4BAA4B,CAAC;CA6G/E"}
1
+ {"version":3,"file":"log_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/log_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC3G,OAAO,EAIL,KAAK,SAAS,EAEd,UAAU,EAEV,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,QAAQ;;IAUjB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,UAAU;IAFpB,YACU,EAAE,EAAE,iBAAiB,EACrB,UAAU,EAAE,UAAU,EAC9B,eAAe,GAAE,MAAa,EAS/B;IAgCD;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAgE3C;IAED,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAyB9C;IAED;;;;;OAKG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CASxE;IAED;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAQhF;IAED;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQ/D;IAuED;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAQ7E;CAqGF"}
@@ -1,4 +1,4 @@
1
- import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX, PUBLIC_LOG_DATA_SIZE_IN_FIELDS } from '@aztec/constants';
1
+ import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX } from '@aztec/constants';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
4
4
  import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, PrivateLog, PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
@@ -25,53 +25,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
25
25
  this.#contractClassLogsByBlock = db.openMap('archiver_contract_class_logs_by_block');
26
26
  this.#logsMaxPageSize = logsMaxPageSize;
27
27
  }
28
- #extractTaggedLogsFromPrivate(block) {
28
+ #extractTaggedLogs(block) {
29
29
  const taggedLogs = new Map();
30
30
  const dataStartIndexForBlock = block.header.state.partial.noteHashTree.nextAvailableLeafIndex - block.body.txEffects.length * MAX_NOTE_HASHES_PER_TX;
31
31
  block.body.txEffects.forEach((txEffect, txIndex)=>{
32
32
  const txHash = txEffect.txHash;
33
33
  const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NOTE_HASHES_PER_TX;
34
- txEffect.privateLogs.forEach((log)=>{
34
+ txEffect.privateLogs.forEach((log, logIndex)=>{
35
35
  const tag = log.fields[0];
36
+ this.#log.debug(`Found private log with tag ${tag.toString()} in block ${block.number}`);
36
37
  const currentLogs = taggedLogs.get(tag.toString()) ?? [];
37
- currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, block.number, /* isFromPublic */ false, log.toBuffer()).toBuffer());
38
+ currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, log).toBuffer());
38
39
  taggedLogs.set(tag.toString(), currentLogs);
39
40
  });
40
- });
41
- return taggedLogs;
42
- }
43
- #extractTaggedLogsFromPublic(block) {
44
- const taggedLogs = new Map();
45
- const dataStartIndexForBlock = block.header.state.partial.noteHashTree.nextAvailableLeafIndex - block.body.txEffects.length * MAX_NOTE_HASHES_PER_TX;
46
- block.body.txEffects.forEach((txEffect, txIndex)=>{
47
- const txHash = txEffect.txHash;
48
- const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NOTE_HASHES_PER_TX;
49
- txEffect.publicLogs.forEach((log)=>{
50
- // Check that each log stores 2 lengths in its first field. If not, it's not a tagged log:
51
- const firstFieldBuf = log.log[0].toBuffer();
52
- // See macros/note/mod/ and see how finalization_log[0] is constructed, to understand this monstrosity. (It wasn't me).
53
- // Search the codebase for "disgusting encoding" to see other hardcoded instances of this encoding, that you might need to change if you ever find yourself here.
54
- if (!firstFieldBuf.subarray(0, 27).equals(Buffer.alloc(27)) || firstFieldBuf[29] !== 0) {
55
- // See parseLogFromPublic - the first field of a tagged log is 5 bytes structured:
56
- // [ publicLen[0], publicLen[1], 0, privateLen[0], privateLen[1]]
57
- this.#log.warn(`Skipping public log with invalid first field: ${log.log[0]}`);
58
- return;
59
- }
60
- // Check that the length values line up with the log contents
61
- const publicValuesLength = firstFieldBuf.subarray(-5).readUint16BE();
62
- const privateValuesLength = firstFieldBuf.subarray(-5).readUint16BE(3);
63
- // Add 1 for the first field holding lengths
64
- const totalLogLength = 1 + publicValuesLength + privateValuesLength;
65
- // Note that zeroes can be valid log values, so we can only assert that we do not go over the given length
66
- if (totalLogLength > PUBLIC_LOG_DATA_SIZE_IN_FIELDS || log.log.slice(totalLogLength).find((f)=>!f.isZero())) {
67
- this.#log.warn(`Skipping invalid tagged public log with first field: ${log.log[0]}`);
68
- return;
69
- }
70
- // The first elt stores lengths as above => tag is in fields[1]
71
- const tag = log.log[1];
72
- this.#log.debug(`Found tagged public log with tag ${tag.toString()} in block ${block.number}`);
41
+ txEffect.publicLogs.forEach((log, logIndex)=>{
42
+ const tag = log.fields[0];
43
+ this.#log.debug(`Found public log with tag ${tag.toString()} in block ${block.number}`);
73
44
  const currentLogs = taggedLogs.get(tag.toString()) ?? [];
74
- currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, block.number, /* isFromPublic */ true, log.toBuffer()).toBuffer());
45
+ currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, log).toBuffer());
75
46
  taggedLogs.set(tag.toString(), currentLogs);
76
47
  });
77
48
  });
@@ -82,16 +53,13 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
82
53
  * @param blocks - The blocks for which to add the logs.
83
54
  * @returns True if the operation is successful.
84
55
  */ addLogs(blocks) {
85
- const taggedLogsToAdd = blocks.flatMap((block)=>[
86
- this.#extractTaggedLogsFromPrivate(block),
87
- this.#extractTaggedLogsFromPublic(block)
88
- ]).reduce((acc, val)=>{
56
+ const taggedLogsToAdd = blocks.map((block)=>this.#extractTaggedLogs(block)).reduce((acc, val)=>{
89
57
  for (const [tag, logs] of val.entries()){
90
58
  const currentLogs = acc.get(tag) ?? [];
91
59
  acc.set(tag, currentLogs.concat(logs));
92
60
  }
93
61
  return acc;
94
- });
62
+ }, new Map());
95
63
  const tagsToUpdate = Array.from(taggedLogsToAdd.keys());
96
64
  return this.db.transactionAsync(async ()=>{
97
65
  const currentTaggedLogs = await Promise.all(tagsToUpdate.map(async (tag)=>({
@@ -137,7 +105,8 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
137
105
  await Promise.all(blocks.map((block)=>Promise.all([
138
106
  this.#privateLogsByBlock.delete(block.number),
139
107
  this.#publicLogsByBlock.delete(block.number),
140
- this.#logTagsByBlock.delete(block.number)
108
+ this.#logTagsByBlock.delete(block.number),
109
+ this.#contractClassLogsByBlock.delete(block.number)
141
110
  ])));
142
111
  await Promise.all(tagsToDelete.map((tag)=>this.#logsByTag.delete(tag.toString())));
143
112
  return true;
@@ -166,9 +135,12 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
166
135
  * @param tags - The tags to filter the logs by.
167
136
  * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
168
137
  * that tag.
169
- */ async getLogsByTags(tags) {
138
+ */ async getLogsByTags(tags, limitPerTag) {
139
+ if (limitPerTag !== undefined && limitPerTag <= 0) {
140
+ throw new TypeError('limitPerTag needs to be greater than 0');
141
+ }
170
142
  const logs = await Promise.all(tags.map((tag)=>this.#logsByTag.getAsync(tag.toString())));
171
- return logs.map((noteLogBuffers)=>noteLogBuffers?.map((noteLogBuffer)=>TxScopedL2Log.fromBuffer(noteLogBuffer)) ?? []);
143
+ return logs.map((logBuffers)=>logBuffers?.slice(0, limitPerTag).map((logBuffer)=>TxScopedL2Log.fromBuffer(logBuffer)) ?? []);
172
144
  }
173
145
  /**
174
146
  * Gets public logs based on the provided filter.
@@ -1,33 +1,39 @@
1
+ import type { L1BlockId } from '@aztec/ethereum';
1
2
  import { Fr } from '@aztec/foundation/fields';
2
- import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
- import { InboxLeaf } from '@aztec/stdlib/messaging';
4
- import type { DataRetrieval } from '../structs/data_retrieval.js';
5
- /**
6
- * LMDB implementation of the ArchiverDataStore interface.
7
- */
3
+ import { type AztecAsyncKVStore, type CustomRange } from '@aztec/kv-store';
4
+ import { type InboxMessage } from '../structs/inbox_message.js';
5
+ export declare class MessageStoreError extends Error {
6
+ readonly inboxMessage: InboxMessage;
7
+ constructor(message: string, inboxMessage: InboxMessage);
8
+ }
8
9
  export declare class MessageStore {
9
10
  #private;
10
11
  private db;
11
12
  constructor(db: AztecAsyncKVStore);
12
13
  getTotalL1ToL2MessageCount(): Promise<bigint>;
13
- /**
14
- * Gets the last L1 block number that emitted new messages.
15
- * @returns The last L1 block number processed
16
- */
17
- getSynchedL1BlockNumber(): Promise<bigint | undefined>;
18
- setSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<void>;
14
+ /** Gets the last L1 block synced. */
15
+ getSynchedL1Block(): Promise<L1BlockId | undefined>;
16
+ /** Sets the last L1 block synced */
17
+ setSynchedL1Block(l1Block: L1BlockId): Promise<void>;
19
18
  /**
20
19
  * Append L1 to L2 messages to the store.
21
- * @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
22
- * @returns True if the operation is successful.
20
+ * Requires new messages to be in order and strictly after the last message added.
21
+ * Throws if out of order messages are added or if the rolling hash is invalid.
23
22
  */
24
- addL1ToL2Messages(messages: DataRetrieval<InboxLeaf>): Promise<boolean>;
23
+ addL1ToL2Messages(messages: InboxMessage[]): Promise<void>;
25
24
  /**
26
25
  * Gets the L1 to L2 message index in the L1 to L2 message tree.
27
26
  * @param l1ToL2Message - The L1 to L2 message.
28
27
  * @returns The index of the L1 to L2 message in the L1 to L2 message tree (undefined if not found).
29
28
  */
30
29
  getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined>;
31
- getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]>;
30
+ getLastMessage(): Promise<InboxMessage | undefined>;
31
+ getL1ToL2Messages(blockNumber: number): Promise<Fr[]>;
32
+ iterateL1ToL2Messages(range?: CustomRange<bigint>): AsyncIterableIterator<InboxMessage>;
33
+ removeL1ToL2Messages(startIndex: bigint): Promise<void>;
34
+ rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number): Promise<void>;
35
+ private indexToKey;
36
+ private leafToIndexKey;
37
+ private increaseTotalMessageCount;
32
38
  }
33
- //# sourceMappingURL=message_store.d.ts.map
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZV9zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FyY2hpdmVyL2t2X2FyY2hpdmVyX3N0b3JlL21lc3NhZ2Vfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFakQsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBSTlDLE9BQU8sRUFDTCxLQUFLLGlCQUFpQixFQUd0QixLQUFLLFdBQVcsRUFFakIsTUFBTSxpQkFBaUIsQ0FBQztBQUd6QixPQUFPLEVBQ0wsS0FBSyxZQUFZLEVBSWxCLE1BQU0sNkJBQTZCLENBQUM7QUFFckMscUJBQWEsaUJBQWtCLFNBQVEsS0FBSzthQUd4QixZQUFZLEVBQUUsWUFBWTtJQUY1QyxZQUNFLE9BQU8sRUFBRSxNQUFNLEVBQ0MsWUFBWSxFQUFFLFlBQVksRUFJM0M7Q0FDRjtBQUVELHFCQUFhLFlBQVk7O0lBWVgsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUt4QztJQUVZLDBCQUEwQixJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FFekQ7SUFFRCxxQ0FBcUM7SUFDeEIsaUJBQWlCLElBQUksT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsQ0FRL0Q7SUFFRCxvQ0FBb0M7SUFDdkIsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBR2hFO0lBRUQ7Ozs7T0FJRztJQUNJLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBNkZoRTtJQUVEOzs7O09BSUc7SUFDSSxxQkFBcUIsQ0FBQyxhQUFhLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNFO0lBRVksY0FBYyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDLENBRy9EO0lBRVksaUJBQWlCLENBQUMsV0FBVyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FxQmpFO0lBRWEscUJBQXFCLENBQUMsS0FBSyxHQUFFLFdBQVcsQ0FBQyxNQUFNLENBQU0sR0FBRyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FLeEc7SUFFTSxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FnQjdEO0lBRU0sK0JBQStCLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FJL0U7SUFFRCxPQUFPLENBQUMsVUFBVTtJQUlsQixPQUFPLENBQUMsY0FBYztZQUlSLHlCQUF5QjtDQVN4QyJ9
@@ -1 +1 @@
1
- {"version":3,"file":"message_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/message_store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,iBAAiB,EAAsC,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE;;GAEG;AACH,qBAAa,YAAY;;IAUX,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,iBAAiB;IAOnC,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC;IAInD;;;OAGG;IACH,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAIhD,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBvE;;;;OAIG;IACH,qBAAqB,CAAC,aAAa,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAI/D,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC;CAqB5D"}
1
+ {"version":3,"file":"message_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/message_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAI9C,OAAO,EACL,KAAK,iBAAiB,EAGtB,KAAK,WAAW,EAEjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,6BAA6B,CAAC;AAErC,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,YAAY,EAAE,YAAY;IAF5C,YACE,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,YAAY,EAI3C;CACF;AAED,qBAAa,YAAY;;IAYX,OAAO,CAAC,EAAE;IAAtB,YAAoB,EAAE,EAAE,iBAAiB,EAKxC;IAEY,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC,CAEzD;IAED,qCAAqC;IACxB,iBAAiB,IAAI,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAQ/D;IAED,oCAAoC;IACvB,iBAAiB,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhE;IAED;;;;OAIG;IACI,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6FhE;IAED;;;;OAIG;IACI,qBAAqB,CAAC,aAAa,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3E;IAEY,cAAc,IAAI,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAG/D;IAEY,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAqBjE;IAEa,qBAAqB,CAAC,KAAK,GAAE,WAAW,CAAC,MAAM,CAAM,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAKxG;IAEM,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7D;IAEM,+BAA+B,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;IAED,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,cAAc;YAIR,yBAAyB;CASxC"}