@aztec/p2p 1.2.1 → 2.0.0-nightly.20250813

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 (221) hide show
  1. package/dest/client/factory.d.ts +5 -1
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +29 -12
  4. package/dest/client/interface.d.ts +8 -13
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +18 -22
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +86 -83
  9. package/dest/config.d.ts +30 -1
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/config.js +34 -1
  12. package/dest/index.d.ts +1 -0
  13. package/dest/index.d.ts.map +1 -1
  14. package/dest/index.js +1 -0
  15. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +13 -1
  16. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  17. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  18. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +117 -10
  19. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +4 -1
  20. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +22 -1
  22. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +4 -1
  23. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  24. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +21 -1
  25. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -2
  26. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/mocks.js +2 -10
  28. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +8 -3
  29. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  30. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +64 -37
  31. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +8 -3
  32. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  33. package/dest/mem_pools/tx_pool/memory_tx_pool.js +18 -10
  34. package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -2
  35. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  36. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +73 -44
  38. package/dest/msg_validators/attestation_validator/attestation_validator.js +1 -1
  39. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  40. package/dest/msg_validators/tx_validator/block_header_validator.js +2 -2
  41. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  42. package/dest/msg_validators/tx_validator/data_validator.js +35 -59
  43. package/dest/msg_validators/tx_validator/double_spend_validator.js +2 -2
  44. package/dest/msg_validators/tx_validator/gas_validator.js +4 -4
  45. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/tx_validator/metadata_validator.js +21 -21
  47. package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
  48. package/dest/msg_validators/tx_validator/tx_proof_validator.js +3 -3
  49. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  50. package/dest/services/discv5/discV5_service.js +4 -1
  51. package/dest/services/dummy_service.d.ts +13 -3
  52. package/dest/services/dummy_service.d.ts.map +1 -1
  53. package/dest/services/dummy_service.js +26 -3
  54. package/dest/services/index.d.ts +3 -1
  55. package/dest/services/index.d.ts.map +1 -1
  56. package/dest/services/index.js +3 -1
  57. package/dest/services/libp2p/libp2p_service.d.ts +13 -20
  58. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  59. package/dest/services/libp2p/libp2p_service.js +123 -46
  60. package/dest/services/peer-manager/interface.d.ts +8 -1
  61. package/dest/services/peer-manager/interface.d.ts.map +1 -1
  62. package/dest/services/peer-manager/peer_manager.d.ts +70 -3
  63. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  64. package/dest/services/peer-manager/peer_manager.js +369 -39
  65. package/dest/services/reqresp/config.d.ts +3 -3
  66. package/dest/services/reqresp/config.d.ts.map +1 -1
  67. package/dest/services/reqresp/config.js +3 -3
  68. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +3 -4
  69. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  70. package/dest/services/reqresp/connection-sampler/connection_sampler.js +35 -52
  71. package/dest/services/reqresp/index.d.ts +2 -1
  72. package/dest/services/reqresp/index.d.ts.map +1 -1
  73. package/dest/services/reqresp/index.js +2 -1
  74. package/dest/services/reqresp/interface.d.ts +61 -10
  75. package/dest/services/reqresp/interface.d.ts.map +1 -1
  76. package/dest/services/reqresp/interface.js +41 -6
  77. package/dest/services/reqresp/protocols/auth.d.ts +43 -0
  78. package/dest/services/reqresp/protocols/auth.d.ts.map +1 -0
  79. package/dest/services/reqresp/protocols/auth.js +71 -0
  80. package/dest/services/reqresp/protocols/block.d.ts +5 -0
  81. package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
  82. package/dest/services/reqresp/protocols/block.js +28 -5
  83. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +30 -0
  84. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -0
  85. package/dest/services/reqresp/protocols/block_txs/bitvector.js +75 -0
  86. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +11 -0
  87. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -0
  88. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +39 -0
  89. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +49 -0
  90. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -0
  91. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +75 -0
  92. package/dest/services/reqresp/protocols/block_txs/index.d.ts +4 -0
  93. package/dest/services/reqresp/protocols/block_txs/index.d.ts.map +1 -0
  94. package/dest/services/reqresp/protocols/block_txs/index.js +3 -0
  95. package/dest/services/reqresp/protocols/goodbye.js +3 -5
  96. package/dest/services/reqresp/protocols/index.d.ts +2 -0
  97. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  98. package/dest/services/reqresp/protocols/index.js +2 -0
  99. package/dest/services/reqresp/protocols/status.d.ts +2 -0
  100. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  101. package/dest/services/reqresp/protocols/status.js +7 -0
  102. package/dest/services/reqresp/protocols/tx.d.ts +12 -1
  103. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  104. package/dest/services/reqresp/protocols/tx.js +34 -6
  105. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  106. package/dest/services/reqresp/rate-limiter/rate_limits.js +20 -0
  107. package/dest/services/reqresp/reqresp.d.ts +37 -39
  108. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  109. package/dest/services/reqresp/reqresp.js +220 -220
  110. package/dest/services/reqresp/status.d.ts +8 -3
  111. package/dest/services/reqresp/status.d.ts.map +1 -1
  112. package/dest/services/reqresp/status.js +6 -2
  113. package/dest/services/service.d.ts +10 -10
  114. package/dest/services/service.d.ts.map +1 -1
  115. package/dest/services/tx_collection/config.d.ts +25 -0
  116. package/dest/services/tx_collection/config.d.ts.map +1 -0
  117. package/dest/services/tx_collection/config.js +58 -0
  118. package/dest/services/tx_collection/fast_tx_collection.d.ts +56 -0
  119. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -0
  120. package/dest/services/tx_collection/fast_tx_collection.js +295 -0
  121. package/dest/services/tx_collection/index.d.ts +3 -0
  122. package/dest/services/tx_collection/index.d.ts.map +1 -0
  123. package/dest/services/tx_collection/index.js +2 -0
  124. package/dest/services/tx_collection/instrumentation.d.ts +10 -0
  125. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -0
  126. package/dest/services/tx_collection/instrumentation.js +34 -0
  127. package/dest/services/tx_collection/slow_tx_collection.d.ts +54 -0
  128. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -0
  129. package/dest/services/tx_collection/slow_tx_collection.js +176 -0
  130. package/dest/services/tx_collection/tx_collection.d.ts +109 -0
  131. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -0
  132. package/dest/services/tx_collection/tx_collection.js +127 -0
  133. package/dest/services/tx_collection/tx_collection_sink.d.ts +30 -0
  134. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -0
  135. package/dest/services/tx_collection/tx_collection_sink.js +81 -0
  136. package/dest/services/tx_collection/tx_source.d.ts +18 -0
  137. package/dest/services/tx_collection/tx_source.d.ts.map +1 -0
  138. package/dest/services/tx_collection/tx_source.js +31 -0
  139. package/dest/services/tx_provider.d.ts +49 -0
  140. package/dest/services/tx_provider.d.ts.map +1 -0
  141. package/dest/services/tx_provider.js +206 -0
  142. package/dest/services/{tx_collect_instrumentation.d.ts → tx_provider_instrumentation.d.ts} +2 -2
  143. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -0
  144. package/dest/services/{tx_collect_instrumentation.js → tx_provider_instrumentation.js} +5 -5
  145. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  146. package/dest/test-helpers/make-test-p2p-clients.js +4 -3
  147. package/dest/test-helpers/mock-pubsub.d.ts +2 -1
  148. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  149. package/dest/test-helpers/mock-pubsub.js +2 -1
  150. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  151. package/dest/test-helpers/reqresp-nodes.js +8 -4
  152. package/dest/testbench/p2p_client_testbench_worker.js +11 -5
  153. package/dest/util.d.ts +1 -1
  154. package/dest/util.d.ts.map +1 -1
  155. package/package.json +14 -15
  156. package/src/client/factory.ts +87 -12
  157. package/src/client/interface.ts +19 -15
  158. package/src/client/p2p_client.ts +108 -92
  159. package/src/config.ts +52 -1
  160. package/src/index.ts +1 -0
  161. package/src/mem_pools/attestation_pool/attestation_pool.ts +15 -1
  162. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +155 -4
  163. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +28 -1
  164. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +28 -2
  165. package/src/mem_pools/attestation_pool/mocks.ts +1 -3
  166. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +59 -41
  167. package/src/mem_pools/tx_pool/memory_tx_pool.ts +19 -9
  168. package/src/mem_pools/tx_pool/tx_pool.ts +7 -2
  169. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +63 -40
  170. package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
  171. package/src/msg_validators/tx_validator/block_header_validator.ts +2 -2
  172. package/src/msg_validators/tx_validator/data_validator.ts +36 -27
  173. package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
  174. package/src/msg_validators/tx_validator/gas_validator.ts +4 -4
  175. package/src/msg_validators/tx_validator/metadata_validator.ts +22 -28
  176. package/src/msg_validators/tx_validator/phases_validator.ts +2 -2
  177. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -2
  178. package/src/services/discv5/discV5_service.ts +4 -1
  179. package/src/services/dummy_service.ts +44 -4
  180. package/src/services/index.ts +3 -1
  181. package/src/services/libp2p/libp2p_service.ts +147 -55
  182. package/src/services/peer-manager/interface.ts +10 -1
  183. package/src/services/peer-manager/peer_manager.ts +441 -41
  184. package/src/services/reqresp/config.ts +3 -3
  185. package/src/services/reqresp/connection-sampler/connection_sampler.ts +38 -63
  186. package/src/services/reqresp/index.ts +2 -0
  187. package/src/services/reqresp/interface.ts +63 -17
  188. package/src/services/reqresp/protocols/auth.ts +83 -0
  189. package/src/services/reqresp/protocols/block.ts +24 -3
  190. package/src/services/reqresp/protocols/block_txs/bitvector.ts +90 -0
  191. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +53 -0
  192. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +79 -0
  193. package/src/services/reqresp/protocols/block_txs/index.ts +3 -0
  194. package/src/services/reqresp/protocols/goodbye.ts +3 -3
  195. package/src/services/reqresp/protocols/index.ts +2 -0
  196. package/src/services/reqresp/protocols/status.ts +20 -0
  197. package/src/services/reqresp/protocols/tx.ts +35 -6
  198. package/src/services/reqresp/rate-limiter/rate_limits.ts +20 -0
  199. package/src/services/reqresp/reqresp.ts +294 -264
  200. package/src/services/reqresp/status.ts +9 -3
  201. package/src/services/service.ts +23 -14
  202. package/src/services/tx_collection/config.ts +84 -0
  203. package/src/services/tx_collection/fast_tx_collection.ts +338 -0
  204. package/src/services/tx_collection/index.ts +2 -0
  205. package/src/services/tx_collection/instrumentation.ts +43 -0
  206. package/src/services/tx_collection/slow_tx_collection.ts +232 -0
  207. package/src/services/tx_collection/tx_collection.ts +214 -0
  208. package/src/services/tx_collection/tx_collection_sink.ts +98 -0
  209. package/src/services/tx_collection/tx_source.ts +37 -0
  210. package/src/services/tx_provider.ts +215 -0
  211. package/src/services/{tx_collect_instrumentation.ts → tx_provider_instrumentation.ts} +5 -5
  212. package/src/test-helpers/make-test-p2p-clients.ts +4 -2
  213. package/src/test-helpers/mock-pubsub.ts +1 -0
  214. package/src/test-helpers/reqresp-nodes.ts +7 -1
  215. package/src/testbench/p2p_client_testbench_worker.ts +9 -2
  216. package/src/util.ts +1 -1
  217. package/dest/services/tx_collect_instrumentation.d.ts.map +0 -1
  218. package/dest/services/tx_collector.d.ts +0 -23
  219. package/dest/services/tx_collector.d.ts.map +0 -1
  220. package/dest/services/tx_collector.js +0 -95
  221. package/src/services/tx_collector.ts +0 -134
