@aztec/archiver 0.0.1-commit.1142ef1 → 0.0.1-commit.125b3452

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 (201) hide show
  1. package/README.md +156 -22
  2. package/dest/archiver.d.ts +139 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +733 -0
  5. package/dest/{archiver/config.d.ts → config.d.ts} +9 -1
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/{archiver/config.js → config.js} +9 -0
  8. package/dest/errors.d.ts +53 -0
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/errors.js +75 -0
  11. package/dest/factory.d.ts +8 -7
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +90 -8
  14. package/dest/index.d.ts +11 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +9 -3
  17. package/dest/interfaces.d.ts +9 -0
  18. package/dest/interfaces.d.ts.map +1 -0
  19. package/dest/interfaces.js +3 -0
  20. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.d.ts +1 -1
  21. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  22. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.js +35 -32
  23. package/dest/l1/calldata_retriever.d.ts +135 -0
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/l1/calldata_retriever.js +402 -0
  26. package/dest/l1/data_retrieval.d.ts +88 -0
  27. package/dest/l1/data_retrieval.d.ts.map +1 -0
  28. package/dest/{archiver/l1 → l1}/data_retrieval.js +54 -71
  29. package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
  30. package/dest/l1/debug_tx.d.ts.map +1 -0
  31. package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +5 -5
  32. package/dest/l1/spire_proposer.d.ts.map +1 -0
  33. package/dest/{archiver/l1 → l1}/spire_proposer.js +9 -17
  34. package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
  35. package/dest/l1/trace_tx.d.ts.map +1 -0
  36. package/dest/l1/types.d.ts +12 -0
  37. package/dest/l1/types.d.ts.map +1 -0
  38. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +6 -3
  39. package/dest/l1/validate_trace.d.ts.map +1 -0
  40. package/dest/{archiver/l1 → l1}/validate_trace.js +13 -9
  41. package/dest/modules/data_source_base.d.ts +89 -0
  42. package/dest/modules/data_source_base.d.ts.map +1 -0
  43. package/dest/modules/data_source_base.js +216 -0
  44. package/dest/modules/data_store_updater.d.ts +88 -0
  45. package/dest/modules/data_store_updater.d.ts.map +1 -0
  46. package/dest/modules/data_store_updater.js +342 -0
  47. package/dest/modules/instrumentation.d.ts +50 -0
  48. package/dest/modules/instrumentation.d.ts.map +1 -0
  49. package/dest/{archiver → modules}/instrumentation.js +36 -12
  50. package/dest/modules/l1_synchronizer.d.ts +72 -0
  51. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  52. package/dest/modules/l1_synchronizer.js +1144 -0
  53. package/dest/{archiver → modules}/validation.d.ts +1 -1
  54. package/dest/modules/validation.d.ts.map +1 -0
  55. package/dest/{archiver → modules}/validation.js +6 -0
  56. package/dest/store/block_store.d.ts +195 -0
  57. package/dest/store/block_store.d.ts.map +1 -0
  58. package/dest/{archiver/kv_archiver_store → store}/block_store.js +248 -101
  59. package/dest/store/contract_class_store.d.ts +18 -0
  60. package/dest/store/contract_class_store.d.ts.map +1 -0
  61. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +12 -8
  62. package/dest/store/contract_instance_store.d.ts +24 -0
  63. package/dest/store/contract_instance_store.d.ts.map +1 -0
  64. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  65. package/dest/store/kv_archiver_store.d.ts +367 -0
  66. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  67. package/dest/store/kv_archiver_store.js +481 -0
  68. package/dest/store/l2_tips_cache.d.ts +19 -0
  69. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  70. package/dest/store/l2_tips_cache.js +89 -0
  71. package/dest/store/log_store.d.ts +57 -0
  72. package/dest/store/log_store.d.ts.map +1 -0
  73. package/dest/{archiver/kv_archiver_store → store}/log_store.js +204 -92
  74. package/dest/store/message_store.d.ts +44 -0
  75. package/dest/store/message_store.d.ts.map +1 -0
  76. package/dest/{archiver/kv_archiver_store → store}/message_store.js +14 -1
  77. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  78. package/dest/structs/data_retrieval.d.ts.map +1 -0
  79. package/dest/structs/inbox_message.d.ts +15 -0
  80. package/dest/structs/inbox_message.d.ts.map +1 -0
  81. package/dest/{archiver/structs → structs}/published.d.ts +1 -1
  82. package/dest/structs/published.d.ts.map +1 -0
  83. package/dest/test/fake_l1_state.d.ts +202 -0
  84. package/dest/test/fake_l1_state.d.ts.map +1 -0
  85. package/dest/test/fake_l1_state.js +455 -0
  86. package/dest/test/index.d.ts +2 -1
  87. package/dest/test/index.d.ts.map +1 -1
  88. package/dest/test/index.js +4 -1
  89. package/dest/test/mock_archiver.d.ts +2 -2
  90. package/dest/test/mock_archiver.d.ts.map +1 -1
  91. package/dest/test/mock_archiver.js +3 -3
  92. package/dest/test/mock_l2_block_source.d.ts +38 -19
  93. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  94. package/dest/test/mock_l2_block_source.js +183 -77
  95. package/dest/test/mock_structs.d.ts +81 -3
  96. package/dest/test/mock_structs.d.ts.map +1 -1
  97. package/dest/test/mock_structs.js +152 -7
  98. package/dest/test/noop_l1_archiver.d.ts +26 -0
  99. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  100. package/dest/test/noop_l1_archiver.js +72 -0
  101. package/package.json +16 -17
  102. package/src/archiver.ts +487 -0
  103. package/src/{archiver/config.ts → config.ts} +11 -0
  104. package/src/{archiver/errors.ts → errors.ts} +52 -24
  105. package/src/factory.ts +141 -10
  106. package/src/index.ts +11 -3
  107. package/src/interfaces.ts +9 -0
  108. package/src/l1/README.md +55 -0
  109. package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +45 -33
  110. package/src/l1/calldata_retriever.ts +511 -0
  111. package/src/{archiver/l1 → l1}/data_retrieval.ts +75 -94
  112. package/src/{archiver/l1 → l1}/spire_proposer.ts +7 -15
  113. package/src/{archiver/l1 → l1}/validate_trace.ts +24 -6
  114. package/src/modules/data_source_base.ts +333 -0
  115. package/src/modules/data_store_updater.ts +464 -0
  116. package/src/{archiver → modules}/instrumentation.ts +46 -14
  117. package/src/modules/l1_synchronizer.ts +963 -0
  118. package/src/{archiver → modules}/validation.ts +5 -0
  119. package/src/{archiver/kv_archiver_store → store}/block_store.ts +309 -141
  120. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +12 -8
  121. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
  122. package/src/{archiver/kv_archiver_store → store}/kv_archiver_store.ts +294 -39
  123. package/src/store/l2_tips_cache.ts +89 -0
  124. package/src/{archiver/kv_archiver_store → store}/log_store.ts +308 -119
  125. package/src/{archiver/kv_archiver_store → store}/message_store.ts +20 -1
  126. package/src/test/fake_l1_state.ts +698 -0
  127. package/src/test/index.ts +4 -0
  128. package/src/test/mock_archiver.ts +4 -3
  129. package/src/test/mock_l2_block_source.ts +233 -93
  130. package/src/test/mock_structs.ts +283 -8
  131. package/src/test/noop_l1_archiver.ts +115 -0
  132. package/dest/archiver/archiver.d.ts +0 -307
  133. package/dest/archiver/archiver.d.ts.map +0 -1
  134. package/dest/archiver/archiver.js +0 -2102
  135. package/dest/archiver/archiver_store.d.ts +0 -315
  136. package/dest/archiver/archiver_store.d.ts.map +0 -1
  137. package/dest/archiver/archiver_store.js +0 -4
  138. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  139. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  140. package/dest/archiver/archiver_store_test_suite.js +0 -2770
  141. package/dest/archiver/config.d.ts.map +0 -1
  142. package/dest/archiver/errors.d.ts +0 -36
  143. package/dest/archiver/errors.d.ts.map +0 -1
  144. package/dest/archiver/errors.js +0 -54
  145. package/dest/archiver/index.d.ts +0 -7
  146. package/dest/archiver/index.d.ts.map +0 -1
  147. package/dest/archiver/index.js +0 -4
  148. package/dest/archiver/instrumentation.d.ts +0 -37
  149. package/dest/archiver/instrumentation.d.ts.map +0 -1
  150. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -164
  151. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  152. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  153. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  154. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  155. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  156. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -159
  157. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  158. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -316
  159. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -45
  160. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  161. package/dest/archiver/kv_archiver_store/message_store.d.ts +0 -40
  162. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  163. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  164. package/dest/archiver/l1/calldata_retriever.d.ts +0 -112
  165. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  166. package/dest/archiver/l1/calldata_retriever.js +0 -471
  167. package/dest/archiver/l1/data_retrieval.d.ts +0 -90
  168. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  169. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  170. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  171. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  172. package/dest/archiver/l1/types.d.ts +0 -12
  173. package/dest/archiver/l1/types.d.ts.map +0 -1
  174. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  175. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  176. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  177. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  178. package/dest/archiver/structs/published.d.ts.map +0 -1
  179. package/dest/archiver/validation.d.ts.map +0 -1
  180. package/dest/rpc/index.d.ts +0 -9
  181. package/dest/rpc/index.d.ts.map +0 -1
  182. package/dest/rpc/index.js +0 -15
  183. package/src/archiver/archiver.ts +0 -2265
  184. package/src/archiver/archiver_store.ts +0 -380
  185. package/src/archiver/archiver_store_test_suite.ts +0 -2842
  186. package/src/archiver/index.ts +0 -6
  187. package/src/archiver/l1/README.md +0 -98
  188. package/src/archiver/l1/calldata_retriever.ts +0 -641
  189. package/src/rpc/index.ts +0 -16
  190. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  191. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  192. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  193. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  194. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  195. /package/dest/{archiver/structs → structs}/published.js +0 -0
  196. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  197. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  198. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  199. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  200. /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
  201. /package/src/{archiver/structs → structs}/published.ts +0 -0
