@aztec/p2p 4.0.0-rc.3 → 4.0.0-rc.5

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.
@@ -30,7 +30,7 @@ import { EvictionEvent } from './interfaces.js';
30
30
  return await this.evictForFeePayers(context.feePayers, this.worldState.getSnapshot(blockNumber), pool);
31
31
  }
32
32
  if (context.event === EvictionEvent.CHAIN_PRUNED) {
33
- await this.worldState.syncImmediate(context.blockNumber);
33
+ await this.worldState.syncImmediate();
34
34
  const feePayers = pool.getPendingFeePayers();
35
35
  return await this.evictForFeePayers(feePayers, this.worldState.getSnapshot(context.blockNumber), pool);
36
36
  }
@@ -38,8 +38,8 @@ import { EvictionEvent } from './interfaces.js';
38
38
  }
39
39
  txsByBlockHash.get(blockHashStr).push(meta.txHash);
40
40
  }
41
- // Ensure world state is synced to this block before accessing the snapshot
42
- await this.worldState.syncImmediate(context.blockNumber);
41
+ // Sync without a block number to ensure the world state processes the prune event.
42
+ await this.worldState.syncImmediate();
43
43
  const db = this.worldState.getSnapshot(context.blockNumber);
44
44
  // Check which blocks exist in the archive
45
45
  const blockHashArray = Array.from(uniqueBlockHashes.values());
@@ -1,7 +1,7 @@
1
1
  import type { EvictionConfig, EvictionContext, EvictionResult, EvictionRule, PoolOperations } from './interfaces.js';
2
2
  /**
3
3
  * Eviction rule that removes low-priority transactions when the pool exceeds configured limits.
4
- * Only triggers on TXS_ADDED events.
4
+ * Triggers on TXS_ADDED and CHAIN_PRUNED events.
5
5
  */