package/src/config.ts CHANGED
@@ -16,11 +16,12 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
16
16
  import { type AllowedElement, type ChainConfig, chainConfigMappings } from '@aztec/stdlib/config';
17
17
 
18
18
  import { type P2PReqRespConfig, p2pReqRespConfigMappings } from './services/reqresp/config.js';
19
+ import { type TxCollectionConfig, txCollectionConfigMappings } from './services/tx_collection/config.js';
19
20
 
20
21
  /**
21
22
  * P2P client configuration values.
22
23
  */
23
- export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
24
+ export interface P2PConfig extends P2PReqRespConfig, ChainConfig, TxCollectionConfig {
24
25
  /** A flag dictating whether the P2P subsystem should be enabled. */
25
26
  p2pEnabled: boolean;
26
27
 
@@ -123,6 +124,9 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
123
124
  /** A list of private peers. */
124
125
  privatePeers: string[];
125
126
 
127
+ /** A list of preferred peers. */
128
+ preferredPeers: string[];
129
+
126
130
  /** The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKB. */
127
131
  p2pStoreMapSizeKb?: number;
128
132
 
@@ -140,6 +144,20 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
140
144
 
141
145
  /** True to disable the status handshake on peer connected. */
142
146
  p2pDisableStatusHandshake?: boolean;
147
+
148
+ /** True to only permit validators to connect */
149
+ p2pAllowOnlyValidators?: boolean;
150
+
151
+ /** True to disable participating in discovery */
152
+ p2pDiscoveryDisabled?: boolean;
153
+ /** Number of auth attempts to allow before peer is banned. Number is inclusive*/
154
+ p2pMaxFailedAuthAttemptsAllowed: number;
155
+
156
+ /** True to simulate discarding transactions. - For testing purposes only*/
157
+ dropTransactions: boolean;
158
+
159
+ /** The probability that a transaction is discarded. - For testing purposes only */
160
+ dropTransactionsProbability: number;
143
161
  }
