@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
@@ -5,13 +5,18 @@ export class ArchiverInstrumentation {
5
5
  tracer;
6
6
  blockHeight;
7
7
  txCount;
8
- syncDuration;
9
- l1BlocksSynced;
10
8
  l1BlockHeight;
11
9
  proofsSubmittedDelay;
12
10
  proofsSubmittedCount;
13
11
  dbMetrics;
12
+ pruneDuration;
14
13
  pruneCount;
14
+ syncDurationPerBlock;
15
+ syncBlockCount;
16
+ manaPerBlock;
17
+ txsPerBlock;
18
+ syncDurationPerMessage;
19
+ syncMessageCount;
15
20
  log;
16
21
  constructor(telemetry, lmdbStats){
17
22
  this.telemetry = telemetry;
@@ -22,13 +27,12 @@ export class ArchiverInstrumentation {
22
27
  description: 'The height of the latest block processed by the archiver',
23
28
  valueType: ValueType.INT
24
29
  });
25
- this.txCount = meter.createUpDownCounter(Metrics.ARCHIVER_TX_COUNT, {
26
- description: 'The total number of transactions',
30
+ this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT, {
31
+ description: 'The height of the latest L1 block processed by the archiver',
27
32
  valueType: ValueType.INT
28
33
  });
29
- this.syncDuration = meter.createHistogram(Metrics.ARCHIVER_SYNC_DURATION, {
30
- unit: 'ms',
31
- description: 'Duration to sync a block',
34
+ this.txCount = meter.createUpDownCounter(Metrics.ARCHIVER_TOTAL_TXS, {
35
+ description: 'The total number of transactions',
32
36
  valueType: ValueType.INT
33
37
  });
34
38
  this.proofsSubmittedCount = meter.createUpDownCounter(Metrics.ARCHIVER_ROLLUP_PROOF_COUNT, {
@@ -40,25 +44,52 @@ export class ArchiverInstrumentation {
40
44
  description: 'Time after a block is submitted until its proof is published',
41
45
  valueType: ValueType.INT
42
46
  });
43
- this.l1BlocksSynced = meter.createUpDownCounter(Metrics.ARCHIVER_L1_BLOCKS_SYNCED, {
47
+ this.syncDurationPerBlock = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_BLOCK, {
48
+ unit: 'ms',
49
+ description: 'Duration to sync a block',
50
+ valueType: ValueType.INT
51
+ });
52
+ this.syncBlockCount = meter.createUpDownCounter(Metrics.ARCHIVER_SYNC_BLOCK_COUNT, {
44
53
  description: 'Number of blocks synced from L1',
45
54
  valueType: ValueType.INT
46
55
  });
47
- this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT, {
48
- description: 'The height of the latest L1 block processed by the archiver',
56
+ this.manaPerBlock = meter.createHistogram(Metrics.ARCHIVER_MANA_PER_BLOCK, {
57
+ description: 'The mana consumed by blocks',
58
+ valueType: ValueType.DOUBLE,
59
+ unit: 'Mmana'
60
+ });
61
+ this.txsPerBlock = meter.createHistogram(Metrics.ARCHIVER_TXS_PER_BLOCK, {
62
+ description: 'The block tx count',
63
+ valueType: ValueType.INT,
64
+ unit: 'tx'
65
+ });
66
+ this.syncDurationPerMessage = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_MESSAGE, {
67
+ unit: 'ms',
68
+ description: 'Duration to sync a message',
69
+ valueType: ValueType.INT
70
+ });
71
+ this.syncMessageCount = meter.createUpDownCounter(Metrics.ARCHIVER_SYNC_MESSAGE_COUNT, {
72
+ description: 'Number of L1 to L2 messages synced',
73
+ valueType: ValueType.INT
74
+ });
75
+ this.pruneDuration = meter.createHistogram(Metrics.ARCHIVER_PRUNE_DURATION, {
76
+ unit: 'ms',
77
+ description: 'Duration to sync a message',
49
78
  valueType: ValueType.INT
50
79
  });
51
- this.dbMetrics = new LmdbMetrics(meter, {
52
- [Attributes.DB_DATA_TYPE]: 'archiver'
53
- }, lmdbStats);
54
80
  this.pruneCount = meter.createUpDownCounter(Metrics.ARCHIVER_PRUNE_COUNT, {
55
81
  description: 'Number of prunes detected',
56
82
  valueType: ValueType.INT
57
83
  });
84
+ this.dbMetrics = new LmdbMetrics(meter, {
85
+ [Attributes.DB_DATA_TYPE]: 'archiver'
86
+ }, lmdbStats);
58
87
  }
59
88
  static async new(telemetry, lmdbStats) {
60
89
  const instance = new ArchiverInstrumentation(telemetry, lmdbStats);
61
- instance.l1BlocksSynced.add(0);
90
+ instance.syncBlockCount.add(0);
91
+ instance.syncMessageCount.add(0);
92
+ instance.pruneCount.add(0);
62
93
  await instance.telemetry.flush();
63
94
  return instance;
64
95
  }
@@ -66,15 +97,25 @@ export class ArchiverInstrumentation {
66
97
  return this.telemetry.isEnabled();
67
98
  }
68
99
  processNewBlocks(syncTimePerBlock, blocks) {
69
- this.syncDuration.record(Math.ceil(syncTimePerBlock));
100
+ this.syncDurationPerBlock.record(Math.ceil(syncTimePerBlock));
70
101
  this.blockHeight.record(Math.max(...blocks.map((b)=>b.number)));
71
- this.l1BlocksSynced.add(blocks.length);
102
+ this.syncBlockCount.add(blocks.length);
72
103
  for (const block of blocks){
73
104
  this.txCount.add(block.body.txEffects.length);
105
+ this.txsPerBlock.record(block.body.txEffects.length);
106
+ this.manaPerBlock.record(block.header.totalManaUsed.toNumber() / 1e6);
107
+ }
108
+ }
109
+ processNewMessages(count, syncPerMessageMs) {
110
+ if (count === 0) {
111
+ return;
74
112
  }
113
+ this.syncMessageCount.add(count);
114
+ this.syncDurationPerMessage.record(Math.ceil(syncPerMessageMs));
75
115
  }
76
- processPrune() {
116
+ processPrune(duration) {
77
117
  this.pruneCount.add(1);
118
+ this.pruneDuration.record(Math.ceil(duration));
78
119
  }
79
120
  updateLastProvenBlock(blockNumber) {
80
121
  this.blockHeight.record(blockNumber, {
@@ -1,9 +1,9 @@
1
+ import { Fr } from '@aztec/foundation/fields';
1
2
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
2
3
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
3
- import { type InBlock, L2Block } from '@aztec/stdlib/block';
4
- import { BlockHeader, TxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
5
- import type { L1Published } from '../structs/published.js';
6
- export { type TxEffect, type TxHash, TxReceipt } from '@aztec/stdlib/tx';
4
+ import { L2BlockHash, PublishedL2Block, type ValidateBlockResult } from '@aztec/stdlib/block';
5
+ import { BlockHeader, type IndexedTxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
6
+ export { TxReceipt, type TxEffect, type TxHash } from '@aztec/stdlib/tx';
7
7
  /**
8
8
  * LMDB implementation of the ArchiverDataStore interface.
9
9
  */
@@ -16,7 +16,9 @@ export declare class BlockStore {
16
16
  * @param blocks - The L2 blocks to be added to the store.
17
17
  * @returns True if the operation is successful.
18
18
  */
19
- addBlocks(blocks: L1Published<L2Block>[]): Promise<boolean>;
19
+ addBlocks(blocks: PublishedL2Block[], opts?: {
20
+ force?: boolean;
21
+ }): Promise<boolean>;
20
22
  /**
21
23
  * Unwinds blocks from the database
22
24
  * @param from - The tip of the chain, passed for verification purposes,
@@ -31,13 +33,37 @@ export declare class BlockStore {
31
33
  * @param limit - The number of blocks to return.
32
34
  * @returns The requested L2 blocks
33
35
  */
34
- getBlocks(start: number, limit: number): AsyncIterableIterator<L1Published<L2Block>>;
36
+ getBlocks(start: number, limit: number): AsyncIterableIterator<PublishedL2Block>;
35
37
  /**
36
38
  * Gets an L2 block.
37
39
  * @param blockNumber - The number of the block to return.
38
40
  * @returns The requested L2 block.
39
41
  */
40
- getBlock(blockNumber: number): Promise<L1Published<L2Block> | undefined>;
42
+ getBlock(blockNumber: number): Promise<PublishedL2Block | undefined>;
43
+ /**
44
+ * Gets an L2 block by its hash.
45
+ * @param blockHash - The hash of the block to return.
46
+ * @returns The requested L2 block.
47
+ */
48
+ getBlockByHash(blockHash: L2BlockHash): Promise<PublishedL2Block | undefined>;
49
+ /**
50
+ * Gets an L2 block by its archive root.
51
+ * @param archive - The archive root of the block to return.
52
+ * @returns The requested L2 block.
53
+ */
54
+ getBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined>;
55
+ /**
56
+ * Gets a block header by its hash.
57
+ * @param blockHash - The hash of the block to return.
58
+ * @returns The requested block header.
59
+ */
60
+ getBlockHeaderByHash(blockHash: L2BlockHash): Promise<BlockHeader | undefined>;
61
+ /**
62
+ * Gets a block header by its archive root.
63
+ * @param archive - The archive root of the block to return.
64
+ * @returns The requested block header.
65
+ */
66
+ getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined>;
41
67
  /**
42
68
  * Gets the headers for a sequence of L2 blocks.
43
69
  * @param start - Number of the first block to return (inclusive).
@@ -45,13 +71,14 @@ export declare class BlockStore {
45
71
  * @returns The requested L2 block headers
46
72
  */
47
73
  getBlockHeaders(start: number, limit: number): AsyncIterableIterator<BlockHeader>;
74
+ private getBlockStorages;
48
75
  private getBlockFromBlockStorage;
49
76
  /**
50
77
  * Gets a tx effect.
51
- * @param txHash - The txHash of the tx corresponding to the tx effect.
52
- * @returns The requested tx effect (or undefined if not found).
78
+ * @param txHash - The hash of the tx corresponding to the tx effect.
79
+ * @returns The requested tx effect with block info (or undefined if not found).
53
80
  */
54
- getTxEffect(txHash: TxHash): Promise<InBlock<TxEffect> | undefined>;
81
+ getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined>;
55
82
  /**
56
83
  * Gets a receipt of a settled tx.
57
84
  * @param txHash - The hash of a tx we try to get the receipt for.
@@ -83,5 +110,15 @@ export declare class BlockStore {
83
110
  setSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<boolean>;
84
111
  getProvenL2BlockNumber(): Promise<number>;
85
112
  setProvenL2BlockNumber(blockNumber: number): Promise<boolean>;
113
+ /**
114
+ * Gets the pending chain validation status.
115
+ * @returns The validation status or undefined if not set.
116
+ */
117
+ getPendingChainValidationStatus(): Promise<ValidateBlockResult | undefined>;
118
+ /**
119
+ * Sets the pending chain validation status.
120
+ * @param status - The validation status to store.
121
+ */
122
+ setPendingChainValidationStatus(status: ValidateBlockResult | undefined): Promise<void>;
86
123
  }
87
- //# sourceMappingURL=block_store.d.ts.map
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcmNoaXZlci9rdl9hcmNoaXZlcl9zdG9yZS9ibG9ja19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFLOUMsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQTZDLE1BQU0saUJBQWlCLENBQUM7QUFDcEcsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDaEUsT0FBTyxFQUlMLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsS0FBSyxtQkFBbUIsRUFDekIsTUFBTSxxQkFBcUIsQ0FBQztBQUc3QixPQUFPLEVBQ0wsV0FBVyxFQUNYLEtBQUssZUFBZSxFQUVwQixNQUFNLEVBQ04sU0FBUyxFQUdWLE1BQU0sa0JBQWtCLENBQUM7QUFLMUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLFFBQVEsRUFBRSxLQUFLLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBWXpFOztHQUVHO0FBQ0gscUJBQWEsVUFBVTs7SUE4QlQsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQVV4QztJQUVEOzs7O09BSUc7SUFDRyxTQUFTLENBQUMsTUFBTSxFQUFFLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxHQUFFO1FBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTyxDQUFBO0tBQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBMEQ1RjtJQUVEOzs7Ozs7T0FNRztJQUNHLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQWtDdEQ7SUFFRDs7Ozs7T0FLRztJQUNJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcscUJBQXFCLENBQUMsZ0JBQWdCLENBQUMsQ0FPdEY7SUFFRDs7OztPQUlHO0lBQ0csUUFBUSxDQUFDLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxDQU16RTtJQUVEOzs7O09BSUc7SUFDRyxjQUFjLENBQUMsU0FBUyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLENBTWxGO0lBRUQ7Ozs7T0FJRztJQUNHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxDQU0xRTtJQUVEOzs7O09BSUc7SUFDRyxvQkFBb0IsQ0FBQyxTQUFTLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFDLENBVW5GO0lBRUQ7Ozs7T0FJRztJQUNHLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUMsQ0FVM0U7SUFFRDs7Ozs7T0FLRztJQUNJLGVBQWUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcscUJBQXFCLENBQUMsV0FBVyxDQUFDLENBVXZGO1lBRWMsZ0JBQWdCO1lBYWpCLHdCQUF3QjtJQXVDdEM7Ozs7T0FJRztJQUNHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFDLENBTXRFO0lBRUQ7Ozs7T0FJRztJQUNHLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsQ0FjeEU7SUFFRDs7OztPQUlHO0lBQ1UsYUFBYSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBT3RHO0lBRUQ7Ozs7T0FJRztJQUNILG1CQUFtQixDQUFDLGVBQWUsRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBRTVHO0lBRUQ7OztPQUdHO0lBQ0csdUJBQXVCLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUcvQztJQUVEOzs7T0FHRztJQUNILHVCQUF1QixJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRXJEO0lBRUQsdUJBQXVCLENBQUMsYUFBYSxFQUFFLE1BQU0sb0JBRTVDO0lBRUssc0JBQXNCLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQU05QztJQUVELHNCQUFzQixDQUFDLFdBQVcsRUFBRSxNQUFNLG9CQUV6QztJQWNEOzs7T0FHRztJQUNHLCtCQUErQixJQUFJLE9BQU8sQ0FBQyxtQkFBbUIsR0FBRyxTQUFTLENBQUMsQ0FNaEY7SUFFRDs7O09BR0c7SUFDRywrQkFBK0IsQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FPNUY7Q0FDRiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"block_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/block_store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAA6C,MAAM,iBAAiB,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAQ,KAAK,OAAO,EAAE,OAAO,EAAe,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,yBAAyB,CAAC;AAE5E,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAUzE;;GAEG;AACH,qBAAa,UAAU;;IAwBT,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,iBAAiB;IAUzC;;;;OAIG;IACG,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BjE;;;;;;OAMG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IA0BvD;;;;;OAKG;IACI,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAO3F;;;;OAIG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAS9E;;;;;OAKG;IACI,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAAC,WAAW,CAAC;YAM1E,wBAAwB;IAgBtC;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAkBzE;;;;OAIG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAmBzE;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAI1F;;;;OAIG;IACH,mBAAmB,CAAC,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAI7G;;;OAGG;IACG,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhD;;;OAGG;IACH,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAItD,uBAAuB,CAAC,aAAa,EAAE,MAAM;IAIvC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/C,sBAAsB,CAAC,WAAW,EAAE,MAAM;CAe3C"}
1
+ {"version":3,"file":"block_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/block_store.ts"],"names":[],"mappings":"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"}
@@ -1,56 +1,90 @@
1
1
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
+ import { Fr } from '@aztec/foundation/fields';
2
3
  import { toArray } from '@aztec/foundation/iterable';
3
4
  import { createLogger } from '@aztec/foundation/log';
4
- import { Body, L2Block, L2BlockHash } from '@aztec/stdlib/block';
5
+ import { BufferReader } from '@aztec/foundation/serialize';
6
+ import { bufferToHex } from '@aztec/foundation/string';
7
+ import { Body, CommitteeAttestation, L2Block, L2BlockHash, PublishedL2Block } from '@aztec/stdlib/block';
8
+ import { L2BlockHeader, deserializeValidateBlockResult, serializeValidateBlockResult } from '@aztec/stdlib/block';
5
9
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
6
- import { BlockHeader, TxReceipt } from '@aztec/stdlib/tx';
10
+ import { TxHash, TxReceipt, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
11
+ import { BlockNumberNotSequentialError, InitialBlockNumberNotSequentialError } from '../errors.js';
7
12
  export { TxReceipt } from '@aztec/stdlib/tx';
8
13
  /**
9
14
  * LMDB implementation of the ArchiverDataStore interface.
10
15
  */ export class BlockStore {
11
16
  db;
12
17
  /** Map block number to block data */ #blocks;
13
- /** Map block hash to block body */ #blockBodies;
18
+ /** Map block hash to list of tx hashes */ #blockTxs;
19
+ /** Tx hash to serialized IndexedTxEffect */ #txEffects;
14
20
  /** Stores L1 block number in which the last processed L2 block was included */ #lastSynchedL1Block;
15
21
  /** Stores l2 block number of the last proven block */ #lastProvenL2Block;
16
- /** Stores l2 epoch number of the last proven epoch */ #lastProvenL2Epoch;
17
- /** Index mapping transaction hash (as a string) to its location in a block */ #txIndex;
22
+ /** Stores the pending chain validation status */ #pendingChainValidationStatus;
18
23
  /** Index mapping a contract's address (as a string) to its location in a block */ #contractIndex;
24
+ /** Index mapping block hash to block number */ #blockHashIndex;
25
+ /** Index mapping block archive to block number */ #blockArchiveIndex;
19
26
  #log;
20
27
  constructor(db){
21
28
  this.db = db;
22
29
  this.#log = createLogger('archiver:block_store');
23
30
  this.#blocks = db.openMap('archiver_blocks');
24
- this.#blockBodies = db.openMap('archiver_block_bodies');
25
- this.#txIndex = db.openMap('archiver_tx_index');
31
+ this.#blockTxs = db.openMap('archiver_block_txs');
32
+ this.#txEffects = db.openMap('archiver_tx_effects');
26
33
  this.#contractIndex = db.openMap('archiver_contract_index');
34
+ this.#blockHashIndex = db.openMap('archiver_block_hash_index');
35
+ this.#blockArchiveIndex = db.openMap('archiver_block_archive_index');
27
36
  this.#lastSynchedL1Block = db.openSingleton('archiver_last_synched_l1_block');
28
37
  this.#lastProvenL2Block = db.openSingleton('archiver_last_proven_l2_block');
29
- this.#lastProvenL2Epoch = db.openSingleton('archiver_last_proven_l2_epoch');
38
+ this.#pendingChainValidationStatus = db.openSingleton('archiver_pending_chain_validation_status');
30
39
  }
31
40
  /**
32
41
  * Append new blocks to the store's list.
33
42
  * @param blocks - The L2 blocks to be added to the store.
34
43
  * @returns True if the operation is successful.
35
- */ async addBlocks(blocks) {
44
+ */ async addBlocks(blocks, opts = {}) {
36
45
  if (blocks.length === 0) {
37
46
  return true;
38
47
  }
39
48
  return await this.db.transactionAsync(async ()=>{
49
+ // Check that the block immediately before the first block to be added is present in the store.
50
+ const firstBlockNumber = blocks[0].block.number;
51
+ const [previousBlockNumber] = await toArray(this.#blocks.keysAsync({
52
+ reverse: true,
53
+ limit: 1,
54
+ end: firstBlockNumber - 1
55
+ }));
56
+ const hasPreviousBlock = firstBlockNumber === INITIAL_L2_BLOCK_NUM || previousBlockNumber !== undefined && previousBlockNumber === firstBlockNumber - 1;
57
+ if (!opts.force && !hasPreviousBlock) {
58
+ throw new InitialBlockNumberNotSequentialError(firstBlockNumber, previousBlockNumber);
59
+ }
60
+ // Iterate over blocks array and insert them, checking that the block numbers are sequential.
61
+ let previousBlock = undefined;
40
62
  for (const block of blocks){
41
- await this.#blocks.set(block.data.number, {
42
- header: block.data.header.toBuffer(),
43
- archive: block.data.archive.toBuffer(),
44
- l1: block.l1
63
+ if (!opts.force && previousBlock && previousBlock.block.number + 1 !== block.block.number) {
64
+ throw new BlockNumberNotSequentialError(block.block.number, previousBlock.block.number);
65
+ }
66
+ previousBlock = block;
67
+ const blockHash = L2BlockHash.fromField(await block.block.hash());
68
+ await this.#blocks.set(block.block.number, {
69
+ header: block.block.header.toBuffer(),
70
+ blockHash: blockHash.toBuffer(),
71
+ archive: block.block.archive.toBuffer(),
72
+ l1: block.l1,
73
+ attestations: block.attestations.map((attestation)=>attestation.toBuffer())
45
74
  });
46
- for(let i = 0; i < block.data.body.txEffects.length; i++){
47
- const txEffect = block.data.body.txEffects[i];
48
- await this.#txIndex.set(txEffect.txHash.toString(), [
49
- block.data.number,
50
- i
51
- ]);
75
+ for(let i = 0; i < block.block.body.txEffects.length; i++){
76
+ const txEffect = {
77
+ data: block.block.body.txEffects[i],
78
+ l2BlockNumber: block.block.number,
79
+ l2BlockHash: blockHash,
80
+ txIndexInBlock: i
81
+ };
82
+ await this.#txEffects.set(txEffect.data.txHash.toString(), serializeIndexedTxEffect(txEffect));
52
83
  }
53
- await this.#blockBodies.set((await block.data.hash()).toString(), block.data.body.toBuffer());
84
+ await this.#blockTxs.set(blockHash.toString(), Buffer.concat(block.block.body.txEffects.map((tx)=>tx.txHash.toBuffer())));
85
+ // Update indices for block hash and archive
86
+ await this.#blockHashIndex.set(blockHash.toString(), block.block.number);
87
+ await this.#blockArchiveIndex.set(block.block.archive.root.toString(), block.block.number);
54
88
  }
55
89
  await this.#lastSynchedL1Block.set(blocks[blocks.length - 1].l1.blockNumber);
56
90
  return true;
@@ -68,6 +102,10 @@ export { TxReceipt } from '@aztec/stdlib/tx';
68
102
  if (from !== last) {
69
103
  throw new Error(`Can only unwind blocks from the tip (requested ${from} but current tip is ${last})`);
70
104
  }
105
+ const proven = await this.getProvenL2BlockNumber();
106
+ if (from - blocksToUnwind < proven) {
107
+ await this.setProvenL2BlockNumber(from - blocksToUnwind);
108
+ }
71
109
  for(let i = 0; i < blocksToUnwind; i++){
72
110
  const blockNumber = from - i;
73
111
  const block = await this.getBlock(blockNumber);
@@ -75,10 +113,13 @@ export { TxReceipt } from '@aztec/stdlib/tx';
75
113
  this.#log.warn(`Cannot remove block ${blockNumber} from the store since we don't have it`);
76
114
  continue;
77
115
  }
78
- await this.#blocks.delete(block.data.number);
79
- await Promise.all(block.data.body.txEffects.map((tx)=>this.#txIndex.delete(tx.txHash.toString())));
80
- const blockHash = (await block.data.hash()).toString();
81
- await this.#blockBodies.delete(blockHash);
116
+ await this.#blocks.delete(block.block.number);
117
+ await Promise.all(block.block.body.txEffects.map((tx)=>this.#txEffects.delete(tx.txHash.toString())));
118
+ const blockHash = (await block.block.hash()).toString();
119
+ await this.#blockTxs.delete(blockHash);
120
+ // Clean up indices
121
+ await this.#blockHashIndex.delete(blockHash);
122
+ await this.#blockArchiveIndex.delete(block.block.archive.root.toString());
82
123
  this.#log.debug(`Unwound block ${blockNumber} ${blockHash}`);
83
124
  }
84
125
  return true;
@@ -90,9 +131,11 @@ export { TxReceipt } from '@aztec/stdlib/tx';
90
131
  * @param limit - The number of blocks to return.
91
132
  * @returns The requested L2 blocks
92
133
  */ async *getBlocks(start, limit) {
93
- for await (const blockStorage of this.#blocks.valuesAsync(this.#computeBlockRange(start, limit))){
94
- const block = await this.getBlockFromBlockStorage(blockStorage);
95
- yield block;
134
+ for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)){
135
+ const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
136
+ if (block) {
137
+ yield block;
138
+ }
96
139
  }
97
140
  }
98
141
  /**
@@ -104,7 +147,59 @@ export { TxReceipt } from '@aztec/stdlib/tx';
104
147
  if (!blockStorage || !blockStorage.header) {
105
148
  return Promise.resolve(undefined);
106
149
  }
107
- return this.getBlockFromBlockStorage(blockStorage);
150
+ return this.getBlockFromBlockStorage(blockNumber, blockStorage);
151
+ }
152
+ /**
153
+ * Gets an L2 block by its hash.
154
+ * @param blockHash - The hash of the block to return.
155
+ * @returns The requested L2 block.
156
+ */ async getBlockByHash(blockHash) {
157
+ const blockNumber = await this.#blockHashIndex.getAsync(blockHash.toString());
158
+ if (blockNumber === undefined) {
159
+ return undefined;
160
+ }
161
+ return this.getBlock(blockNumber);
162
+ }
163
+ /**
164
+ * Gets an L2 block by its archive root.
165
+ * @param archive - The archive root of the block to return.
166
+ * @returns The requested L2 block.
167
+ */ async getBlockByArchive(archive) {
168
+ const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
169
+ if (blockNumber === undefined) {
170
+ return undefined;
171
+ }
172
+ return this.getBlock(blockNumber);
173
+ }
174
+ /**
175
+ * Gets a block header by its hash.
176
+ * @param blockHash - The hash of the block to return.
177
+ * @returns The requested block header.
178
+ */ async getBlockHeaderByHash(blockHash) {
179
+ const blockNumber = await this.#blockHashIndex.getAsync(blockHash.toString());
180
+ if (blockNumber === undefined) {
181
+ return undefined;
182
+ }
183
+ const blockStorage = await this.#blocks.getAsync(blockNumber);
184
+ if (!blockStorage || !blockStorage.header) {
185
+ return undefined;
186
+ }
187
+ return L2BlockHeader.fromBuffer(blockStorage.header).toBlockHeader();
188
+ }
189
+ /**
190
+ * Gets a block header by its archive root.
191
+ * @param archive - The archive root of the block to return.
192
+ * @returns The requested block header.
193
+ */ async getBlockHeaderByArchive(archive) {
194
+ const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
195
+ if (blockNumber === undefined) {
196
+ return undefined;
197
+ }
198
+ const blockStorage = await this.#blocks.getAsync(blockNumber);
199
+ if (!blockStorage || !blockStorage.header) {
200
+ return undefined;
201
+ }
202
+ return L2BlockHeader.fromBuffer(blockStorage.header).toBlockHeader();
108
203
  }
109
204
  /**
110
205
  * Gets the headers for a sequence of L2 blocks.
@@ -112,63 +207,96 @@ export { TxReceipt } from '@aztec/stdlib/tx';
112
207
  * @param limit - The number of blocks to return.
113
208
  * @returns The requested L2 block headers
114
209
  */ async *getBlockHeaders(start, limit) {
115
- for await (const blockStorage of this.#blocks.valuesAsync(this.#computeBlockRange(start, limit))){
116
- yield BlockHeader.fromBuffer(blockStorage.header);
210
+ for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)){
211
+ const header = L2BlockHeader.fromBuffer(blockStorage.header).toBlockHeader();
212
+ if (header.getBlockNumber() !== blockNumber) {
213
+ throw new Error(`Block number mismatch when retrieving block header from archive (expected ${blockNumber} but got ${header.getBlockNumber()})`);
214
+ }
215
+ yield header;
216
+ }
217
+ }
218
+ async *getBlockStorages(start, limit) {
219
+ let expectedBlockNumber = start;
220
+ for await (const [blockNumber, blockStorage] of this.#blocks.entriesAsync(this.#computeBlockRange(start, limit))){
221
+ if (blockNumber !== expectedBlockNumber) {
222
+ throw new Error(`Block number mismatch when iterating blocks from archive (expected ${expectedBlockNumber} but got ${blockNumber})`);
223
+ }
224
+ expectedBlockNumber++;
225
+ yield [
226
+ blockNumber,
227
+ blockStorage
228
+ ];
117
229
  }
118
230
  }
119
- async getBlockFromBlockStorage(blockStorage) {
120
- const header = BlockHeader.fromBuffer(blockStorage.header);
231
+ async getBlockFromBlockStorage(blockNumber, blockStorage) {
232
+ const header = L2BlockHeader.fromBuffer(blockStorage.header);
121
233
  const archive = AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive);
122
- const blockHash = (await header.hash()).toString();
123
- const blockBodyBuffer = await this.#blockBodies.getAsync(blockHash);
124
- if (blockBodyBuffer === undefined) {
125
- throw new Error(`Could not retrieve body for block ${header.globalVariables.blockNumber.toNumber()} ${blockHash}`);
234
+ const blockHash = blockStorage.blockHash;
235
+ const blockHashString = bufferToHex(blockHash);
236
+ const blockTxsBuffer = await this.#blockTxs.getAsync(blockHashString);
237
+ if (blockTxsBuffer === undefined) {
238
+ this.#log.warn(`Could not find body for block ${header.globalVariables.blockNumber} ${blockHash}`);
239
+ return undefined;
126
240
  }
127
- const body = Body.fromBuffer(blockBodyBuffer);
128
- const l2Block = new L2Block(archive, header, body);
129
- return {
130
- data: l2Block,
131
- l1: blockStorage.l1
132
- };
241
+ const txEffects = [];
242
+ const reader = BufferReader.asReader(blockTxsBuffer);
243
+ while(!reader.isEmpty()){
244
+ const txHash = reader.readObject(TxHash);
245
+ const txEffect = await this.#txEffects.getAsync(txHash.toString());
246
+ if (txEffect === undefined) {
247
+ this.#log.warn(`Could not find tx effect for tx ${txHash} in block ${blockNumber}`);
248
+ return undefined;
249
+ }
250
+ txEffects.push(deserializeIndexedTxEffect(txEffect).data);
251
+ }
252
+ const body = new Body(txEffects);
253
+ const block = new L2Block(archive, header, body, Fr.fromBuffer(blockHash));
254
+ if (block.number !== blockNumber) {
255
+ throw new Error(`Block number mismatch when retrieving block from archive (expected ${blockNumber} but got ${block.number} with hash ${blockHashString})`);
256
+ }
257
+ const attestations = blockStorage.attestations.map(CommitteeAttestation.fromBuffer);
258
+ return PublishedL2Block.fromFields({
259
+ block,
260
+ l1: blockStorage.l1,
261
+ attestations
262
+ });
133
263
  }
134
264
  /**
135
265
  * Gets a tx effect.
136
- * @param txHash - The txHash of the tx corresponding to the tx effect.
137
- * @returns The requested tx effect (or undefined if not found).
266
+ * @param txHash - The hash of the tx corresponding to the tx effect.
267
+ * @returns The requested tx effect with block info (or undefined if not found).
138
268
  */ async getTxEffect(txHash) {
139
- const [blockNumber, txIndex] = await this.getTxLocation(txHash) ?? [];
140
- if (typeof blockNumber !== 'number' || typeof txIndex !== 'number') {
269
+ const buffer = await this.#txEffects.getAsync(txHash.toString());
270
+ if (!buffer) {
141
271
  return undefined;
142
272
  }
143
- const block = await this.getBlock(blockNumber);
144
- if (!block) {
145
- return undefined;
146
- }
147
- return {
148
- data: block.data.body.txEffects[txIndex],
149
- l2BlockNumber: block.data.number,
150
- l2BlockHash: (await block.data.hash()).toString()
151
- };
273
+ return deserializeIndexedTxEffect(buffer);
152
274
  }
153
275
  /**
154
276
  * Gets a receipt of a settled tx.
155
277
  * @param txHash - The hash of a tx we try to get the receipt for.
156
278
  * @returns The requested tx receipt (or undefined if not found).
157
279
  */ async getSettledTxReceipt(txHash) {
158
- const [blockNumber, txIndex] = await this.getTxLocation(txHash) ?? [];
159
- if (typeof blockNumber !== 'number' || typeof txIndex !== 'number') {
280
+ const txEffect = await this.getTxEffect(txHash);
281
+ if (!txEffect) {
160
282
  return undefined;
161
283
  }
162
- const block = await this.getBlock(blockNumber);
163
- const tx = block.data.body.txEffects[txIndex];
164
- return new TxReceipt(txHash, TxReceipt.statusFromRevertCode(tx.revertCode), '', tx.transactionFee.toBigInt(), L2BlockHash.fromField(await block.data.hash()), block.data.number);
284
+ return new TxReceipt(txHash, TxReceipt.statusFromRevertCode(txEffect.data.revertCode), '', txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, txEffect.l2BlockNumber);
165
285
  }
166
286
  /**
167
287
  * Looks up which block included the requested tx effect.
168
288
  * @param txHash - The txHash of the tx.
169
289
  * @returns The block number and index of the tx.
170
- */ getTxLocation(txHash) {
171
- return this.#txIndex.getAsync(txHash.toString());
290
+ */ async getTxLocation(txHash) {
291
+ const txEffect = await this.#txEffects.getAsync(txHash.toString());
292
+ if (!txEffect) {
293
+ return undefined;
294
+ }
295
+ const { l2BlockNumber, txIndexInBlock } = deserializeIndexedTxEffect(txEffect);
296
+ return [
297
+ l2BlockNumber,
298
+ txIndexInBlock
299
+ ];
172
300
  }
173
301
  /**
174
302
  * Looks up which block deployed a particular contract.
@@ -197,7 +325,11 @@ export { TxReceipt } from '@aztec/stdlib/tx';
197
325
  return this.#lastSynchedL1Block.set(l1BlockNumber);
198
326
  }
199
327
  async getProvenL2BlockNumber() {
200
- return await this.#lastProvenL2Block.getAsync() ?? 0;
328
+ const [latestBlockNumber, provenBlockNumber] = await Promise.all([
329
+ this.getSynchedL2BlockNumber(),
330
+ this.#lastProvenL2Block.getAsync()
331
+ ]);
332
+ return (provenBlockNumber ?? 0) > latestBlockNumber ? latestBlockNumber : provenBlockNumber ?? 0;
201
333
  }
202
334
  setProvenL2BlockNumber(blockNumber) {
203
335
  return this.#lastProvenL2Block.set(blockNumber);
@@ -214,4 +346,25 @@ export { TxReceipt } from '@aztec/stdlib/tx';
214
346
  limit
215
347
  };
216
348
  }
349
+ /**
350
+ * Gets the pending chain validation status.
351
+ * @returns The validation status or undefined if not set.
352
+ */ async getPendingChainValidationStatus() {
353
+ const buffer = await this.#pendingChainValidationStatus.getAsync();
354
+ if (!buffer) {
355
+ return undefined;
356
+ }
357
+ return deserializeValidateBlockResult(buffer);
358
+ }
359
+ /**
360
+ * Sets the pending chain validation status.
361
+ * @param status - The validation status to store.
362
+ */ async setPendingChainValidationStatus(status) {
363
+ if (status) {
364
+ const buffer = serializeValidateBlockResult(status);
365
+ await this.#pendingChainValidationStatus.set(buffer);
366
+ } else {
367
+ await this.#pendingChainValidationStatus.delete();
368
+ }
369
+ }
217
370
  }
@@ -1,6 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
- import type { ContractClassPublic, ExecutablePrivateFunctionWithMembershipProof, UnconstrainedFunctionWithMembershipProof } from '@aztec/stdlib/contract';
3
+ import type { ContractClassPublic, ExecutablePrivateFunctionWithMembershipProof, UtilityFunctionWithMembershipProof } from '@aztec/stdlib/contract';
4
4
  /**
5
5
  * LMDB implementation of the ArchiverDataStore interface.
6
6
  */
@@ -13,6 +13,6 @@ export declare class ContractClassStore {
13
13
  getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;
14
14
  getBytecodeCommitment(id: Fr): Promise<Fr | undefined>;
15
15
  getContractClassIds(): Promise<Fr[]>;
16
- addFunctions(contractClassId: Fr, newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], newUnconstrainedFunctions: UnconstrainedFunctionWithMembershipProof[]): Promise<boolean>;
16
+ addFunctions(contractClassId: Fr, newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], newUtilityFunctions: UtilityFunctionWithMembershipProof[]): Promise<boolean>;
17
17
  }
18
- //# sourceMappingURL=contract_class_store.d.ts.map
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfY2xhc3Nfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcmNoaXZlci9rdl9hcmNoaXZlcl9zdG9yZS9jb250cmFjdF9jbGFzc19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFHOUMsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0saUJBQWlCLENBQUM7QUFFeEUsT0FBTyxLQUFLLEVBQ1YsbUJBQW1CLEVBRW5CLDRDQUE0QyxFQUM1QyxrQ0FBa0MsRUFDbkMsTUFBTSx3QkFBd0IsQ0FBQztBQUdoQzs7R0FFRztBQUNILHFCQUFhLGtCQUFrQjs7SUFJakIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUd4QztJQUVLLGdCQUFnQixDQUNwQixhQUFhLEVBQUUsbUJBQW1CLEVBQ2xDLGtCQUFrQixFQUFFLEVBQUUsRUFDdEIsV0FBVyxFQUFFLE1BQU0sR0FDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU1mO0lBRUsscUJBQXFCLENBQUMsYUFBYSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU1sRztJQUVLLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxDQUd2RTtJQUVLLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FHM0Q7SUFFSyxtQkFBbUIsSUFBSSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FFekM7SUFFSyxZQUFZLENBQ2hCLGVBQWUsRUFBRSxFQUFFLEVBQ25CLG1CQUFtQixFQUFFLDRDQUE0QyxFQUFFLEVBQ25FLG1CQUFtQixFQUFFLGtDQUFrQyxFQUFFLEdBQ3hELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0F5QmxCO0NBQ0YifQ==