6
6
  export declare class LowPriorityEvictionRule implements EvictionRule {
7
7
  readonly name = "LowPriorityEviction";
@@ -13,4 +13,4 @@ export declare class LowPriorityEvictionRule implements EvictionRule {
13
13
  evict(context: EvictionContext, pool: PoolOperations): Promise<EvictionResult>;
14
14
  updateConfig(config: EvictionConfig): void;
15
15
  }
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG93X3ByaW9yaXR5X2V2aWN0aW9uX3J1bGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9tZW1fcG9vbHMvdHhfcG9vbF92Mi9ldmljdGlvbi9sb3dfcHJpb3JpdHlfZXZpY3Rpb25fcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHckg7OztHQUdHO0FBQ0gscUJBQWEsdUJBQXdCLFlBQVcsWUFBWTtJQUMxRCxTQUFnQixJQUFJLHlCQUF5QjtJQUU3QyxPQUFPLENBQUMsR0FBRyxDQUE2RDtJQUN4RSxPQUFPLENBQUMsV0FBVyxDQUFTO0lBRTVCLFlBQVksTUFBTSxFQUFFO1FBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEVBRTFDO0lBRUssS0FBSyxDQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBNERuRjtJQUVELFlBQVksQ0FBQyxNQUFNLEVBQUUsY0FBYyxHQUFHLElBQUksQ0FJekM7Q0FDRiJ9
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG93X3ByaW9yaXR5X2V2aWN0aW9uX3J1bGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9tZW1fcG9vbHMvdHhfcG9vbF92Mi9ldmljdGlvbi9sb3dfcHJpb3JpdHlfZXZpY3Rpb25fcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHckg7OztHQUdHO0FBQ0gscUJBQWEsdUJBQXdCLFlBQVcsWUFBWTtJQUMxRCxTQUFnQixJQUFJLHlCQUF5QjtJQUU3QyxPQUFPLENBQUMsR0FBRyxDQUE2RDtJQUN4RSxPQUFPLENBQUMsV0FBVyxDQUFTO0lBRTVCLFlBQVksTUFBTSxFQUFFO1FBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEVBRTFDO0lBRUssS0FBSyxDQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBZ0VuRjtJQUVELFlBQVksQ0FBQyxNQUFNLEVBQUUsY0FBYyxHQUFHLElBQUksQ0FJekM7Q0FDRiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"low_priority_eviction_rule.d.ts","sourceRoot":"","sources":["../../../../src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGrH;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,YAAY;IAC1D,SAAgB,IAAI,yBAAyB;IAE7C,OAAO,CAAC,GAAG,CAA6D;IACxE,OAAO,CAAC,WAAW,CAAS;IAE5B,YAAY,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,EAE1C;IAEK,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CA4DnF;IAED,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAIzC;CACF"}
1
+ {"version":3,"file":"low_priority_eviction_rule.d.ts","sourceRoot":"","sources":["../../../../src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGrH;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,YAAY;IAC1D,SAAgB,IAAI,yBAAyB;IAE7C,OAAO,CAAC,GAAG,CAA6D;IACxE,OAAO,CAAC,WAAW,CAAS;IAE5B,YAAY,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,EAE1C;IAEK,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAgEnF;IAED,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAIzC;CACF"}
@@ -2,7 +2,7 @@ import { createLogger } from '@aztec/foundation/log';
2
2
  import { EvictionEvent } from './interfaces.js';
3
3
  /**
4
4
  * Eviction rule that removes low-priority transactions when the pool exceeds configured limits.
5
- * Only triggers on TXS_ADDED events.
5
+ * Triggers on TXS_ADDED and CHAIN_PRUNED events.
6
6
  */ export class LowPriorityEvictionRule {
7
7
  name = 'LowPriorityEviction';
8
8
  log = createLogger('p2p:tx_pool_v2:low_priority_eviction_rule');
@@ -11,7 +11,7 @@ import { EvictionEvent } from './interfaces.js';
11
11
  this.maxPoolSize = config.maxPoolSize;
12
12
  }
13
13
  async evict(context, pool) {
14
- if (context.event !== EvictionEvent.TXS_ADDED) {
14
+ if (context.event !== EvictionEvent.TXS_ADDED && context.event !== EvictionEvent.CHAIN_PRUNED) {
15
15
  return {
16
16
  reason: 'low_priority',
17
17
  success: true,
@@ -38,13 +38,17 @@ import { EvictionEvent } from './interfaces.js';
38
38
  this.log.info(`Evicting low priority txs. Pending tx count above limit: ${currentTxCount} > ${this.maxPoolSize}`);
39
39
  const numberToEvict = currentTxCount - this.maxPoolSize;
40
40
  const txsToEvict = pool.getLowestPriorityPending(numberToEvict);
41
- const toEvictSet = new Set(txsToEvict);
42
- const numNewTxsEvicted = context.newTxHashes.filter((newTxHash)=>toEvictSet.has(newTxHash)).length;
43
41
  if (txsToEvict.length > 0) {
44
- this.log.info(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`);
42
+ if (context.event === EvictionEvent.TXS_ADDED) {
43
+ const toEvictSet = new Set(txsToEvict);
44
+ const numNewTxsEvicted = context.newTxHashes.filter((newTxHash)=>toEvictSet.has(newTxHash)).length;
45
+ this.log.info(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`);
46
+ } else {
47
+ this.log.info(`Evicted ${txsToEvict.length} low priority txs after chain prune`);
48
+ }
45
49
  await pool.deleteTxs(txsToEvict, this.name);
46
50
  }
47
- this.log.debug(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`, {
51
+ this.log.debug(`Evicted ${txsToEvict.length} low priority txs`, {
48
52
  txHashes: txsToEvict
49
53
  });
50
54
  return {
@@ -74,4 +74,4 @@ export declare class TxPoolV2Impl {
74
74
  totalMetadataBytes: number;
75
75
  };
76
76
  }
77
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfcG9vbF92Ml9pbXBsLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbWVtX3Bvb2xzL3R4X3Bvb2xfdjIvdHhfcG9vbF92Ml9pbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUl4RSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFpQixNQUFNLHFCQUFxQixDQUFDO0FBRzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBb0IsTUFBTSxrQkFBa0IsQ0FBQztBQUM3RSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQW9CL0QsT0FBTyxFQUNMLEtBQUssWUFBWSxFQUVqQixLQUFLLGNBQWMsRUFDbkIsS0FBSyxjQUFjLEVBQ25CLEtBQUssb0JBQW9CLEVBQzFCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFtQixLQUFLLE9BQU8sRUFBMkMsTUFBTSxrQkFBa0IsQ0FBQztBQUcxRzs7R0FFRztBQUNILE1BQU0sV0FBVyxpQkFBaUI7SUFDaEMsVUFBVSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRTtRQUFFLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQzNELFlBQVksRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUM7Q0FDdkQ7QUFFRDs7OztHQUlHO0FBQ0gscUJBQWEs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
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfcG9vbF92Ml9pbXBsLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbWVtX3Bvb2xzL3R4X3Bvb2xfdjIvdHhfcG9vbF92Ml9pbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUl4RSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFpQixNQUFNLHFCQUFxQixDQUFDO0FBRzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBb0IsTUFBTSxrQkFBa0IsQ0FBQztBQUM3RSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQW9CL0QsT0FBTyxFQUNMLEtBQUssWUFBWSxFQUVqQixLQUFLLGNBQWMsRUFDbkIsS0FBSyxjQUFjLEVBQ25CLEtBQUssb0JBQW9CLEVBQzFCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFtQixLQUFLLE9BQU8sRUFBMkMsTUFBTSxrQkFBa0IsQ0FBQztBQUcxRzs7R0FFRztBQUNILE1BQU0sV0FBVyxpQkFBaUI7SUFDaEMsVUFBVSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRTtRQUFFLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQzNELFlBQVksRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUM7Q0FDdkQ7QUFFRDs7OztHQUlHO0FBQ0gscUJBQWEsWUFBWTs7SUF3QnZCLFlBQ0UsS0FBSyxFQUFFLGlCQUFpQixFQUN4QixZQUFZLEVBQUUsaUJBQWlCLEVBQy9CLElBQUksRUFBRSxvQkFBb0IsRUFDMUIsU0FBUyxFQUFFLGlCQUFpQixFQUM1QixTQUFTLEVBQUUsZUFBZSxFQUMxQixNQUFNLHFDQUE4QixFQUNwQyxZQUFZLEVBQUUsWUFBWSxFQUMxQixHQUFHLEVBQUUsTUFBTSxFQWtDWjtJQU1EOzs7Ozs7T0FNRztJQUNHLG1CQUFtQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0ErQ3pDO0lBRUssYUFBYSxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUU7UUFBRSxNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7UUFBQyxpQkFBaUIsQ0FBQyxFQUFFLE9BQU8sQ0FBQTtLQUFFLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQTZFNUc7SUFnRUssZUFBZSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsR0FBRyxTQUFTLEdBQUcsVUFBVSxDQUFDLENBb0IxRTtJQUVLLGVBQWUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7UUFBRSxNQUFNLENBQUMsRUFBRSxNQUFNLENBQUE7S0FBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0E0QjdGO0lBRUssVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQXFEMUU7SUFFSyxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO1FBQUUsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFBO0tBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBbUJ6RjtJQUVLLGdCQUFnQixDQUFDLEtBQUssRUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQStCcEQ7SUFFSyxjQUFjLENBQUMsVUFBVSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBd0MxRDtJQUVLLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLEVBQUU7UUFBRSxZQUFZLENBQUMsRUFBRSxPQUFPLENBQUE7S0FBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0EwRHBHO0lBRUsscUJBQXFCLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FNN0Q7SUFFSyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FtQzVEO0lBSUssV0FBVyxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FHekQ7SUFFSyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLENBT2xFO0lBRUQsTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FLcEM7SUFFRCxXQUFXLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxPQUFPLEdBQUcsU0FBUyxDQVcvQztJQUVELGtCQUFrQixJQUFJLE1BQU0sRUFBRSxDQUU3QjtJQUVELDBCQUEwQixJQUFJLE1BQU0sRUFBRSxDQUtyQztJQUVELGlCQUFpQixJQUFJLE1BQU0sQ0FFMUI7SUFFRCxnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsRUFBRSxDQUV4QztJQUVELGVBQWUsSUFBSSxNQUFNLENBUXhCO0lBRUQsT0FBTyxJQUFJLE9BQU8sQ0FFakI7SUFFRCxVQUFVLElBQUksTUFBTSxDQUVuQjtJQUVELG1CQUFtQixDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FFM0Q7SUFFRCx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUVoRDtJQUlELFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLElBQUksQ0FhbEQ7SUFJRCxpQkFBaUIsSUFBSSxjQUFjLENBT2xDO0lBSUQsUUFBUSxJQUFJO1FBQ1YsT0FBTyxFQUFFLE1BQU0sQ0FBQztRQUNoQixTQUFTLEVBQUUsTUFBTSxDQUFDO1FBQ2xCLEtBQUssRUFBRSxNQUFNLENBQUM7UUFDZCxXQUFXLEVBQUUsTUFBTSxDQUFDO1FBQ3BCLGtCQUFrQixFQUFFLE1BQU0sQ0FBQztLQUM1QixDQUtBO0NBcVRGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"tx_pool_v2_impl.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AAIxE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAiB,MAAM,qBAAqB,CAAC;AAG7E,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAoB,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAoB/D,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAmB,KAAK,OAAO,EAA2C,MAAM,kBAAkB,CAAC;AAG1G;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CACvD;AAED;;;;GAIG;AACH,qBAAa,YAAY;;IAwBvB,YACE,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,iBAAiB,EAC/B,IAAI,EAAE,oBAAoB,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,eAAe,EAC1B,MAAM,qCAA8B,EACpC,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,MAAM,EAkCZ;IAMD;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CA+CzC;IAEK,aAAa,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CA6E5G;IAgEK,eAAe,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,CAoB1E;IAEK,eAAe,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B7F;IAEK,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmD1E;IAEK,WAAW,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBzF;IAEK,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BpD;IAEK,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC1D;IAEK,kBAAkB,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDpG;IAEK,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D;IAEK,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC5D;IAIK,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,CAGzD;IAEK,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAOlE;IAED,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAKpC;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAW/C;IAED,kBAAkB,IAAI,MAAM,EAAE,CAE7B;IAED,0BAA0B,IAAI,MAAM,EAAE,CAKrC;IAED,iBAAiB,IAAI,MAAM,CAE1B;IAED,gBAAgB,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAExC;IAED,eAAe,IAAI,MAAM,CAQxB;IAED,OAAO,IAAI,OAAO,CAEjB;IAED,UAAU,IAAI,MAAM,CAEnB;IAED,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,CAE3D;IAED,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhD;IAID,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAalD;IAID,iBAAiB,IAAI,cAAc,CAOlC;IAID,QAAQ,IAAI;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAKA;CAqTF"}
1
+ {"version":3,"file":"tx_pool_v2_impl.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts"],"names":[],"mappings":"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"}
@@ -168,6 +168,14 @@ import { TxPoolIndices } from './tx_pool_indices.js';
168
168
  }
169
169
  }
170
170
  }
171
+ // Run post-add eviction rules for pending txs (inside transaction for atomicity)
172
+ if (acceptedPending.size > 0) {
173
+ const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
174
+ const uniqueFeePayers = new Set(feePayers);
175
+ await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
176
+ ...uniqueFeePayers
177
+ ]);
178
+ }
171
179
  });
172
180
  // Build final accepted list for pending txs (excludes intra-batch evictions)
173
181
  for (const txHashStr of acceptedPending){
@@ -180,14 +188,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
180
188
  if (rejected.length > 0) {
181
189
  this.#instrumentation.recordRejected(rejected.length);
182
190
  }
183
- // Run post-add eviction rules for pending txs
184
- if (acceptedPending.size > 0) {
185
- const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
186
- const uniqueFeePayers = new Set(feePayers);
187
- await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
188
- ...uniqueFeePayers
189
- ]);
190
- }
191
191
  return {
192
192
  accepted,
193
193
  ignored,
@@ -305,34 +305,36 @@ import { TxPoolIndices } from './tx_pool_indices.js';
305
305
  const missing = [];
306
306
  let softDeletedHits = 0;
307
307
  let missingPreviouslyEvicted = 0;
308
- for (const txHash of txHashes){
309
- const txHashStr = txHash.toString();
310
- if (this.#indices.has(txHashStr)) {
311
- // Update protection for existing tx
312
- this.#indices.updateProtection(txHashStr, slotNumber);
313
- } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
314
- // Resurrect soft-deleted tx as protected
315
- const buffer = await this.#txsDB.getAsync(txHashStr);
316
- if (buffer) {
317
- const tx = Tx.fromBuffer(buffer);
318
- await this.#addTx(tx, {
319
- protected: slotNumber
320
- });
321
- softDeletedHits++;
308
+ await this.#store.transactionAsync(async ()=>{
309
+ for (const txHash of txHashes){
310
+ const txHashStr = txHash.toString();
311
+ if (this.#indices.has(txHashStr)) {
312
+ // Update protection for existing tx
313
+ this.#indices.updateProtection(txHashStr, slotNumber);
314
+ } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
315
+ // Resurrect soft-deleted tx as protected
316
+ const buffer = await this.#txsDB.getAsync(txHashStr);
317
+ if (buffer) {
318
+ const tx = Tx.fromBuffer(buffer);
319
+ await this.#addTx(tx, {
320
+ protected: slotNumber
321
+ });
322
+ softDeletedHits++;
323
+ } else {
324
+ // Data missing despite soft-delete flag — treat as truly missing
325
+ this.#indices.setProtection(txHashStr, slotNumber);
326
+ missing.push(txHash);
327
+ }
322
328
  } else {
323
- // Data missing despite soft-delete flag treat as truly missing
329
+ // Truly missing pre-record protection for tx we don't have yet
324
330
  this.#indices.setProtection(txHashStr, slotNumber);
325
331
  missing.push(txHash);
326
- }
327
- } else {
328
- // Truly missing — pre-record protection for tx we don't have yet
329
- this.#indices.setProtection(txHashStr, slotNumber);
330
- missing.push(txHash);
331
- if (this.#evictedTxHashes.has(txHashStr)) {
332
- missingPreviouslyEvicted++;
332
+ if (this.#evictedTxHashes.has(txHashStr)) {
333
+ missingPreviouslyEvicted++;
334
+ }
333
335
  }
334
336
  }
335
- }
337
+ });
336
338
  // Record metrics
337
339
  if (softDeletedHits > 0) {
338
340
  this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
@@ -383,44 +385,48 @@ import { TxPoolIndices } from './tx_pool_indices.js';
383
385
  found.push(meta);
384
386
  }
385
387
  }
386
- // Step 4: Mark txs as mined (only those we have in the pool)
387
- for (const meta of found){
388
- this.#indices.markAsMined(meta, blockId);
389
- await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
390
- }
391
- // Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
392
- await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
388
+ await this.#store.transactionAsync(async ()=>{
389
+ // Step 4: Mark txs as mined (only those we have in the pool)
390
+ for (const meta of found){
391
+ this.#indices.markAsMined(meta, blockId);
392
+ await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
393
+ }
394
+ // Step 5: Run post-event eviction rules (inside transaction for atomicity)
395
+ await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
396
+ });
393
397
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
394
398
  }
395
399
  async prepareForSlot(slotNumber) {
396
- // Step 0: Clean up slot-deleted txs from previous slots
397
- await this.#deletedPool.cleanupSlotDeleted(slotNumber);
398
- // Step 1: Find expired protected txs
399
- const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
400
- // Step 2: Clear protection for all expired entries (including those without metadata)
401
- this.#indices.clearProtection(expiredProtected);
402
- // Step 3: Filter to only txs that have metadata and are not mined
403
- const txsToRestore = this.#indices.filterRestorable(expiredProtected);
404
- if (txsToRestore.length === 0) {
405
- this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
406
- return;
407
- }
408
- this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
409
- // Step 4: Validate for pending pool
410
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
411
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
412
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
413
- // Step 6: Delete invalid txs and evict conflict losers
414
- await this.#deleteTxsBatch(invalid);
415
- await this.#evictTxs(toEvict, 'NullifierConflict');
416
- // Step 7: Run eviction rules (enforce pool size limit)
417
- if (added.length > 0) {
418
- const feePayers = added.map((meta)=>meta.feePayer);
419
- const uniqueFeePayers = new Set(feePayers);
420
- await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
421
- ...uniqueFeePayers
422
- ]);
423
- }
400
+ await this.#store.transactionAsync(async ()=>{
401
+ // Step 0: Clean up slot-deleted txs from previous slots
402
+ await this.#deletedPool.cleanupSlotDeleted(slotNumber);
403
+ // Step 1: Find expired protected txs
404
+ const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
405
+ // Step 2: Clear protection for all expired entries (including those without metadata)
406
+ this.#indices.clearProtection(expiredProtected);
407
+ // Step 3: Filter to only txs that have metadata and are not mined
408
+ const txsToRestore = this.#indices.filterRestorable(expiredProtected);
409
+ if (txsToRestore.length === 0) {
410
+ this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
411
+ return;
412
+ }
413
+ this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
414
+ // Step 4: Validate for pending pool
415
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
416
+ // Step 5: Resolve nullifier conflicts and add winners to pending indices
417
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
418
+ // Step 6: Delete invalid txs and evict conflict losers
419
+ await this.#deleteTxsBatch(invalid);
420
+ await this.#evictTxs(toEvict, 'NullifierConflict');
421
+ // Step 7: Run eviction rules (enforce pool size limit)
422
+ if (added.length > 0) {
423
+ const feePayers = added.map((meta)=>meta.feePayer);
424
+ const uniqueFeePayers = new Set(feePayers);
425
+ await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
426
+ ...uniqueFeePayers
427
+ ]);
428
+ }
429
+ });
424
430
  }
425
431
  async handlePrunedBlocks(latestBlock, options) {
426
432
  // Step 1: Find transactions mined after the prune point
@@ -430,45 +436,48 @@ import { TxPoolIndices } from './tx_pool_indices.js';
430
436
  return;
431
437
  }
432
438
  this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
433
- // Step 2: Mark ALL un-mined txs with their original mined block number
434
- // This ensures they get soft-deleted if removed later, and only hard-deleted
435
- // when their original mined block is finalized
436
- await this.#deletedPool.markFromPrunedBlock(txsToUnmine.map((m)=>({
437
- txHash: m.txHash,
438
- minedAtBlock: BlockNumber(m.minedL2BlockId.number)
439
- })));
440
- // Step 3: Unmine - clear mined status from metadata
441
- for (const meta of txsToUnmine){
442
- this.#indices.markAsUnmined(meta);
443
- }
444
- // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
445
- if (options?.deleteAllTxs) {
446
- const allTxHashes = txsToUnmine.map((m)=>m.txHash);
447
- await this.#deleteTxsBatch(allTxHashes);
448
- this.#log.info(`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`);
449
- return;
450
- }
451
- // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
452
- const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
453
- // Step 5: Validate for pending pool
454
- const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
455
- // Step 6: Resolve nullifier conflicts and add winners to pending indices
456
- const { toEvict } = this.#applyNullifierConflictResolution(valid);
457
- // Step 7: Delete invalid txs and evict conflict losers
458
- await this.#deleteTxsBatch(invalid);
459
- await this.#evictTxs(toEvict, 'NullifierConflict');
460
- this.#log.info(`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`, {
461
- txHashesRestored: valid.map((m)=>m.txHash),
462
- txHashesInvalid: invalid,
463
- txHashesEvicted: toEvict
439
+ await this.#store.transactionAsync(async ()=>{
440
+ // Step 2: Mark ALL un-mined txs with their original mined block number
441
+ // This ensures they get soft-deleted if removed later, and only hard-deleted
442
+ // when their original mined block is finalized
443
+ await this.#deletedPool.markFromPrunedBlock(txsToUnmine.map((m)=>({
444
+ txHash: m.txHash,
445
+ minedAtBlock: BlockNumber(m.minedL2BlockId.number)
446
+ })));
447
+ // Step 3: Unmine - clear mined status from metadata
448
+ for (const meta of txsToUnmine){
449
+ this.#indices.markAsUnmined(meta);
450
+ }
451
+ // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
452
+ if (options?.deleteAllTxs) {
453
+ const allTxHashes = txsToUnmine.map((m)=>m.txHash);
454
+ await this.#deleteTxsBatch(allTxHashes);
455
+ this.#log.info(`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`);
456
+ return;
457
+ }
458
+ // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
459
+ const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
460
+ // Step 5: Validate for pending pool
461
+ const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
462
+ // Step 6: Resolve nullifier conflicts and add winners to pending indices
463
+ const { toEvict } = this.#applyNullifierConflictResolution(valid);
464
+ // Step 7: Delete invalid txs and evict conflict losers
465
+ await this.#deleteTxsBatch(invalid);
466
+ await this.#evictTxs(toEvict, 'NullifierConflict');
467
+ this.#log.info(`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`, {
468
+ txHashesRestored: valid.map((m)=>m.txHash),
469
+ txHashesInvalid: invalid,
470
+ txHashesEvicted: toEvict
471
+ });
472
+ // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
473
+ // This handles cases like existing pending txs with invalid fee payer balances
474
+ await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
464
475
  });
465
- // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
466
- // This handles cases like existing pending txs with invalid fee payer balances
467
- await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
468
476
  }
469
477
  async handleFailedExecution(txHashes) {
470
- // Delete failed txs
471
- await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
478
+ await this.#store.transactionAsync(async ()=>{
479
+ await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
480
+ });
472
481
  this.#log.info(`Deleted ${txHashes.length} failed txs`, {
473
482
  txHashes: txHashes.map((h)=>h.toString())
474
483
  });
@@ -477,24 +486,26 @@ import { TxPoolIndices } from './tx_pool_indices.js';
477
486
  const blockNumber = block.globalVariables.blockNumber;
478
487
  // Step 1: Find mined txs at or before finalized block
479
488
  const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
480
- // Step 2: Collect mined txs for archiving (before deletion)
481
- const txsToArchive = [];
482
- if (this.#archive.isEnabled()) {
483
- for (const txHashStr of minedTxsToFinalize){
484
- const buffer = await this.#txsDB.getAsync(txHashStr);
485
- if (buffer) {
486
- txsToArchive.push(Tx.fromBuffer(buffer));
489
+ await this.#store.transactionAsync(async ()=>{
490
+ // Step 2: Collect mined txs for archiving (before deletion)
491
+ const txsToArchive = [];
492
+ if (this.#archive.isEnabled()) {
493
+ for (const txHashStr of minedTxsToFinalize){
494
+ const buffer = await this.#txsDB.getAsync(txHashStr);
495
+ if (buffer) {
496
+ txsToArchive.push(Tx.fromBuffer(buffer));
497
+ }
487
498
  }
488
499
  }
489
- }
490
- // Step 3: Delete mined txs from active pool
491
- await this.#deleteTxsBatch(minedTxsToFinalize);
492
- // Step 4: Finalize soft-deleted txs
493
- await this.#deletedPool.finalizeBlock(blockNumber);
494
- // Step 5: Archive mined txs
495
- if (txsToArchive.length > 0) {
496
- await this.#archive.archiveTxs(txsToArchive);
497
- }
500
+ // Step 3: Delete mined txs from active pool
501
+ await this.#deleteTxsBatch(minedTxsToFinalize);
502
+ // Step 4: Finalize soft-deleted txs
503
+ await this.#deletedPool.finalizeBlock(blockNumber);
504
+ // Step 5: Archive mined txs
505
+ if (txsToArchive.length > 0) {
506
+ await this.#archive.archiveTxs(txsToArchive);
507
+ }
508
+ });
498
509
  if (minedTxsToFinalize.length > 0) {
499
510
  this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
500
511
  txHashes: minedTxsToFinalize
@@ -9,4 +9,4 @@ export declare class GasTxValidator implements TxValidator<Tx> {
9
9
  validateTx(tx: Tx): Promise<TxValidationResult>;
10
10
  validateTxFee(tx: Tx): Promise<TxValidationResult>;
11
11
  }
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FzX3ZhbGlkYXRvci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21zZ192YWxpZGF0b3JzL3R4X3ZhbGlkYXRvci9nYXNfdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBZSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUV2RixPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQU8sT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM3RCxPQUFPLEVBS0wsS0FBSyxFQUFFLEVBQ1AsS0FBSyxrQkFBa0IsRUFDdkIsS0FBSyxXQUFXLEVBQ2pCLE1BQU0sa0JBQWtCLENBQUM7QUFJMUIscUJBQWEsY0FBZSxZQUFXLFdBQVcsQ0FBQyxFQUFFLENBQUM7O0lBTXBELFlBQ0UsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQ25DLGVBQWUsRUFBRSxZQUFZLEVBQzdCLE9BQU8sRUFBRSxPQUFPLEVBQ2hCLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFNMUI7SUFFSyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FTcEQ7SUFtRFksYUFBYSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBeUI5RDtDQUNGIn0=
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FzX3ZhbGlkYXRvci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21zZ192YWxpZGF0b3JzL3R4X3ZhbGlkYXRvci9nYXNfdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sRUFBZSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUV2RixPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQU8sT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM3RCxPQUFPLEVBS0wsS0FBSyxFQUFFLEVBQ1AsS0FBSyxrQkFBa0IsRUFDdkIsS0FBSyxXQUFXLEVBQ2pCLE1BQU0sa0JBQWtCLENBQUM7QUFJMUIscUJBQWEsY0FBZSxZQUFXLFdBQVcsQ0FBQyxFQUFFLENBQUM7O0lBTXBELFlBQ0UsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQ25DLGVBQWUsRUFBRSxZQUFZLEVBQzdCLE9BQU8sRUFBRSxPQUFPLEVBQ2hCLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFNMUI7SUFFSyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FTcEQ7SUFzRFksYUFBYSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBeUI5RDtDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"gas_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/gas_validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAO,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAKL,KAAK,EAAE,EACP,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAI1B,qBAAa,cAAe,YAAW,WAAW,CAAC,EAAE,CAAC;;IAMpD,YACE,gBAAgB,EAAE,iBAAiB,EACnC,eAAe,EAAE,YAAY,EAC7B,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,cAAc,EAM1B;IAEK,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CASpD;IAmDY,aAAa,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyB9D;CACF"}
1
+ {"version":3,"file":"gas_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/gas_validator.ts"],"names":[],"mappings":"AAMA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAO,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAKL,KAAK,EAAE,EACP,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAI1B,qBAAa,cAAe,YAAW,WAAW,CAAC,EAAE,CAAC;;IAMpD,YACE,gBAAgB,EAAE,iBAAiB,EACnC,eAAe,EAAE,YAAY,EAC7B,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,cAAc,EAM1B;IAEK,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CASpD;IAsDY,aAAa,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyB9D;CACF"}
@@ -1,4 +1,4 @@
1
- import { AVM_MAX_PROCESSABLE_L2_GAS, FIXED_DA_GAS, FIXED_L2_GAS } from '@aztec/constants';
1
+ import { MAX_PROCESSABLE_L2_GAS, PRIVATE_TX_L2_GAS_OVERHEAD, PUBLIC_TX_L2_GAS_OVERHEAD, TX_DA_GAS_OVERHEAD } from '@aztec/constants';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
4
4
  import { Gas } from '@aztec/stdlib/gas';
@@ -52,7 +52,7 @@ export class GasTxValidator {
52
52
  * Check whether the tx's gas limit is above the minimum amount.
53
53
  */ #validateGasLimit(tx) {
54
54
  const gasLimits = tx.data.constants.txContext.gasSettings.gasLimits;
55
- const minGasLimits = new Gas(FIXED_DA_GAS, FIXED_L2_GAS);
55
+ const minGasLimits = new Gas(TX_DA_GAS_OVERHEAD, tx.data.forPublic ? PUBLIC_TX_L2_GAS_OVERHEAD : PRIVATE_TX_L2_GAS_OVERHEAD);
56
56
  if (minGasLimits.gtAny(gasLimits)) {
57
57
  this.#log.verbose(`Rejecting transaction due to the gas limit(s) not being above the minimum gas limit`, {
58
58
  gasLimits,
@@ -65,7 +65,7 @@ export class GasTxValidator {
65
65
  ]
66
66
  };
67
67
  }
68
- if (gasLimits.l2Gas > AVM_MAX_PROCESSABLE_L2_GAS) {
68
+ if (gasLimits.l2Gas > MAX_PROCESSABLE_L2_GAS) {
69
69
  this.#log.verbose(`Rejecting transaction due to the gas limit(s) being higher than the maximum processable gas`, {
70
70
  gasLimits,
71
71
  minGasLimits
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "4.0.0-rc.3",
3
+ "version": "4.0.0-rc.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -67,17 +67,17 @@
67
67
  ]
68
68
  },
69
69
  "dependencies": {
70
- "@aztec/constants": "4.0.0-rc.3",
71
- "@aztec/epoch-cache": "4.0.0-rc.3",
72
- "@aztec/ethereum": "4.0.0-rc.3",
73
- "@aztec/foundation": "4.0.0-rc.3",
74
- "@aztec/kv-store": "4.0.0-rc.3",
75
- "@aztec/noir-contracts.js": "4.0.0-rc.3",
76
- "@aztec/noir-protocol-circuits-types": "4.0.0-rc.3",
77
- "@aztec/protocol-contracts": "4.0.0-rc.3",
78
- "@aztec/simulator": "4.0.0-rc.3",
79
- "@aztec/stdlib": "4.0.0-rc.3",
80
- "@aztec/telemetry-client": "4.0.0-rc.3",
70
+ "@aztec/constants": "4.0.0-rc.5",
71
+ "@aztec/epoch-cache": "4.0.0-rc.5",
72
+ "@aztec/ethereum": "4.0.0-rc.5",
73
+ "@aztec/foundation": "4.0.0-rc.5",
74
+ "@aztec/kv-store": "4.0.0-rc.5",
75
+ "@aztec/noir-contracts.js": "4.0.0-rc.5",
76
+ "@aztec/noir-protocol-circuits-types": "4.0.0-rc.5",
77
+ "@aztec/protocol-contracts": "4.0.0-rc.5",
78
+ "@aztec/simulator": "4.0.0-rc.5",
79
+ "@aztec/stdlib": "4.0.0-rc.5",
80
+ "@aztec/telemetry-client": "4.0.0-rc.5",
81
81
  "@chainsafe/libp2p-gossipsub": "13.0.0",
82
82
  "@chainsafe/libp2p-noise": "^15.0.0",
83
83
  "@chainsafe/libp2p-yamux": "^6.0.2",
@@ -104,8 +104,8 @@
104
104
  "xxhash-wasm": "^1.1.0"
105
105
  },
106
106
  "devDependencies": {
107
- "@aztec/archiver": "4.0.0-rc.3",
108
- "@aztec/world-state": "4.0.0-rc.3",
107
+ "@aztec/archiver": "4.0.0-rc.5",
108
+ "@aztec/world-state": "4.0.0-rc.5",
109
109
  "@jest/globals": "^30.0.0",
110
110
  "@types/jest": "^30.0.0",
111
111
  "@types/node": "^22.15.17",
@@ -34,7 +34,7 @@ export class FeePayerBalanceEvictionRule implements EvictionRule {
34
34
  }
35
35
 
36
36
  if (context.event === EvictionEvent.CHAIN_PRUNED) {
37
- await this.worldState.syncImmediate(context.blockNumber);
37
+ await this.worldState.syncImmediate();
38
38
  const feePayers = pool.getPendingFeePayers();
39
39
  return await this.evictForFeePayers(feePayers, this.worldState.getSnapshot(context.blockNumber), pool);
40
40
  }
@@ -45,8 +45,8 @@ export class InvalidTxsAfterReorgRule implements EvictionRule {
45
45
  txsByBlockHash.get(blockHashStr)!.push(meta.txHash);
46
46
  }
47
47
 
48
- // Ensure world state is synced to this block before accessing the snapshot
49
- await this.worldState.syncImmediate(context.blockNumber);
48
+ // Sync without a block number to ensure the world state processes the prune event.
49
+ await this.worldState.syncImmediate();
50
50
  const db = this.worldState.getSnapshot(context.blockNumber);
51
51
 
52
52
  // Check which blocks exist in the archive
@@ -5,7 +5,7 @@ import { EvictionEvent } from './interfaces.js';
5
5
 
6
6
  /**
7
7
  * Eviction rule that removes low-priority transactions when the pool exceeds configured limits.
8
- * Only triggers on TXS_ADDED events.
8
+ * Triggers on TXS_ADDED and CHAIN_PRUNED events.
9
9
  */
10
10
  export class LowPriorityEvictionRule implements EvictionRule {
11
11
  public readonly name = 'LowPriorityEviction';
@@ -18,7 +18,7 @@ export class LowPriorityEvictionRule implements EvictionRule {
18
18
  }
19
19
 
20
20
  async evict(context: EvictionContext, pool: PoolOperations): Promise<EvictionResult> {
21
- if (context.event !== EvictionEvent.TXS_ADDED) {
21
+ if (context.event !== EvictionEvent.TXS_ADDED && context.event !== EvictionEvent.CHAIN_PRUNED) {
22
22
  return {
23
23
  reason: 'low_priority',
24
24
  success: true,
@@ -51,15 +51,19 @@ export class LowPriorityEvictionRule implements EvictionRule {
51
51
  this.log.info(`Evicting low priority txs. Pending tx count above limit: ${currentTxCount} > ${this.maxPoolSize}`);
52
52
  const numberToEvict = currentTxCount - this.maxPoolSize;
53
53
  const txsToEvict = pool.getLowestPriorityPending(numberToEvict);
54
- const toEvictSet = new Set(txsToEvict);
55
- const numNewTxsEvicted = context.newTxHashes.filter(newTxHash => toEvictSet.has(newTxHash)).length;
56
54
 
57
55
  if (txsToEvict.length > 0) {
58
- this.log.info(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`);
56
+ if (context.event === EvictionEvent.TXS_ADDED) {
57
+ const toEvictSet = new Set(txsToEvict);
58
+ const numNewTxsEvicted = context.newTxHashes.filter(newTxHash => toEvictSet.has(newTxHash)).length;
59
+ this.log.info(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`);
60
+ } else {
61
+ this.log.info(`Evicted ${txsToEvict.length} low priority txs after chain prune`);
62
+ }
59
63
  await pool.deleteTxs(txsToEvict, this.name);
60
64
  }
61
65
 
62
- this.log.debug(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`, {
66
+ this.log.debug(`Evicted ${txsToEvict.length} low priority txs`, {
63
67
  txHashes: txsToEvict,
64
68
  });
65
69
 
@@ -234,6 +234,13 @@ export class TxPoolV2Impl {
234
234
  }
235
235
  }
236
236
  }
237
+
238
+ // Run post-add eviction rules for pending txs (inside transaction for atomicity)
239
+ if (acceptedPending.size > 0) {
240
+ const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
241
+ const uniqueFeePayers = new Set<string>(feePayers);
242
+ await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
243
+ }
237
244
  });
238
245
 
239
246
  // Build final accepted list for pending txs (excludes intra-batch evictions)
@@ -249,13 +256,6 @@ export class TxPoolV2Impl {
249
256
  this.#instrumentation.recordRejected(rejected.length);
250
257
  }
251
258
 
252
- // Run post-add eviction rules for pending txs
253
- if (acceptedPending.size > 0) {
254
- const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
255
- const uniqueFeePayers = new Set<string>(feePayers);
256
- await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
257
- }
258
-
259
259
  return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
260
260
  }
261
261
 
@@ -379,33 +379,35 @@ export class TxPoolV2Impl {
379
379
  let softDeletedHits = 0;
380
380
  let missingPreviouslyEvicted = 0;
381
381
 
382
- for (const txHash of txHashes) {
383
- const txHashStr = txHash.toString();
384
-
385
- if (this.#indices.has(txHashStr)) {
386
- // Update protection for existing tx
387
- this.#indices.updateProtection(txHashStr, slotNumber);
388
- } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
389
- // Resurrect soft-deleted tx as protected
390
- const buffer = await this.#txsDB.getAsync(txHashStr);
391
- if (buffer) {
392
- const tx = Tx.fromBuffer(buffer);
393
- await this.#addTx(tx, { protected: slotNumber });
394
- softDeletedHits++;
382
+ await this.#store.transactionAsync(async () => {
383
+ for (const txHash of txHashes) {
384
+ const txHashStr = txHash.toString();
385
+
386
+ if (this.#indices.has(txHashStr)) {
387
+ // Update protection for existing tx
388
+ this.#indices.updateProtection(txHashStr, slotNumber);
389
+ } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
390
+ // Resurrect soft-deleted tx as protected
391
+ const buffer = await this.#txsDB.getAsync(txHashStr);
392
+ if (buffer) {
393
+ const tx = Tx.fromBuffer(buffer);
394
+ await this.#addTx(tx, { protected: slotNumber });
395
+ softDeletedHits++;
396
+ } else {
397
+ // Data missing despite soft-delete flag — treat as truly missing
398
+ this.#indices.setProtection(txHashStr, slotNumber);
399
+ missing.push(txHash);
400
+ }
395
401
  } else {
396
- // Data missing despite soft-delete flag treat as truly missing
402
+ // Truly missing pre-record protection for tx we don't have yet
397
403
  this.#indices.setProtection(txHashStr, slotNumber);
398
404
  missing.push(txHash);
399
- }
400
- } else {
401
- // Truly missing — pre-record protection for tx we don't have yet
402
- this.#indices.setProtection(txHashStr, slotNumber);
403
- missing.push(txHash);
404
- if (this.#evictedTxHashes.has(txHashStr)) {
405
- missingPreviouslyEvicted++;
405
+ if (this.#evictedTxHashes.has(txHashStr)) {
406
+ missingPreviouslyEvicted++;
407
+ }
406
408
  }
407
409
  }
408
- }
410
+ });
409
411
 
410
412
  // Record metrics
411
413
  if (softDeletedHits > 0) {
@@ -466,56 +468,60 @@ export class TxPoolV2Impl {
466
468
  }
467
469
  }
468
470
 
469
- // Step 4: Mark txs as mined (only those we have in the pool)
470
- for (const meta of found) {
471
- this.#indices.markAsMined(meta, blockId);
472
- await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
473
- }
471
+ await this.#store.transactionAsync(async () => {
472
+ // Step 4: Mark txs as mined (only those we have in the pool)
473
+ for (const meta of found) {
474
+ this.#indices.markAsMined(meta, blockId);
475
+ await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
476
+ }
474
477
 
475
- // Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
476
- await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
478
+ // Step 5: Run post-event eviction rules (inside transaction for atomicity)
479
+ await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
480
+ });
477
481
 