144
162
 
145
163
  export const DEFAULT_P2P_PORT = 40400;
@@ -150,6 +168,11 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
150
168
  description: 'A flag dictating whether the P2P subsystem should be enabled.',
151
169
  ...booleanConfigHelper(),
152
170
  },
171
+ p2pDiscoveryDisabled: {
172
+ env: 'P2P_DISCOVERY_DISABLED',
173
+ description: 'A flag dictating whether the P2P discovery system should be disabled.',
174
+ ...booleanConfigHelper(false),
175
+ },
153
176
  blockCheckIntervalMS: {
154
177
  env: 'P2P_BLOCK_CHECK_INTERVAL_MS',
155
178
  description: 'The frequency in which to check for new L2 blocks.',
@@ -321,6 +344,13 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
321
344
  'A list of private peer ENRs that will always be persisted and not be used for discovery. Separated by commas.',
322
345
  defaultValue: [],
323
346
  },
347
+ preferredPeers: {
348
+ env: 'P2P_PREFERRED_PEERS',
349
+ parseEnv: (val: string) => val.split(','),
350
+ description:
351
+ 'A list of preferred peer ENRs that will always be persisted and not be used for discovery. Separated by commas.',
352
+ defaultValue: [],
353
+ },
324
354
  p2pStoreMapSizeKb: {
325
355
  env: 'P2P_STORE_MAP_SIZE_KB',
326
356
  parseEnv: (val: string | undefined) => (val ? +val : undefined),
@@ -353,8 +383,29 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
353
383
  description: 'True to disable the status handshake on peer connected.',
354
384
  ...booleanConfigHelper(false),
355
385
  },
386
+ p2pAllowOnlyValidators: {
387
+ env: 'P2P_ALLOW_ONLY_VALIDATORS',
388
+ description: 'True to only permit validators to connect.',
389
+ ...booleanConfigHelper(false),
390
+ },
391
+ p2pMaxFailedAuthAttemptsAllowed: {
392
+ env: 'P2P_MAX_AUTH_FAILED_ATTEMPTS_ALLOWED',
393
+ description: 'Number of auth attempts to allow before peer is banned. Number is inclusive',
394
+ ...numberConfigHelper(3),
395
+ },
396
+ dropTransactions: {
397
+ env: 'P2P_DROP_TX',
398
+ description: 'True to simulate discarding transactions. - For testing purposes only',
399
+ ...booleanConfigHelper(false),
400
+ },
401
+ dropTransactionsProbability: {
402
+ env: 'P2P_DROP_TX_CHANCE',
403
+ description: 'The probability that a transaction is discarded. - For testing purposes only',
404
+ ...floatConfigHelper(0),
405
+ },
356
406
  ...p2pReqRespConfigMappings,