@@ -1,10 +1,14 @@
1
1
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
+ import { filterAsync } from '@aztec/foundation/collection';
3
4
  import { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { createLogger } from '@aztec/foundation/log';
5
6
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
6
- import { L2BlockHash } from '@aztec/stdlib/block';
7
+ import { BlockHash } from '@aztec/stdlib/block';
8
+ import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
7
9
  import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
10
+ import { TxHash } from '@aztec/stdlib/tx';
11
+ import { OutOfOrderLogInsertionError } from '../errors.js';
8
12
  /**
9
13
  * A store for logs
10
14
  */ export class LogStore {
@@ -95,60 +99,100 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
95
99
  publicTaggedLogs
96
100
  };
97
101
  }
98
- /**
99
- * Append new logs to the store's list.
100
- * @param blocks - The blocks for which to add the logs.
101
- * @returns True if the operation is successful.
102
- */ addLogs(blocks) {
103
- const { privateTaggedLogs, publicTaggedLogs } = this.#extractTaggedLogs(blocks);
102
+ async #addPrivateLogs(blocks) {
103
+ const newBlocks = await filterAsync(blocks, async (block)=>!await this.#privateLogKeysByBlock.hasAsync(block.number));
104
+ const { privateTaggedLogs } = this.#extractTaggedLogs(newBlocks);
104
105
  const keysOfPrivateLogsToUpdate = Array.from(privateTaggedLogs.keys());
105
- const keysOfPublicLogsToUpdate = Array.from(publicTaggedLogs.keys());
106
- return this.db.transactionAsync(async ()=>{
107
- const currentPrivateTaggedLogs = await Promise.all(keysOfPrivateLogsToUpdate.map(async (key)=>({
108
- tag: key,
109
- logBuffers: await this.#privateLogsByTag.getAsync(key)
110
- })));
111
- currentPrivateTaggedLogs.forEach((taggedLogBuffer)=>{
112
- if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
113
- privateTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(privateTaggedLogs.get(taggedLogBuffer.tag)));
106
+ const currentPrivateTaggedLogs = await Promise.all(keysOfPrivateLogsToUpdate.map(async (key)=>({
107
+ tag: key,
108
+ logBuffers: await this.#privateLogsByTag.getAsync(key)
109
+ })));
110
+ for (const taggedLogBuffer of currentPrivateTaggedLogs){
111
+ if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
112
+ const newLogs = privateTaggedLogs.get(taggedLogBuffer.tag);
113
+ if (newLogs.length === 0) {
114
+ continue;
114
115
  }
115
- });
116
- const currentPublicTaggedLogs = await Promise.all(keysOfPublicLogsToUpdate.map(async (key)=>({
117
- key,
118
- logBuffers: await this.#publicLogsByContractAndTag.getAsync(key)
119
- })));
120
- currentPublicTaggedLogs.forEach((taggedLogBuffer)=>{
121
- if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
122
- publicTaggedLogs.set(taggedLogBuffer.key, taggedLogBuffer.logBuffers.concat(publicTaggedLogs.get(taggedLogBuffer.key)));
116
+ const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1));
117
+ const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
118
+ if (lastExisting.blockNumber > firstNew.blockNumber) {
119
+ throw new OutOfOrderLogInsertionError('private', taggedLogBuffer.tag, lastExisting.blockNumber, firstNew.blockNumber);
123
120
  }
124
- });
125
- for (const block of blocks){
126
- const blockHash = await block.hash();
127
- const privateTagsInBlock = [];
128
- for (const [tag, logs] of privateTaggedLogs.entries()){
129
- await this.#privateLogsByTag.set(tag, logs);
130
- privateTagsInBlock.push(tag);
121
+ privateTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
122
+ }
123
+ }
124
+ for (const block of newBlocks){
125
+ const privateTagsInBlock = [];
126
+ for (const [tag, logs] of privateTaggedLogs.entries()){
127
+ await this.#privateLogsByTag.set(tag, logs);
128
+ privateTagsInBlock.push(tag);
129
+ }
130
+ await this.#privateLogKeysByBlock.set(block.number, privateTagsInBlock);
131
+ }
132
+ }
133
+ async #addPublicLogs(blocks) {
134
+ const newBlocks = await filterAsync(blocks, async (block)=>!await this.#publicLogKeysByBlock.hasAsync(block.number));
135
+ const { publicTaggedLogs } = this.#extractTaggedLogs(newBlocks);
136
+ const keysOfPublicLogsToUpdate = Array.from(publicTaggedLogs.keys());
137
+ const currentPublicTaggedLogs = await Promise.all(keysOfPublicLogsToUpdate.map(async (key)=>({
138
+ tag: key,
139
+ logBuffers: await this.#publicLogsByContractAndTag.getAsync(key)
140
+ })));
141
+ for (const taggedLogBuffer of currentPublicTaggedLogs){
142
+ if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
143
+ const newLogs = publicTaggedLogs.get(taggedLogBuffer.tag);
144
+ if (newLogs.length === 0) {
145
+ continue;
131
146
  }
132
- await this.#privateLogKeysByBlock.set(block.number, privateTagsInBlock);
133
- const publicKeysInBlock = [];
134
- for (const [key, logs] of publicTaggedLogs.entries()){
135
- await this.#publicLogsByContractAndTag.set(key, logs);
136
- publicKeysInBlock.push(key);
147
+ const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1));
148
+ const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
149
+ if (lastExisting.blockNumber > firstNew.blockNumber) {
150
+ throw new OutOfOrderLogInsertionError('public', taggedLogBuffer.tag, lastExisting.blockNumber, firstNew.blockNumber);
137
151
  }
138
- await this.#publicLogKeysByBlock.set(block.number, publicKeysInBlock);
139
- const publicLogsInBlock = block.body.txEffects.map((txEffect, txIndex)=>[
140
- numToUInt32BE(txIndex),
141
- numToUInt32BE(txEffect.publicLogs.length),
142
- txEffect.publicLogs.map((log)=>log.toBuffer())
143
- ].flat()).flat();
144
- const contractClassLogsInBlock = block.body.txEffects.map((txEffect, txIndex)=>[
145
- numToUInt32BE(txIndex),
146
- numToUInt32BE(txEffect.contractClassLogs.length),
147
- txEffect.contractClassLogs.map((log)=>log.toBuffer())
148
- ].flat()).flat();
149
- await this.#publicLogsByBlock.set(block.number, this.#packWithBlockHash(blockHash, publicLogsInBlock));
150
- await this.#contractClassLogsByBlock.set(block.number, this.#packWithBlockHash(blockHash, contractClassLogsInBlock));
152
+ publicTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
153
+ }
154
+ }
155
+ for (const block of newBlocks){
156
+ const blockHash = await block.hash();
157
+ const publicTagsInBlock = [];
158
+ for (const [tag, logs] of publicTaggedLogs.entries()){
159
+ await this.#publicLogsByContractAndTag.set(tag, logs);
160
+ publicTagsInBlock.push(tag);
151
161
  }
162
+ await this.#publicLogKeysByBlock.set(block.number, publicTagsInBlock);
163
+ const publicLogsInBlock = block.body.txEffects.map((txEffect, txIndex)=>[
164
+ numToUInt32BE(txIndex),
165
+ txEffect.txHash.toBuffer(),
166
+ numToUInt32BE(txEffect.publicLogs.length),
167
+ txEffect.publicLogs.map((log)=>log.toBuffer())
168
+ ].flat()).flat();
169
+ await this.#publicLogsByBlock.set(block.number, this.#packWithBlockHash(blockHash, publicLogsInBlock));
170
+ }
171
+ }
172
+ async #addContractClassLogs(blocks) {
173
+ const newBlocks = await filterAsync(blocks, async (block)=>!await this.#contractClassLogsByBlock.hasAsync(block.number));
174
+ for (const block of newBlocks){
175
+ const blockHash = await block.hash();
176
+ const contractClassLogsInBlock = block.body.txEffects.map((txEffect, txIndex)=>[
177
+ numToUInt32BE(txIndex),
178
+ txEffect.txHash.toBuffer(),
179
+ numToUInt32BE(txEffect.contractClassLogs.length),
180
+ txEffect.contractClassLogs.map((log)=>log.toBuffer())
181
+ ].flat()).flat();
182
+ await this.#contractClassLogsByBlock.set(block.number, this.#packWithBlockHash(blockHash, contractClassLogsInBlock));
183
+ }
184
+ }
185
+ /**
186
+ * Append new logs to the store's list.
187
+ * @param blocks - The blocks for which to add the logs.
188
+ * @returns True if the operation is successful.
189
+ */ addLogs(blocks) {
190
+ return this.db.transactionAsync(async ()=>{
191
+ await Promise.all([
192
+ this.#addPrivateLogs(blocks),
193
+ this.#addPublicLogs(blocks),
194
+ this.#addContractClassLogs(blocks)
195
+ ]);
152
196
  return true;
153
197
  });
154
198
  }