478
482
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
479
483
  }
480
484
 
481
485
  async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
482
- // Step 0: Clean up slot-deleted txs from previous slots
483
- await this.#deletedPool.cleanupSlotDeleted(slotNumber);
486
+ await this.#store.transactionAsync(async () => {
487
+ // Step 0: Clean up slot-deleted txs from previous slots
488
+ await this.#deletedPool.cleanupSlotDeleted(slotNumber);
484
489
 
485
- // Step 1: Find expired protected txs
486
- const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
490
+ // Step 1: Find expired protected txs
491
+ const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
487
492
 
488
- // Step 2: Clear protection for all expired entries (including those without metadata)
489
- this.#indices.clearProtection(expiredProtected);
493
+ // Step 2: Clear protection for all expired entries (including those without metadata)
494
+ this.#indices.clearProtection(expiredProtected);
490
495
 
491
- // Step 3: Filter to only txs that have metadata and are not mined
492
- const txsToRestore = this.#indices.filterRestorable(expiredProtected);
493
- if (txsToRestore.length === 0) {
494
- this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
495
- return;
496
- }
496
+ // Step 3: Filter to only txs that have metadata and are not mined
497
+ const txsToRestore = this.#indices.filterRestorable(expiredProtected);
498
+ if (txsToRestore.length === 0) {
499
+ this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
500
+ return;
501
+ }
497
502
 