357
407
  ...chainConfigMappings,
408
+ ...txCollectionConfigMappings,
358
409
  };
359
410
 
360
411
  /**
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { createSecp256k1PeerId } from '@libp2p/peer-id-factory';
1
2
  export type { PeerId } from '@libp2p/interface';
2
3
 
3
4
  export * from './bootstrap/bootstrap.js';
@@ -1,4 +1,4 @@
1
- import type { BlockAttestation } from '@aztec/stdlib/p2p';
1
+ import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
2
2
 
3
3
  /**
4
4
  * An Attestation Pool contains attestations collected by a validator
@@ -7,6 +7,20 @@ import type { BlockAttestation } from '@aztec/stdlib/p2p';
7
7
  * from the validator to produce a block, or to serve to other peers.
8
8
  */
9
9
  export interface AttestationPool {
10
+ /**
11
+ * Adds new block proposal to the pool
12
+ */
13
+ addBlockProposal(blockProposal: BlockProposal): Promise<void>;
14
+
15
+ /**
16
+ * Get block proposal by it's ID
17
+ *
18
+ * @param id - The ID of the block proposal to retrieve. The ID is proposal.payload.archive
19
+ *
20
+ * @return The block proposal if it exists, otherwise undefined.
21
+ */
22
+ getBlockProposal(id: string): Promise<BlockProposal | undefined>;
23
+
10
24
  /**
11
25
  * AddAttestations
12
26
  *
@@ -1,6 +1,13 @@
1
1
  import { Secp256k1Signer } from '@aztec/foundation/crypto';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
- import type { BlockAttestation } from '@aztec/stdlib/p2p';
3
+ import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
4
+ import {
5
+ BlockProposal as BlockProposalClass,
6
+ ConsensusPayload,
7
+ SignatureDomainSeparator,
8
+ getHashedSignaturePayloadEthSignedMessage,
9
+ } from '@aztec/stdlib/p2p';
10
+ import { makeHeader } from '@aztec/stdlib/testing';
4
11
  import { TxHash } from '@aztec/stdlib/tx';
5
12
 
6
13
  import { jest } from '@jest/globals';
@@ -33,6 +40,19 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
33
40
  return signers.map(signer => mockAttestation(signer, slotNumber, archive));
34
41
  };
35
42
 
43
+ const mockBlockProposal = (signer: Secp256k1Signer, slotNumber: number, archive: Fr = Fr.random()): BlockProposal => {
44
+ const blockNumber = 1;
45
+ const header = makeHeader(1, 2, slotNumber);
46
+ const payload = new ConsensusPayload(header.toPropose(), archive, header.state);
47
+
48
+ const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
49
+ const signature = signer.sign(hash);
50
+
51
+ const txHashes = [TxHash.random(), TxHash.random()]; // Mock tx hashes
52
+
53
+ return new BlockProposalClass(blockNumber, payload, signature, txHashes);
54
+ };
55
+
36
56
  // We compare buffers as the objects can have cached values attached to them which are not serialised
37
57
  // using array containing as the kv store does not respect insertion order
38
58
  const compareAttestations = (a1: BlockAttestation[], a2: BlockAttestation[]) => {
@@ -83,13 +103,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
83
103
  it('should handle duplicate proposals in a slot', async () => {
84
104
  const slotNumber = 420;
85
105
  const archive = Fr.random();
86
- const txs = [0, 1, 2, 3, 4, 5].map(() => TxHash.random());
87
106
 
88
107
  // Use the same signer for all attestations
89
108
  const attestations: BlockAttestation[] = [];
90
109
  const signer = signers[0];
91
110
  for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
92
- attestations.push(mockAttestation(signer, slotNumber, archive, txs));
111
+ attestations.push(mockAttestation(signer, slotNumber, archive));
93
112
  }
94
113
 
95
114
  // Add them to store and check we end up with only one
@@ -98,7 +117,6 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
98
117
  const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(BigInt(slotNumber), archive.toString());
99
118
  expect(retreivedAttestations.length).toBe(1);
100
119
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
101
- expect(retreivedAttestations[0].payload.txHashes).toEqual(txs);
102
120
  expect(retreivedAttestations[0].getSender().toString()).toEqual(signer.address.toString());
103
121
 
104
122
  // Try adding them on another operation and check they are still not duplicated
@@ -234,4 +252,137 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
234
252
  expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(69));
235
253
  expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72));
236
254
  });
255
+
256
+ describe('BlockProposal in attestation pool', () => {
257
+ it('should add and retrieve block proposal', async () => {
258
+ const slotNumber = 420;
259
+ const archive = Fr.random();
260
+ const proposal = mockBlockProposal(signers[0], slotNumber, archive);
261
+ const proposalId = proposal.archive.toString();
262
+
263
+ await ap.addBlockProposal(proposal);
264
+
265
+ const retrievedProposal = await ap.getBlockProposal(proposalId);
266
+
267
+ // This are cached values, so we need to call them to ensure they are not undefined
268
+ retrievedProposal!.payload.getSize();
269
+ retrievedProposal!.signature.getSize();
270
+
271
+ expect(retrievedProposal).toBeDefined();
272
+ expect(retrievedProposal!).toEqual(proposal);
273
+ });
274
+
275
+ it('should return undefined for non-existent block proposal', async () => {
276
+ const nonExistentId = Fr.random().toString();
277
+ const retrievedProposal = await ap.getBlockProposal(nonExistentId);
278
+ expect(retrievedProposal).toBeUndefined();
279
+ });
280
+
281
+ it('should update block proposal if added twice with same id', async () => {
282
+ const slotNumber = 420;
283
+ const archive = Fr.random();
284
+ const proposal1 = mockBlockProposal(signers[0], slotNumber, archive);
285
+ const proposalId = proposal1.archive.toString();
286
+
287
+ await ap.addBlockProposal(proposal1);
288
+
289
+ // Create a new proposal with same archive but different signer
290
+ const proposal2 = mockBlockProposal(signers[1], slotNumber, archive);
291
+
292
+ await ap.addBlockProposal(proposal2);
293
+
294
+ const retrievedProposal = await ap.getBlockProposal(proposalId);
295
+ expect(retrievedProposal).toBeDefined();
296
+ // Should have the second proposal
297
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
298
+ expect(retrievedProposal!.getSender().toString()).toBe(signers[1].address.toString());
299
+ });
300
+
301
+ it('should handle block proposals with different slots and same archive', async () => {
302
+ const archive = Fr.random();
303
+ const proposal1 = mockBlockProposal(signers[0], 100, archive);
304
+ const proposal2 = mockBlockProposal(signers[1], 200, archive);
305
+ const proposalId = archive.toString();
306
+
307
+ await ap.addBlockProposal(proposal1);
308
+ await ap.addBlockProposal(proposal2);
309
+
310
+ // Should get the latest one added
311
+ const retrievedProposal = await ap.getBlockProposal(proposalId);
312
+ expect(retrievedProposal).toBeDefined();
313
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
314
+ expect(retrievedProposal!.slotNumber.toBigInt()).toBe(BigInt(200));
315
+ });
316
+
317
+ it('should delete block proposal when deleting attestations for slot and proposal', async () => {
318
+ const slotNumber = 420;
319
+ const archive = Fr.random();
320
+ const proposal = mockBlockProposal(signers[0], slotNumber, archive);
321
+ const proposalId = proposal.archive.toString();
322
+
323
+ // Add proposal and some attestations
324
+ await ap.addBlockProposal(proposal);
325
+ const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
326
+ await ap.addAttestations(attestations);
327
+
328
+ // Verify proposal exists
329
+ let retrievedProposal = await ap.getBlockProposal(proposalId);
330
+ expect(retrievedProposal).toBeDefined();
331
+
332
+ // Delete attestations for slot and proposal
333
+ await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
334
+
335
+ // Proposal should be deleted
336
+ retrievedProposal = await ap.getBlockProposal(proposalId);
337
+ expect(retrievedProposal).toBeUndefined();
338
+ });
339
+
340
+ it('should delete block proposal when deleting attestations for slot', async () => {
341
+ const slotNumber = 420;
342
+ const archive = Fr.random();
343
+ const proposal = mockBlockProposal(signers[0], slotNumber, archive);
344
+ const proposalId = proposal.archive.toString();
345
+
346
+ // Add proposal
347
+ await ap.addBlockProposal(proposal);
348
+
349
+ // Verify proposal exists
350
+ let retrievedProposal = await ap.getBlockProposal(proposalId);
351
+ expect(retrievedProposal).toBeDefined();
352
+
353
+ // Delete attestations for slot
354
+ await ap.deleteAttestationsForSlot(BigInt(slotNumber));
355
+
356
+ // Proposal should be deleted
357
+ retrievedProposal = await ap.getBlockProposal(proposalId);
358
+ expect(retrievedProposal).toBeUndefined();
359
+ });
360
+
361
+ it('should be able to fetch both block proposal and attestations', async () => {
362
+ const slotNumber = 420;
363
+ const archive = Fr.random();
364
+ const proposal = mockBlockProposal(signers[0], slotNumber, archive);
365
+ const proposalId = proposal.archive.toString();
366
+
367
+ // Add proposal first
368
+ await ap.addBlockProposal(proposal);
369
+
370
+ // Add attestations for the same proposal
371
+ const attestations = signers.slice(1).map(signer => mockAttestation(signer, slotNumber, archive));
372
+ await ap.addAttestations(attestations);
373
+
374
+ // Retrieve both proposal and attestations
375
+ const retrievedProposal = await ap.getBlockProposal(proposalId);
376
+ const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
377
+
378
+ expect(retrievedProposal).toBeDefined();
379
+ // This are cached values, so we need to call them to ensure they are not undefined
380
+ retrievedProposal!.payload.getSize();
381
+ retrievedProposal!.signature.getSize();
382
+
383
+ expect(retrievedProposal).toEqual(proposal);
384
+
385
+ compareAttestations(retrievedAttestations, attestations);
386
+ });
387
+ });
237
388
  }
@@ -2,7 +2,7 @@ import { Fr } from '@aztec/foundation/fields';
2
2
  import { toArray } from '@aztec/foundation/iterable';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
5
- import { BlockAttestation } from '@aztec/stdlib/p2p';
5
+ import { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
6
6
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
7
7
 
8
8
  import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
@@ -12,6 +12,10 @@ export class KvAttestationPool implements AttestationPool {
12
12
  private metrics: PoolInstrumentation<BlockAttestation>;
13
13
 
14
14
  private attestations: AztecAsyncMap<string, Buffer>;
15
+ private proposals: AztecAsyncMap<
16
+ /* proposal.payload.archive */ string,
17
+ /* buffer representation of proposal */ Buffer
18
+ >;
15
19
  private proposalsForSlot: AztecAsyncMultiMap<string, string>;
16
20
  private attestationsForProposal: AztecAsyncMultiMap<string, string>;
17
21
 
@@ -21,6 +25,7 @@ export class KvAttestationPool implements AttestationPool {
21
25
  private log = createLogger('aztec:attestation_pool'),
22
26
  ) {
23
27
  this.attestations = store.openMap('attestations');
28
+ this.proposals = store.openMap('proposals');
24
29
  this.proposalsForSlot = store.openMultiMap('proposals_for_slot');
25
30
  this.attestationsForProposal = store.openMultiMap('attestations_for_proposal');
26
31
 
@@ -137,6 +142,7 @@ export class KvAttestationPool implements AttestationPool {
137
142
  await this.attestations.delete(attestation);
138
143
  }
139
144
 
145
+ await this.proposals.delete(proposalId);
140
146
  await this.attestationsForProposal.delete(this.getProposalKey(slotFr, proposalId));
141
147
  }
142
148
 
@@ -157,6 +163,7 @@ export class KvAttestationPool implements AttestationPool {
157
163
  await this.attestations.delete(attestation);
158
164
  }
159
165
 
166
+ await this.proposals.delete(proposalId);
160
167
  await this.proposalsForSlot.deleteValue(slotString, proposalId);
161
168
  await this.attestationsForProposal.delete(this.getProposalKey(slotString, proposalId));
162
169
 
@@ -185,4 +192,24 @@ export class KvAttestationPool implements AttestationPool {
185
192
  }
186
193
  });