@@ -163,7 +207,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
163
207
  if (!blockHash) {
164
208
  throw new Error('Failed to read block hash from log entry buffer');
165
209
  }
166
- return L2BlockHash.fromField(blockHash);
210
+ return new BlockHash(blockHash);
167
211
  }
168
212
  deleteLogs(blocks) {
169
213
  return this.db.transactionAsync(async ()=>{
@@ -185,21 +229,54 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
185
229
  });
186
230
  }
187
231
  /**
188
- * Gets all private logs that match any of the `tags`. For each tag, an array of matching logs is returned. An empty
232
+ * Gets private logs that match any of the `tags`. For each tag, an array of matching logs is returned. An empty
189
233
  * array implies no logs match that tag.
190
- */ async getPrivateLogsByTags(tags) {
234
+ * @param tags - The tags to search for.
235
+ * @param page - The page number (0-indexed) for pagination.
236
+ * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
237
+ * @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
238
+ * MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
239
+ */ async getPrivateLogsByTags(tags, page = 0, upToBlockNumber) {
191
240
  const logs = await Promise.all(tags.map((tag)=>this.#privateLogsByTag.getAsync(tag.toString())));
192
- return logs.map((logBuffers)=>logBuffers?.map((logBuffer)=>TxScopedL2Log.fromBuffer(logBuffer)) ?? []);
241
+ const start = page * MAX_LOGS_PER_TAG;
242
+ const end = start + MAX_LOGS_PER_TAG;
243
+ return logs.map((logBuffers)=>{
244
+ const deserialized = logBuffers?.slice(start, end).map((buf)=>TxScopedL2Log.fromBuffer(buf)) ?? [];
245
+ if (upToBlockNumber !== undefined) {
246
+ const cutoff = deserialized.findIndex((log)=>log.blockNumber > upToBlockNumber);
247
+ if (cutoff !== -1) {
248
+ return deserialized.slice(0, cutoff);
249
+ }
250
+ }
251
+ return deserialized;
252
+ });
193
253
  }
194
254
  /**
195
- * Gets all public logs that match any of the `tags` from the specified contract. For each tag, an array of matching
255
+ * Gets public logs that match any of the `tags` from the specified contract. For each tag, an array of matching
196
256
  * logs is returned. An empty array implies no logs match that tag.
197
- */ async getPublicLogsByTagsFromContract(contractAddress, tags) {
257
+ * @param contractAddress - The contract address to search logs for.
258
+ * @param tags - The tags to search for.
259
+ * @param page - The page number (0-indexed) for pagination.
260
+ * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
261
+ * @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
262
+ * MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
263
+ */ async getPublicLogsByTagsFromContract(contractAddress, tags, page = 0, upToBlockNumber) {
198
264
  const logs = await Promise.all(tags.map((tag)=>{
199
265
  const key = `${contractAddress.toString()}_${tag.value.toString()}`;
200
266
  return this.#publicLogsByContractAndTag.getAsync(key);
201
267
  }));
202
- return logs.map((logBuffers)=>logBuffers?.map((logBuffer)=>TxScopedL2Log.fromBuffer(logBuffer)) ?? []);
268
+ const start = page * MAX_LOGS_PER_TAG;
269
+ const end = start + MAX_LOGS_PER_TAG;
270
+ return logs.map((logBuffers)=>{
271
+ const deserialized = logBuffers?.slice(start, end).map((buf)=>TxScopedL2Log.fromBuffer(buf)) ?? [];
272
+ if (upToBlockNumber !== undefined) {
273
+ const cutoff = deserialized.findIndex((log)=>log.blockNumber > upToBlockNumber);
274
+ if (cutoff !== -1) {
275
+ return deserialized.slice(0, cutoff);
276
+ }
277
+ }
278
+ return deserialized;
279
+ });
203
280
  }
204
281
  /**
205
282
  * Gets public logs based on the provided filter.
@@ -226,22 +303,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
226
303
  };
227
304
  }
228
305
  const buffer = await this.#publicLogsByBlock.getAsync(blockNumber) ?? Buffer.alloc(0);
229
- const publicLogsInBlock = [
230
- []
231
- ];
306
+ const publicLogsInBlock = [];
232
307
  const reader = new BufferReader(buffer);
233
308
  const blockHash = this.#unpackBlockHash(reader);
234
309
  while(reader.remainingBytes() > 0){
235
310
  const indexOfTx = reader.readNumber();
311
+ const txHash = reader.readObject(TxHash);
236
312
  const numLogsInTx = reader.readNumber();
237
- publicLogsInBlock[indexOfTx] = [];
313
+ publicLogsInBlock[indexOfTx] = {
314
+ txHash,
315
+ logs: []
316
+ };
238
317
  for(let i = 0; i < numLogsInTx; i++){
239
- publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
318
+ publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
240
319
  }
241
320
  }
242
- const txLogs = publicLogsInBlock[txIndex];
321
+ const txData = publicLogsInBlock[txIndex];
243
322
  const logs = [];
244
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
323
+ const maxLogsHit = this.#accumulatePublicLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
245
324
  return {
246
325
  logs,
247
326
  maxLogsHit
@@ -262,22 +341,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
262
341
  start,
263
342
  end
264
343
  })){
265
- const publicLogsInBlock = [
266
- []
267
- ];
344
+ const publicLogsInBlock = [];
268
345
  const reader = new BufferReader(logBuffer);
269
346
  const blockHash = this.#unpackBlockHash(reader);
270
347
  while(reader.remainingBytes() > 0){
271
348
  const indexOfTx = reader.readNumber();
349
+ const txHash = reader.readObject(TxHash);
272
350
  const numLogsInTx = reader.readNumber();
273
- publicLogsInBlock[indexOfTx] = [];
351
+ publicLogsInBlock[indexOfTx] = {
352
+ txHash,
353
+ logs: []
354
+ };
274
355
  for(let i = 0; i < numLogsInTx; i++){
275
- publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
356
+ publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
276
357
  }
277
358
  }
278
359
  for(let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < publicLogsInBlock.length; txIndex++){
279
- const txLogs = publicLogsInBlock[txIndex];
280
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
360
+ const txData = publicLogsInBlock[txIndex];
361
+ maxLogsHit = this.#accumulatePublicLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
281
362
  if (maxLogsHit) {
282
363
  this.#log.debug(`Max logs hit at block ${blockNumber}`);
283
364
  break loopOverBlocks;
@@ -314,22 +395,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
314
395
  };
315
396
  }
316
397
  const contractClassLogsBuffer = await this.#contractClassLogsByBlock.getAsync(blockNumber) ?? Buffer.alloc(0);
317
- const contractClassLogsInBlock = [
318
- []
319
- ];
398
+ const contractClassLogsInBlock = [];
320
399
  const reader = new BufferReader(contractClassLogsBuffer);
321
400
  const blockHash = this.#unpackBlockHash(reader);
322
401
  while(reader.remainingBytes() > 0){
323
402
  const indexOfTx = reader.readNumber();
403
+ const txHash = reader.readObject(TxHash);
324
404
  const numLogsInTx = reader.readNumber();
325
- contractClassLogsInBlock[indexOfTx] = [];
405
+ contractClassLogsInBlock[indexOfTx] = {
406
+ txHash,
407
+ logs: []
408
+ };
326
409
  for(let i = 0; i < numLogsInTx; i++){
327
- contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
410
+ contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
328
411
  }
329
412
  }
330
- const txLogs = contractClassLogsInBlock[txIndex];
413
+ const txData = contractClassLogsInBlock[txIndex];
331
414
  const logs = [];
332
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
415
+ const maxLogsHit = this.#accumulateContractClassLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
333
416
  return {
334
417
  logs,
335
418
  maxLogsHit
@@ -350,22 +433,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
350
433
  start,
351
434
  end
352
435
  })){
353
- const contractClassLogsInBlock = [
354
- []
355
- ];
436
+ const contractClassLogsInBlock = [];
356
437
  const reader = new BufferReader(logBuffer);
357
438
  const blockHash = this.#unpackBlockHash(reader);
358
439
  while(reader.remainingBytes() > 0){
359
440
  const indexOfTx = reader.readNumber();
441
+ const txHash = reader.readObject(TxHash);
360
442
  const numLogsInTx = reader.readNumber();
361
- contractClassLogsInBlock[indexOfTx] = [];
443
+ contractClassLogsInBlock[indexOfTx] = {
444
+ txHash,
445
+ logs: []
446
+ };
362
447
  for(let i = 0; i < numLogsInTx; i++){
363
- contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
448
+ contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
364
449
  }
365
450
  }
366
451
  for(let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++){
367
- const txLogs = contractClassLogsInBlock[txIndex];
368
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
452
+ const txData = contractClassLogsInBlock[txIndex];
453
+ maxLogsHit = this.#accumulateContractClassLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
369
454
  if (maxLogsHit) {
370
455
  this.#log.debug(`Max logs hit at block ${blockNumber}`);
371
456
  break loopOverBlocks;
@@ -377,19 +462,46 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
377
462
  maxLogsHit
378
463
  };
379
464
  }
380
- #accumulateLogs(results, blockNumber, blockHash, txIndex, txLogs, filter = {}) {
465
+ #accumulatePublicLogs(results, blockNumber, blockHash, txIndex, txHash, txLogs, filter = {}) {
466
+ if (filter.fromBlock && blockNumber < filter.fromBlock) {
467
+ return false;
468
+ }
469
+ if (filter.toBlock && blockNumber >= filter.toBlock) {
470
+ return false;
471
+ }
472
+ if (filter.txHash && !txHash.equals(filter.txHash)) {
473
+ return false;
474
+ }
381
475
  let maxLogsHit = false;
382
476
  let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
383
477
  for(; logIndex < txLogs.length; logIndex++){
384
478
  const log = txLogs[logIndex];
385
- if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
386
- if (log instanceof ContractClassLog) {
387
- results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
388
- } else if (log instanceof PublicLog) {
389
- results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
390
- } else {
391
- throw new Error('Unknown log type');
479
+ if ((!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) && (!filter.tag || log.fields[0]?.equals(filter.tag))) {
480
+ results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log));
481
+ if (results.length >= this.#logsMaxPageSize) {
482
+ maxLogsHit = true;
483
+ break;
392
484
  }
485
+ }
486
+ }
487
+ return maxLogsHit;
488
+ }
489
+ #accumulateContractClassLogs(results, blockNumber, blockHash, txIndex, txHash, txLogs, filter = {}) {
490
+ if (filter.fromBlock && blockNumber < filter.fromBlock) {
491
+ return false;
492
+ }
493
+ if (filter.toBlock && blockNumber >= filter.toBlock) {
494
+ return false;
495
+ }
496
+ if (filter.txHash && !txHash.equals(filter.txHash)) {
497
+ return false;
498
+ }
499
+ let maxLogsHit = false;
500
+ let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
501
+ for(; logIndex < txLogs.length; logIndex++){
502
+ const log = txLogs[logIndex];
503
+ if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
504
+ results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log));
393
505
  if (results.length >= this.#logsMaxPageSize) {
394
506
  maxLogsHit = true;
395
507
  break;
@@ -0,0 +1,44 @@
1
+ import type { L1BlockId } from '@aztec/ethereum/l1-types';
2
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ import { type AztecAsyncKVStore, type CustomRange } from '@aztec/kv-store';
5
+ import { type InboxMessage } from '../structs/inbox_message.js';
6
+ export declare class MessageStoreError extends Error {
7
+ readonly inboxMessage: InboxMessage;
8
+ constructor(message: string, inboxMessage: InboxMessage);
9
+ }
10
+ export declare class MessageStore {
11
+ #private;
12
+ private db;
13
+ constructor(db: AztecAsyncKVStore);
14
+ getTotalL1ToL2MessageCount(): Promise<bigint>;
15
+ /** Gets the last L1 block synced. */
16
+ getSynchedL1Block(): Promise<L1BlockId | undefined>;
17
+ /** Sets the last L1 block synced */
18
+ setSynchedL1Block(l1Block: L1BlockId): Promise<void>;
19
+ /**
20
+ * Append L1 to L2 messages to the store.
21
+ * Requires new messages to be in order and strictly after the last message added.
22
+ * Throws if out of order messages are added or if the rolling hash is invalid.
23
+ */
24
+ addL1ToL2Messages(messages: InboxMessage[]): Promise<void>;
25
+ /**
26
+ * Gets the L1 to L2 message index in the L1 to L2 message tree.
27
+ * @param l1ToL2Message - The L1 to L2 message.
28
+ * @returns The index of the L1 to L2 message in the L1 to L2 message tree (undefined if not found).
29
+ */
30
+ getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined>;
31
+ getLastMessage(): Promise<InboxMessage | undefined>;
32
+ /** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */
33
+ getInboxTreeInProgress(): Promise<bigint | undefined>;
34
+ /** Persists the inbox tree-in-progress checkpoint number from L1 state. */
35
+ setInboxTreeInProgress(value: bigint): Promise<void>;
36
+ getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]>;
37
+ iterateL1ToL2Messages(range?: CustomRange<bigint>): AsyncIterableIterator<InboxMessage>;
38
+ removeL1ToL2Messages(startIndex: bigint): Promise<void>;
39
+ rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise<void>;
40
+ private indexToKey;
41
+ private leafToIndexKey;
42
+ private increaseTotalMessageCount;
43
+ }
44
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZV9zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0b3JlL21lc3NhZ2Vfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFbkUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sRUFDTCxLQUFLLGlCQUFpQixFQUd0QixLQUFLLFdBQVcsRUFFakIsTUFBTSxpQkFBaUIsQ0FBQztBQUl6QixPQUFPLEVBQ0wsS0FBSyxZQUFZLEVBSWxCLE1BQU0sNkJBQTZCLENBQUM7QUFFckMscUJBQWEsaUJBQWtCLFNBQVEsS0FBSzthQUd4QixZQUFZLEVBQUUsWUFBWTtJQUY1QyxZQUNFLE9BQU8sRUFBRSxNQUFNLEVBQ0MsWUFBWSxFQUFFLFlBQVksRUFJM0M7Q0FDRjtBQUVELHFCQUFhLFlBQVk7O0lBY1gsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQU14QztJQUVZLDBCQUEwQixJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FFekQ7SUFFRCxxQ0FBcUM7SUFDeEIsaUJBQWlCLElBQUksT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsQ0FRL0Q7SUFFRCxvQ0FBb0M7SUFDdkIsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBR2hFO0lBRUQ7Ozs7T0FJRztJQUNJLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBNkZoRTtJQUVEOzs7O09BSUc7SUFDSSxxQkFBcUIsQ0FBQyxhQUFhLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNFO0lBRVksY0FBYyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDLENBRy9EO0lBRUQsaUdBQWlHO0lBQzFGLHNCQUFzQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNEO0lBRUQsMkVBQTJFO0lBQzlELHNCQUFzQixDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUVoRTtJQUVZLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQTRCaEY7SUFFYSxxQkFBcUIsQ0FBQyxLQUFLLEdBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBTSxHQUFHLHFCQUFxQixDQUFDLFlBQVksQ0FBQyxDQUt4RztJQUVNLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWdCN0Q7SUFFTSxrQ0FBa0MsQ0FBQyxzQkFBc0IsRUFBRSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWpHO0lBRUQsT0FBTyxDQUFDLFVBQVU7SUFJbEIsT0FBTyxDQUFDLGNBQWM7WUFJUix5QkFBeUI7Q0FTeEMifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message_store.d.ts","sourceRoot":"","sources":["../../src/store/message_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,EACL,KAAK,iBAAiB,EAGtB,KAAK,WAAW,EAEjB,MAAM,iBAAiB,CAAC;AAIzB,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;;IAcX,OAAO,CAAC,EAAE;IAAtB,YAAoB,EAAE,EAAE,iBAAiB,EAMxC;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;IAED,iGAAiG;IAC1F,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3D;IAED,2EAA2E;IAC9D,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;IAEY,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CA4BhF;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,kCAAkC,CAAC,sBAAsB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG;IAED,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,cAAc;YAIR,yBAAyB;CASxC"}
@@ -5,6 +5,7 @@ import { createLogger } from '@aztec/foundation/log';
5
5
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
6
6
  import { mapRange } from '@aztec/kv-store';
7
7
  import { InboxLeaf } from '@aztec/stdlib/messaging';
8
+ import { L1ToL2MessagesNotReadyError } from '../errors.js';
8
9
  import { deserializeInboxMessage, serializeInboxMessage, updateRollingHash } from '../structs/inbox_message.js';
9
10
  export class MessageStoreError extends Error {
10
11
  inboxMessage;
@@ -19,6 +20,7 @@ export class MessageStore {
19
20
  /** Maps from hex-stringified message leaf to its index */ #l1ToL2MessageIndices;
20
21
  /** Stores L1 block number and hash of the L1 synchpoint */ #lastSynchedL1Block;
21
22
  /** Stores total messages stored */ #totalMessageCount;
23
+ /** Stores the checkpoint number whose message tree is currently being filled on L1. */ #inboxTreeInProgress;
22
24
  #log;
23
25
  constructor(db){
24
26
  this.db = db;
@@ -27,6 +29,7 @@ export class MessageStore {
27
29
  this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices');
28
30
  this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_id');
29
31
  this.#totalMessageCount = db.openSingleton('archiver_l1_to_l2_message_count');
32
+ this.#inboxTreeInProgress = db.openSingleton('archiver_inbox_tree_in_progress');
30
33
  }
31
34
  async getTotalL1ToL2MessageCount() {
32
35
  return await this.#totalMessageCount.getAsync() ?? 0n;
@@ -87,7 +90,7 @@ export class MessageStore {
87
90
  if (lastMessage && message.checkpointNumber === lastMessage.checkpointNumber && message.index !== lastMessage.index + 1n) {
88
91
  throw new MessageStoreError(`Missing prior message for incoming L1 to L2 message ${message.leaf.toString()} ` + `with index ${message.index}`, message);
89
92
  }
90
- // Check the first message in a block has the correct index.
93
+ // Check the first message in a checkpoint has the correct index.
91
94
  if ((!lastMessage || message.checkpointNumber > lastMessage.checkpointNumber) && message.index !== expectedStart) {
92
95
  throw new MessageStoreError(`Message ${message.leaf.toString()} for checkpoint ${message.checkpointNumber} has wrong index ` + `${message.index} (expected ${expectedStart})`, message);
93
96
  }
@@ -124,7 +127,17 @@ export class MessageStore {
124
127
  }));
125
128
  return msg ? deserializeInboxMessage(msg) : undefined;
126
129
  }
130
+ /** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */ getInboxTreeInProgress() {
131
+ return this.#inboxTreeInProgress.getAsync();
132
+ }
133
+ /** Persists the inbox tree-in-progress checkpoint number from L1 state. */ async setInboxTreeInProgress(value) {
134
+ await this.#inboxTreeInProgress.set(value);
135
+ }
127
136
  async getL1ToL2Messages(checkpointNumber) {
137
+ const treeInProgress = await this.#inboxTreeInProgress.getAsync();
138
+ if (treeInProgress !== undefined && BigInt(checkpointNumber) >= treeInProgress) {
139
+ throw new L1ToL2MessagesNotReadyError(checkpointNumber, treeInProgress);
140
+ }
128
141
  const messages = [];
129
142
  const [startIndex, endIndex] = InboxLeaf.indexRangeForCheckpoint(checkpointNumber);
130
143
  let lastIndex = startIndex - 1n;
@@ -24,4 +24,4 @@ export type SingletonDataRetrieval<T> = {
24
24
  */
25
25
  retrievedData: T;
26
26
  };
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV9yZXRyaWV2YWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcmNoaXZlci9zdHJ1Y3RzL2RhdGFfcmV0cmlldmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxNQUFNLGFBQWEsQ0FBQyxDQUFDLElBQUk7SUFDN0I7O09BRUc7SUFDSCwwQkFBMEIsRUFBRSxNQUFNLENBQUM7SUFDbkM7O09BRUc7SUFDSCxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7Q0FDcEIsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxNQUFNLHNCQUFzQixDQUFDLENBQUMsSUFBSTtJQUN0Qzs7T0FFRztJQUNILDBCQUEwQixFQUFFLE1BQU0sQ0FBQztJQUNuQzs7T0FFRztJQUNILGFBQWEsRUFBRSxDQUFDLENBQUM7Q0FDbEIsQ0FBQyJ9
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV9yZXRyaWV2YWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdHJ1Y3RzL2RhdGFfcmV0cmlldmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxNQUFNLGFBQWEsQ0FBQyxDQUFDLElBQUk7SUFDN0I7O09BRUc7SUFDSCwwQkFBMEIsRUFBRSxNQUFNLENBQUM7SUFDbkM7O09BRUc7SUFDSCxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7Q0FDcEIsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxNQUFNLHNCQUFzQixDQUFDLENBQUMsSUFBSTtJQUN0Qzs7T0FFRztJQUNILDBCQUEwQixFQUFFLE1BQU0sQ0FBQztJQUNuQzs7T0FFRztJQUNILGFBQWEsRUFBRSxDQUFDLENBQUM7Q0FDbEIsQ0FBQyJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data_retrieval.d.ts","sourceRoot":"","sources":["../../src/structs/data_retrieval.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B;;OAEG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;OAEG;IACH,aAAa,EAAE,CAAC,EAAE,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC;;OAEG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC;CAClB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
2
+ import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ export type InboxMessage = {
5
+ index: bigint;
6
+ leaf: Fr;
7
+ checkpointNumber: CheckpointNumber;
8
+ l1BlockNumber: bigint;
9
+ l1BlockHash: Buffer32;
10
+ rollingHash: Buffer16;
11
+ };
12
+ export declare function updateRollingHash(currentRollingHash: Buffer16, leaf: Fr): Buffer16;
13
+ export declare function serializeInboxMessage(message: InboxMessage): Buffer;
14
+ export declare function deserializeInboxMessage(buffer: Buffer): InboxMessage;
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5ib3hfbWVzc2FnZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0cnVjdHMvaW5ib3hfbWVzc2FnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTlELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUdwRCxNQUFNLE1BQU0sWUFBWSxHQUFHO0lBQ3pCLEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCxJQUFJLEVBQUUsRUFBRSxDQUFDO0lBQ1QsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUM7SUFDbkMsYUFBYSxFQUFFLE1BQU0sQ0FBQztJQUN0QixXQUFXLEVBQUUsUUFBUSxDQUFDO0lBQ3RCLFdBQVcsRUFBRSxRQUFRLENBQUM7Q0FDdkIsQ0FBQztBQUVGLHdCQUFnQixpQkFBaUIsQ0FBQyxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsR0FBRyxRQUFRLENBR2xGO0FBRUQsd0JBQWdCLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsTUFBTSxDQVNuRTtBQUVELHdCQUFnQix1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLFlBQVksQ0FTcEUifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox_message.d.ts","sourceRoot":"","sources":["../../src/structs/inbox_message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,EAAE,CAAC;IACT,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,QAAQ,CAAC;IACtB,WAAW,EAAE,QAAQ,CAAC;CACvB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,QAAQ,CAGlF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CASnE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CASpE"}
@@ -1,2 +1,2 @@
1
1
  export type { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGlzaGVkLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXJjaGl2ZXIvc3RydWN0cy9wdWJsaXNoZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDIn0=
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGlzaGVkLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RydWN0cy9wdWJsaXNoZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"published.d.ts","sourceRoot":"","sources":["../../src/structs/published.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}