498
- this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
503
+ this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
499
504
 
500
- // Step 4: Validate for pending pool
501
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
505
+ // Step 4: Validate for pending pool
506
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
502
507
 
503
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
504
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
508
+ // Step 5: Resolve nullifier conflicts and add winners to pending indices
509
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
505
510
 
506
- // Step 6: Delete invalid txs and evict conflict losers
507
- await this.#deleteTxsBatch(invalid);
508
- await this.#evictTxs(toEvict, 'NullifierConflict');
511
+ // Step 6: Delete invalid txs and evict conflict losers
512
+ await this.#deleteTxsBatch(invalid);
513
+ await this.#evictTxs(toEvict, 'NullifierConflict');
509
514
 
510
- // Step 7: Run eviction rules (enforce pool size limit)
511
- if (added.length > 0) {
512
- const feePayers = added.map(meta => meta.feePayer);
513
- const uniqueFeePayers = new Set<string>(feePayers);
514
- await this.#evictionManager.evictAfterNewTxs(
515
- added.map(m => m.txHash),
516
- [...uniqueFeePayers],
517
- );
518
- }
515
+ // Step 7: Run eviction rules (enforce pool size limit)
516
+ if (added.length > 0) {
517
+ const feePayers = added.map(meta => meta.feePayer);
518
+ const uniqueFeePayers = new Set<string>(feePayers);
519
+ await this.#evictionManager.evictAfterNewTxs(
520
+ added.map(m => m.txHash),
521
+ [...uniqueFeePayers],
522
+ );
523
+ }
524
+ });
519
525
  }