187
194
  }
195
+
196
+ public async getBlockProposal(id: string): Promise<BlockProposal | undefined> {
197
+ const buffer = await this.proposals.getAsync(id);
198
+ try {
199
+ if (buffer && buffer.length > 0) {
200
+ return BlockProposal.fromBuffer(buffer);
201
+ }
202
+ } catch {
203
+ return Promise.resolve(undefined);
204
+ }
205
+
206
+ return Promise.resolve(undefined);
207
+ }
208
+
209
+ public async addBlockProposal(blockProposal: BlockProposal): Promise<void> {
210
+ await this.store.transactionAsync(async () => {
211
+ await this.proposalsForSlot.set(blockProposal.slotNumber.toString(), blockProposal.archive.toString());
212
+ await this.proposals.set(blockProposal.payload.archive.toString(), blockProposal.toBuffer());
213
+ });
214
+ }
188
215
  }
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
- import type { BlockAttestation } from '@aztec/stdlib/p2p';
2
+ import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
3
3
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
4
4
 
5
5
  import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
@@ -9,12 +9,14 @@ export class InMemoryAttestationPool implements AttestationPool {
9
9
  private metrics: PoolInstrumentation<BlockAttestation>;
10
10
 
11
11
  private attestations: Map</*slot=*/ bigint, Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>>;
12
+ private proposals: Map<string, BlockProposal>;
12
13
 
13
14
  constructor(
14
15
  telemetry: TelemetryClient = getTelemetryClient(),
15
16
  private log = createLogger('p2p:attestation_pool'),
16
17
  ) {
17
18
  this.attestations = new Map();
19
+ this.proposals = new Map();
18
20
  this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL, this.poolStats);
19
21
  }
