@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.
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +129 -118
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +3 -3
- package/package.json +14 -14
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +132 -121
- package/src/msg_validators/tx_validator/gas_validator.ts +11 -3
|
@@ -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(
|
|
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
|
-
//
|
|
42
|
-
await this.worldState.syncImmediate(
|
|
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
|
-
*
|
|
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,
|
|
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,
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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,
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfcG9vbF92Ml9pbXBsLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbWVtX3Bvb2xzL3R4X3Bvb2xfdjIvdHhfcG9vbF92Ml9pbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUl4RSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFpQixNQUFNLHFCQUFxQixDQUFDO0FBRzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBb0IsTUFBTSxrQkFBa0IsQ0FBQztBQUM3RSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQW9CL0QsT0FBTyxFQUNMLEtBQUssWUFBWSxFQUVqQixLQUFLLGNBQWMsRUFDbkIsS0FBSyxjQUFjLEVBQ25CLEtBQUssb0JBQW9CLEVBQzFCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFtQixLQUFLLE9BQU8sRUFBMkMsTUFBTSxrQkFBa0IsQ0FBQztBQUcxRzs7R0FFRztBQUNILE1BQU0sV0FBVyxpQkFBaUI7SUFDaEMsVUFBVSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRTtRQUFFLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQzNELFlBQVksRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUM7Q0FDdkQ7QUFFRDs7OztHQUlHO0FBQ0gscUJBQWEs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
|
|
@@ -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,
|
|
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
|
-
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
328
|
-
|
|
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
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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
|
-
|
|
471
|
-
|
|
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
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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,
|
|
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":"
|
|
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 {
|
|
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(
|
|
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 >
|
|
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
|
+
"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.
|
|
71
|
-
"@aztec/epoch-cache": "4.0.0-rc.
|
|
72
|
-
"@aztec/ethereum": "4.0.0-rc.
|
|
73
|
-
"@aztec/foundation": "4.0.0-rc.
|
|
74
|
-
"@aztec/kv-store": "4.0.0-rc.
|
|
75
|
-
"@aztec/noir-contracts.js": "4.0.0-rc.
|
|
76
|
-
"@aztec/noir-protocol-circuits-types": "4.0.0-rc.
|
|
77
|
-
"@aztec/protocol-contracts": "4.0.0-rc.
|
|
78
|
-
"@aztec/simulator": "4.0.0-rc.
|
|
79
|
-
"@aztec/stdlib": "4.0.0-rc.
|
|
80
|
-
"@aztec/telemetry-client": "4.0.0-rc.
|
|
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.
|
|
108
|
-
"@aztec/world-state": "4.0.0-rc.
|
|
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(
|
|
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
|
-
//
|
|
49
|
-
await this.worldState.syncImmediate(
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
401
|
-
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
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
|
-
|
|
476
|
-
|
|
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
|
-
|
|
483
|
-
|
|
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
|
-
|
|
486
|
-
|
|
490
|
+
// Step 1: Find expired protected txs
|
|
491
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
487
492
|
|
|
488
|
-
|
|
489
|
-
|
|
493
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
494
|
+
this.#indices.clearProtection(expiredProtected);
|
|
490
495
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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
|
-
|
|
503
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
499
504
|
|
|
500
|
-
|
|
501
|
-
|
|
505
|
+
// Step 4: Validate for pending pool
|
|
506
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
502
507
|
|
|
503
|
-
|
|
504
|
-
|
|
508
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
509
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
505
510
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
511
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
512
|
+
await this.#deleteTxsBatch(invalid);
|
|
513
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
509
514
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
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
|
-
|
|
557
|
-
|
|
563
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
564
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
558
565
|
|
|
559
|
-
|
|
560
|
-
|
|
566
|
+
// Step 5: Validate for pending pool
|
|
567
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
561
568
|
|
|
562
|
-
|
|
563
|
-
|
|
569
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
570
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
564
571
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
572
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
573
|
+
await this.#deleteTxsBatch(invalid);
|
|
574
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
568
575
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
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
|
-
|
|
575
|
-
|
|
576
|
-
|
|
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
|
-
|
|
581
|
-
|
|
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
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
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
|
-
|
|
604
|
-
|
|
613
|
+
// Step 3: Delete mined txs from active pool
|
|
614
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
605
615
|
|
|
606
|
-
|
|
607
|
-
|
|
616
|
+
// Step 4: Finalize soft-deleted txs
|
|
617
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
608
618
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
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 {
|
|
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(
|
|
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 >
|
|
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,
|