520
526
 
521
527
  async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
@@ -528,57 +534,60 @@ export class TxPoolV2Impl {
528
534
 
529
535
  this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
530
536
 
531
- // Step 2: Mark ALL un-mined txs with their original mined block number
532
- // This ensures they get soft-deleted if removed later, and only hard-deleted
533
- // when their original mined block is finalized
534
- await this.#deletedPool.markFromPrunedBlock(
535
- txsToUnmine.map(m => ({
536
- txHash: m.txHash,
537
- minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
538
- })),
539
- );
537
+ await this.#store.transactionAsync(async () => {
538
+ // Step 2: Mark ALL un-mined txs with their original mined block number
539
+ // This ensures they get soft-deleted if removed later, and only hard-deleted
540
+ // when their original mined block is finalized
541
+ await this.#deletedPool.markFromPrunedBlock(
542
+ txsToUnmine.map(m => ({
543
+ txHash: m.txHash,
544
+ minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
545
+ })),
546
+ );
540
547
 
541
- // Step 3: Unmine - clear mined status from metadata
542
- for (const meta of txsToUnmine) {
543
- this.#indices.markAsUnmined(meta);
544
- }
548
+ // Step 3: Unmine - clear mined status from metadata
549
+ for (const meta of txsToUnmine) {
550
+ this.#indices.markAsUnmined(meta);
551
+ }
545
552
 