20
22
 
@@ -106,9 +108,17 @@ export class InMemoryAttestationPool implements AttestationPool {
106
108
  public deleteAttestationsForSlot(slot: bigint): Promise<void> {
107
109
  // We count the number of attestations we are removing
108
110
  const numberOfAttestations = this.#getNumberOfAttestationsInSlot(slot);
111
+ const proposalIdsToDelete = this.attestations.get(slot)?.keys();
112
+ let proposalIdsToDeleteCount = 0;
113
+ proposalIdsToDelete?.forEach(proposalId => {
114
+ this.proposals.delete(proposalId);
115
+ proposalIdsToDeleteCount++;
116
+ });
109
117
 
110
118
  this.attestations.delete(slot);
111
- this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
119
+ this.log.verbose(
120
+ `Removed ${numberOfAttestations} attestations and ${proposalIdsToDeleteCount} proposals for slot ${slot}`,
121
+ );
112
122
 
113
123
  return Promise.resolve();
114
124
  }
@@ -124,6 +134,8 @@ export class InMemoryAttestationPool implements AttestationPool {
124
134
  this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
125
135
  }
126
136
  }
137
+
138
+ this.proposals.delete(proposalId);
127
139
  return Promise.resolve();
128
140
  }
129
141
 
@@ -143,6 +155,20 @@ export class InMemoryAttestationPool implements AttestationPool {
143
155
  }
144
156
  return Promise.resolve();
145
157
  }
158
+
159
+ public addBlockProposal(blockProposal: BlockProposal): Promise<void> {
160
+ // We initialize slot-proposal mapping if it does not exist
161
+ // This is important to ensure we can delete this proposal if there were not attestations for it
162
+ const slotProposalMapping = getSlotOrDefault(this.attestations, blockProposal.slotNumber.toBigInt());
163
+ slotProposalMapping.set(blockProposal.payload.archive.toString(), new Map<string, BlockAttestation>());
164
+
165
+ this.proposals.set(blockProposal.payload.archive.toString(), blockProposal);
166
+ return Promise.resolve();
167
+ }
168
+
169
+ public getBlockProposal(id: string): Promise<BlockProposal | undefined> {
170
+ return Promise.resolve(this.proposals.get(id));
171
+ }
146
172
  }
147
173
 
148
174
  /**
@@ -7,7 +7,6 @@ import {
7
7
  getHashedSignaturePayloadEthSignedMessage,
8
8
  } from '@aztec/stdlib/p2p';
9
9
  import { makeHeader } from '@aztec/stdlib/testing';
10
- import { TxHash } from '@aztec/stdlib/tx';
11
10
 
12
11
  import { type LocalAccount, generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
13
12
 
@@ -31,11 +30,10 @@ export const mockAttestation = (
31
30
  signer: Secp256k1Signer,
32
31
  slot: number = 0,
33
32
  archive: Fr = Fr.random(),
34
- txs: TxHash[] = [0, 1, 2, 3, 4, 5].map(() => TxHash.random()),
35
33
  ): BlockAttestation => {
36
34
  // Use arbitrary numbers for all other than slot
37
35
  const header = makeHeader(1, 2, slot);
38
- const payload = new ConsensusPayload(header.toPropose(), archive, header.state, txs);
36
+ const payload = new ConsensusPayload(header.toPropose(), archive, header.state);
39
37
 
40
38
  const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
41
39
  const signature = signer.sign(hash);
@@ -1,6 +1,7 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
  import { toArray } from '@aztec/foundation/iterable';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
+ import type { TypedEventEmitter } from '@aztec/foundation/types';
4
5
  import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap, AztecAsyncSingleton } from '@aztec/kv-store';
5
6
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
6
7
  import { GasFees } from '@aztec/stdlib/gas';
@@ -12,17 +13,18 @@ import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
12
13
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
13
14
 
14
15
  import assert from 'assert';
16
+ import EventEmitter from 'node:events';
15
17
 
16
18
  import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
17
19
  import { GasTxValidator } from '../../msg_validators/tx_validator/gas_validator.js';
18
20
  import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
19
21
  import { getPendingTxPriority } from './priority.js';
20
- import type { TxPool, TxPoolOptions } from './tx_pool.js';
22
+ import type { TxPool, TxPoolEvents, TxPoolOptions } from './tx_pool.js';
21
23
 
22
24
  /**
23
25
  * KV implementation of the Transaction Pool.
24
26
  */