546
- // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
547
- if (options?.deleteAllTxs) {
548
- const allTxHashes = txsToUnmine.map(m => m.txHash);
549
- await this.#deleteTxsBatch(allTxHashes);
550
- this.#log.info(
551
- `Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
552
- );
553
- return;
554
- }
553
+ // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
554
+ if (options?.deleteAllTxs) {
555
+ const allTxHashes = txsToUnmine.map(m => m.txHash);
556
+ await this.#deleteTxsBatch(allTxHashes);
557
+ this.#log.info(
558
+ `Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
559
+ );
560
+ return;
561
+ }
555
562
 
556
- // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
557
- const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
563
+ // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
564
+ const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
558
565
 
559
- // Step 5: Validate for pending pool
560
- const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
566
+ // Step 5: Validate for pending pool
567
+ const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
561
568
 
562
- // Step 6: Resolve nullifier conflicts and add winners to pending indices
563
- const { toEvict } = this.#applyNullifierConflictResolution(valid);
569
+ // Step 6: Resolve nullifier conflicts and add winners to pending indices
570
+ const { toEvict } = this.#applyNullifierConflictResolution(valid);
564
571
 
565
- // Step 7: Delete invalid txs and evict conflict losers
566
- await this.#deleteTxsBatch(invalid);
567
- await this.#evictTxs(toEvict, 'NullifierConflict');
572
+ // Step 7: Delete invalid txs and evict conflict losers
573
+ await this.#deleteTxsBatch(invalid);
574
+ await this.#evictTxs(toEvict, 'NullifierConflict');
568
575
 
569
- this.#log.info(
570
- `Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
571
- { txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
572
- );
576
+ this.#log.info(
577
+ `Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
578
+ { txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
579
+ );
573
580
 
574
- // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
575
- // This handles cases like existing pending txs with invalid fee payer balances
576
- await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
581
+ // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
582
+ // This handles cases like existing pending txs with invalid fee payer balances
583
+ await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
584
+ });
577
585
  }
578
586
 
579
587
  async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
580
- // Delete failed txs
581
- await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
588
+ await this.#store.transactionAsync(async () => {
589
+ await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
590
+ });
582
591
 
583
592
  this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
584
593
  }
@@ -589,27 +598,29 @@ export class TxPoolV2Impl {
589
598
  // Step 1: Find mined txs at or before finalized block
590
599
  const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
591
600
 
592
- // Step 2: Collect mined txs for archiving (before deletion)
593
- const txsToArchive: Tx[] = [];
594
- if (this.#archive.isEnabled()) {
595
- for (const txHashStr of minedTxsToFinalize) {
596
- const buffer = await this.#txsDB.getAsync(txHashStr);
597
- if (buffer) {
598
- txsToArchive.push(Tx.fromBuffer(buffer));
601
+ await this.#store.transactionAsync(async () => {
602
+ // Step 2: Collect mined txs for archiving (before deletion)
603
+ const txsToArchive: Tx[] = [];
604
+ if (this.#archive.isEnabled()) {
605
+ for (const txHashStr of minedTxsToFinalize) {
606
+ const buffer = await this.#txsDB.getAsync(txHashStr);
607
+ if (buffer) {
608
+ txsToArchive.push(Tx.fromBuffer(buffer));
609
+ }
599
610
  }
600
611
  }
601
- }
602
612
 
603
- // Step 3: Delete mined txs from active pool
604
- await this.#deleteTxsBatch(minedTxsToFinalize);
613
+ // Step 3: Delete mined txs from active pool
614
+ await this.#deleteTxsBatch(minedTxsToFinalize);
605
615
 
606
- // Step 4: Finalize soft-deleted txs
607
- await this.#deletedPool.finalizeBlock(blockNumber);
616
+ // Step 4: Finalize soft-deleted txs
617
+ await this.#deletedPool.finalizeBlock(blockNumber);
608
618
 
609
- // Step 5: Archive mined txs
610
- if (txsToArchive.length > 0) {
611
- await this.#archive.archiveTxs(txsToArchive);
612
- }
619
+ // Step 5: Archive mined txs
620
+ if (txsToArchive.length > 0) {
621
+ await this.#archive.archiveTxs(txsToArchive);
622
+ }
623
+ });
613
624
 
614
625
  if (minedTxsToFinalize.length > 0) {
615
626
  this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
@@ -1,4 +1,9 @@
1
- import { AVM_MAX_PROCESSABLE_L2_GAS, FIXED_DA_GAS, FIXED_L2_GAS } from '@aztec/constants';
1
+ import {
2
+ MAX_PROCESSABLE_L2_GAS,
3
+ PRIVATE_TX_L2_GAS_OVERHEAD,
4
+ PUBLIC_TX_L2_GAS_OVERHEAD,
5
+ TX_DA_GAS_OVERHEAD,
6
+ } from '@aztec/constants';
2
7
  import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
3
8
  import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
4
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -73,7 +78,10 @@ export class GasTxValidator implements TxValidator<Tx> {
73
78
  */
74
79
  #validateGasLimit(tx: Tx): TxValidationResult {
75
80
  const gasLimits = tx.data.constants.txContext.gasSettings.gasLimits;
76
- const minGasLimits = new Gas(FIXED_DA_GAS, FIXED_L2_GAS);
81
+ const minGasLimits = new Gas(
82
+ TX_DA_GAS_OVERHEAD,
83
+ tx.data.forPublic ? PUBLIC_TX_L2_GAS_OVERHEAD : PRIVATE_TX_L2_GAS_OVERHEAD,
84
+ );
77
85
 
78
86
  if (minGasLimits.gtAny(gasLimits)) {
79
87
  this.#log.verbose(`Rejecting transaction due to the gas limit(s) not being above the minimum gas limit`, {
@@ -83,7 +91,7 @@ export class GasTxValidator implements TxValidator<Tx> {
83
91
  return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_GAS_LIMIT] };
84
92
  }
85
93
 
86
- if (gasLimits.l2Gas > AVM_MAX_PROCESSABLE_L2_GAS) {
94
+ if (gasLimits.l2Gas > MAX_PROCESSABLE_L2_GAS) {
87
95
  this.#log.verbose(`Rejecting transaction due to the gas limit(s) being higher than the maximum processable gas`, {
88
96
  gasLimits,
89
97
  minGasLimits,