25
- export class AztecKVTxPool implements TxPool {
27
+ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<TxPoolEvents>) implements TxPool {
26
28
  #store: AztecAsyncKVStore;
27
29
 
28
30
  /** Our tx pool, stored as a Map, with K: tx hash and V: the transaction. */
@@ -90,6 +92,8 @@ export class AztecKVTxPool implements TxPool {
90
92
  config: TxPoolOptions = {},
91
93
  log = createLogger('p2p:tx_pool'),
92
94
  ) {
95
+ super();
96
+
93
97
  this.#log = log;
94
98
  this.updateConfig(config);
95
99
 
@@ -276,11 +280,9 @@ export class AztecKVTxPool implements TxPool {
276
280
  * @param txs - An array of txs to be added to the pool.
277
281
  * @returns Empty promise.
278
282
  */
279
- public async addTxs(txs: Tx[]): Promise<number> {
280
- let addedCount = 0;
281
- const hashesAndStats = await Promise.all(
282
- txs.map(async tx => ({ txHash: await tx.getTxHash(), txStats: await tx.getStats() })),
283
- );
283
+ public async addTxs(txs: Tx[], opts: { source?: string } = {}): Promise<number> {
284
+ const addedTxs: Tx[] = [];
285
+ const hashesAndStats = txs.map(tx => ({ txHash: tx.getTxHash(), txStats: tx.getStats() }));
284
286
  await this.#store.transactionAsync(async () => {
285
287
  let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
286
288
  await Promise.all(
@@ -298,9 +300,9 @@ export class AztecKVTxPool implements TxPool {
298
300
  } satisfies TxAddedToPoolStats);
299
301
 
300
302
  await this.#txs.set(key, tx.toBuffer());
303
+ addedTxs.push(tx as Tx);
301
304
 
302
305
  if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
303
- addedCount++;
304
306
  pendingTxSize += tx.getSize();
305
307
  await this.addPendingTxIndices(tx, key);
306
308
  this.#metrics.recordSize(tx);
@@ -312,7 +314,10 @@ export class AztecKVTxPool implements TxPool {
312
314
  await this.evictLowPriorityTxs(hashesAndStats.map(({ txHash }) => txHash));
313
315
  });
314
316
 
315
- return addedCount;
317
+ if (addedTxs.length > 0) {
318
+ this.emit('txs-added', { ...opts, txs: addedTxs });
319
+ }
320
+ return addedTxs.length;
316
321
  }
317
322
 
318
323
  /**
@@ -321,6 +326,9 @@ export class AztecKVTxPool implements TxPool {
321
326
  * @returns Empty promise.
322
327
  */
323
328
  public deleteTxs(txHashes: TxHash[], eviction = false): Promise<void> {
329
+ if (txHashes.length === 0) {
330
+ return Promise.resolve();
331
+ }
324
332
  const deletedTxs: Tx[] = [];
325
333
  const poolDbTx = this.#store.transactionAsync(async () => {
326
334
  let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
@@ -346,7 +354,7 @@ export class AztecKVTxPool implements TxPool {
346
354
 
347
355
  await this.#pendingTxSize.set(pendingTxSize);
348
356
  });
349
-
357
+ this.#log.debug(`Deleted ${txHashes.length} txs from pool`, { txHashes });
350
358
  return this.#archivedTxLimit ? poolDbTx.then(() => this.archiveTxs(deletedTxs)) : poolDbTx;
351
359
  }
352
360
 
@@ -451,36 +459,46 @@ export class AztecKVTxPool implements TxPool {
451
459
  * @returns Empty promise.
452
460
  */
453
461
  private async archiveTxs(txs: Tx[]): Promise<void> {
454
- const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
455
- await this.#archive.transactionAsync(async () => {
456
- // calcualte the head and tail indices of the archived txs by insertion order.
457
- let headIdx =
458
- ((await this.#archivedTxIndices.entriesAsync({ limit: 1, reverse: true }).next()).value?.[0] ?? -1) + 1;
459
- let tailIdx = (await this.#archivedTxIndices.entriesAsync({ limit: 1 }).next()).value?.[0] ?? 0;
460
-
461
- for (let i = 0; i < txs.length; i++) {
462
- const tx = txs[i];
463
- while (headIdx - tailIdx >= this.#archivedTxLimit) {
464
- const txHash = await this.#archivedTxIndices.getAsync(tailIdx);
465
- if (txHash) {
466
- await this.#archivedTxs.delete(txHash);
467
- await this.#archivedTxIndices.delete(tailIdx);
462
+ if (txs.length === 0) {
463
+ return;
464
+ }
465
+ try {
466
+ const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
467
+ await this.#archive.transactionAsync(async () => {
468
+ // calculate the head and tail indices of the archived txs by insertion order.
469
+ let headIdx =
470
+ ((await this.#archivedTxIndices.entriesAsync({ limit: 1, reverse: true }).next()).value?.[0] ?? -1) + 1;
471
+ let tailIdx = (await this.#archivedTxIndices.entriesAsync({ limit: 1 }).next()).value?.[0] ?? 0;
472
+
473
+ for (let i = 0; i < txs.length; i++) {
474
+ const tx = txs[i];
475
+ while (headIdx - tailIdx >= this.#archivedTxLimit) {
476
+ const txHash = await this.#archivedTxIndices.getAsync(tailIdx);
477
+ if (txHash) {
478
+ await this.#archivedTxs.delete(txHash);
479
+ await this.#archivedTxIndices.delete(tailIdx);
480
+ }
481
+ tailIdx++;
468
482
  }
469
- tailIdx++;
470
- }
471
483
 
472
- const archivedTx: Tx = new Tx(
473
- tx.data,
474
- ClientIvcProof.empty(),
475
- tx.contractClassLogFields,
476
- tx.publicFunctionCalldata,
477
- );
478
- const txHash = txHashes[i].toString();
479
- await this.#archivedTxs.set(txHash, archivedTx.toBuffer());
480
- await this.#archivedTxIndices.set(headIdx, txHash);
481
- headIdx++;
482
- }
483
- });
484
+ const archivedTx: Tx = new Tx(
485
+ tx.txHash,
486
+ tx.data,
487
+ ClientIvcProof.empty(),
488
+ tx.contractClassLogFields,
489
+ tx.publicFunctionCalldata,
490
+ );
491
+ const txHash = txHashes[i].toString();
492
+ await this.#archivedTxs.set(txHash, archivedTx.toBuffer());
493
+ await this.#archivedTxIndices.set(headIdx, txHash);
494
+ headIdx++;
495
+ }
496
+ this.#log.debug(`Archived ${txs.length} txs`, { txHashes });
497
+ this.#log.debug(`Total archived txs: ${headIdx - tailIdx}`);
498
+ });
499
+ } catch (error) {
500
+ this.#log.error(`Error archiving txs`, { error });
501
+ }
484
502
  }
485
503
 
486
504
  /**
@@ -591,10 +609,10 @@ export class AztecKVTxPool implements TxPool {
591
609
  }
592
610
 
593
611
  // Evict pending txs with an expiration timestamp less than or equal to the mined block timestamp
594
- const includeByTimestamp = tx.data.rollupValidationRequests.includeByTimestamp;
595
- if (includeByTimestamp.isSome && includeByTimestamp.value <= timestamp) {
612
+ const includeByTimestamp = tx.data.includeByTimestamp;
613
+ if (includeByTimestamp <= timestamp) {
596
614
  this.#log.verbose(
597
- `Evicting tx ${txHash} from pool due to the tx being expired (includeByTimestamp: ${includeByTimestamp.value}, mined block timestamp: ${timestamp})`,
615
+ `Evicting tx ${txHash} from pool due to the tx being expired (includeByTimestamp: ${includeByTimestamp}, mined block timestamp: ${timestamp})`,
598
616
  );
599
617
  txsToEvict.push(TxHash.fromString(txHash));
600
618
  continue;