@aztec/p2p 0.0.1-commit.cd76b27 → 0.0.1-commit.ce4f8c4f2
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/README.md +129 -3
- package/dest/client/factory.d.ts +5 -6
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +28 -26
- package/dest/client/interface.d.ts +6 -13
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +5 -13
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +25 -92
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +4 -5
- package/dest/config.d.ts +33 -15
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +86 -37
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +8 -4
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +16 -14
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +4 -4
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +3 -2
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +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/eviction/low_priority_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +15 -9
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +48 -11
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +81 -17
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -44
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +5 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +3 -2
- 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 +196 -151
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +5 -4
- package/dest/msg_validators/clock_tolerance.d.ts +1 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +4 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +53 -41
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +247 -60
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +4 -2
- package/dest/services/dummy_service.d.ts +2 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +1 -4
- package/dest/services/encoding.d.ts +6 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +14 -8
- package/dest/services/libp2p/libp2p_service.d.ts +20 -20
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +221 -143
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +6 -0
- package/dest/services/peer-manager/peer_manager.d.ts +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +6 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +82 -101
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +19 -10
- package/dest/services/service.d.ts +8 -2
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +57 -73
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
- package/dest/services/tx_collection/request_tracker.d.ts +53 -0
- package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/request_tracker.js +84 -0
- package/dest/services/tx_collection/slow_tx_collection.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +3 -6
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +4 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +7 -3
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +11 -3
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +2 -2
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +22 -3
- package/dest/testbench/p2p_client_testbench_worker.js +10 -9
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -2
- package/dest/util.d.ts +9 -4
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +2 -9
- package/package.json +14 -14
- package/src/client/factory.ts +45 -45
- package/src/client/interface.ts +5 -19
- package/src/client/p2p_client.ts +26 -122
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +5 -8
- package/src/config.ts +125 -43
- package/src/mem_pools/attestation_pool/attestation_pool.ts +8 -7
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/instrumentation.ts +17 -13
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool/priority.ts +4 -4
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
- package/src/mem_pools/tx_pool_v2/README.md +9 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +3 -2
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -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/eviction/low_priority_pre_add_rule.ts +15 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/index.ts +1 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +16 -8
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +115 -20
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +17 -2
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +207 -154
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
- package/src/msg_validators/clock_tolerance.ts +4 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +69 -45
- package/src/msg_validators/tx_validator/README.md +119 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +394 -78
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/services/discv5/discV5_service.ts +4 -2
- package/src/services/dummy_service.ts +1 -5
- package/src/services/encoding.ts +14 -7
- package/src/services/libp2p/libp2p_service.ts +235 -166
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +7 -3
- package/src/services/reqresp/README.md +229 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +78 -111
- package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/reqresp.ts +22 -12
- package/src/services/service.ts +8 -1
- package/src/services/tx_collection/fast_tx_collection.ts +57 -83
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +3 -5
- package/src/services/tx_provider.ts +2 -2
- package/src/test-helpers/make-test-p2p-clients.ts +1 -3
- package/src/test-helpers/mock-pubsub.ts +12 -6
- package/src/test-helpers/reqresp-nodes.ts +3 -6
- package/src/test-helpers/testbench-utils.ts +30 -4
- package/src/testbench/p2p_client_testbench_worker.ts +7 -12
- package/src/testbench/worker_client_manager.ts +13 -5
- package/src/util.ts +9 -13
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
- package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
2
|
|
|
3
|
-
import { type TxMetaData, comparePriority } from '../tx_metadata.js';
|
|
3
|
+
import { type TxMetaData, comparePriority, getMinimumPriceBumpFee } from '../tx_metadata.js';
|
|
4
4
|
import {
|
|
5
5
|
type EvictionConfig,
|
|
6
6
|
type PreAddContext,
|
|
@@ -48,10 +48,14 @@ export class LowPriorityPreAddRule implements PreAddRule {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// Compare incoming tx against lowest priority tx.
|
|
51
|
-
// feeOnly mode (RPC): use strict fee comparison only — avoids churn from hash ordering
|
|
52
|
-
//
|
|
51
|
+
// feeOnly mode (RPC): use strict fee comparison only — avoids churn from hash ordering.
|
|
52
|
+
// When price bump is also set, require the bumped fee threshold.
|
|
53
|
+
// Default (gossip): use full comparePriority (fee + tx hash tiebreaker) for determinism.
|
|
53
54
|
const isHigherPriority = context?.feeComparisonOnly
|
|
54
|
-
?
|
|
55
|
+
? context.priceBumpPercentage !== undefined
|
|
56
|
+
? incomingMeta.priorityFee >=
|
|
57
|
+
getMinimumPriceBumpFee(lowestPriorityMeta.priorityFee, context.priceBumpPercentage)
|
|
58
|
+
: incomingMeta.priorityFee > lowestPriorityMeta.priorityFee
|
|
55
59
|
: comparePriority(incomingMeta, lowestPriorityMeta) > 0;
|
|
56
60
|
|
|
57
61
|
if (isHigherPriority) {
|
|
@@ -66,6 +70,11 @@ export class LowPriorityPreAddRule implements PreAddRule {
|
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
// Incoming tx has equal or lower priority - ignore it (it would be evicted anyway)
|
|
73
|
+
const minimumFee =
|
|
74
|
+
context?.feeComparisonOnly && context.priceBumpPercentage !== undefined
|
|
75
|
+
? getMinimumPriceBumpFee(lowestPriorityMeta.priorityFee, context.priceBumpPercentage)
|
|
76
|
+
: lowestPriorityMeta.priorityFee + 1n;
|
|
77
|
+
|
|
69
78
|
this.log.debug(
|
|
70
79
|
`Pool at capacity (${currentCount}/${this.maxPoolSize}), ignoring ${incomingMeta.txHash} ` +
|
|
71
80
|
`(priority ${incomingMeta.priorityFee}) - lower than existing minimum (priority ${lowestPriorityMeta.priorityFee})`,
|
|
@@ -75,8 +84,8 @@ export class LowPriorityPreAddRule implements PreAddRule {
|
|
|
75
84
|
txHashesToEvict: [],
|
|
76
85
|
reason: {
|
|
77
86
|
code: TxPoolRejectionCode.LOW_PRIORITY_FEE,
|
|
78
|
-
message: `Tx does not meet minimum priority fee. Required: ${
|
|
79
|
-
minimumPriorityFee:
|
|
87
|
+
message: `Tx does not meet minimum priority fee. Required: ${minimumFee}, got: ${incomingMeta.priorityFee}`,
|
|
88
|
+
minimumPriorityFee: minimumFee,
|
|
80
89
|
txPriorityFee: incomingMeta.priorityFee,
|
|
81
90
|
},
|
|
82
91
|
});
|
|
@@ -15,11 +15,12 @@ export class NullifierConflictRule implements PreAddRule {
|
|
|
15
15
|
|
|
16
16
|
private log = createLogger('p2p:tx_pool_v2:nullifier_conflict_rule');
|
|
17
17
|
|
|
18
|
-
check(incomingMeta: TxMetaData, poolAccess: PreAddPoolAccess,
|
|
18
|
+
check(incomingMeta: TxMetaData, poolAccess: PreAddPoolAccess, context?: PreAddContext): Promise<PreAddResult> {
|
|
19
19
|
const result = checkNullifierConflict(
|
|
20
20
|
incomingMeta,
|
|
21
21
|
nullifier => poolAccess.getTxHashByNullifier(nullifier),
|
|
22
22
|
txHash => poolAccess.getMetadata(txHash),
|
|
23
|
+
context?.priceBumpPercentage,
|
|
23
24
|
);
|
|
24
25
|
|
|
25
26
|
if (result.shouldIgnore) {
|
|
@@ -7,6 +7,6 @@ export {
|
|
|
7
7
|
type PoolReadAccess,
|
|
8
8
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
9
9
|
} from './interfaces.js';
|
|
10
|
-
export { type TxMetaData, type TxState, buildTxMetaData, comparePriority } from './tx_metadata.js';
|
|
10
|
+
export { type TxMetaData, type TxState, buildTxMetaData, comparePriority, stubTxMetaData } from './tx_metadata.js';
|
|
11
11
|
export { TxArchive } from './archive/index.js';
|
|
12
12
|
export { DeletedPool } from './deleted_pool.js';
|
|
@@ -44,6 +44,10 @@ export type TxPoolV2Config = {
|
|
|
44
44
|
minTxPoolAgeMs: number;
|
|
45
45
|
/** Maximum number of evicted tx hashes to remember for metrics tracking */
|
|
46
46
|
evictedTxCacheSize: number;
|
|
47
|
+
/** The probability (0-1) that a transaction is discarded. 0 disables dropping. For testing purposes only. */
|
|
48
|
+
dropTransactionsProbability: number;
|
|
49
|
+
/** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */
|
|
50
|
+
priceBumpPercentage: bigint;
|
|
47
51
|
};
|
|
48
52
|
|
|
49
53
|
/**
|
|
@@ -54,6 +58,8 @@ export const DEFAULT_TX_POOL_V2_CONFIG: TxPoolV2Config = {
|
|
|
54
58
|
archivedTxLimit: 0, // 0 = disabled
|
|
55
59
|
minTxPoolAgeMs: 2_000,
|
|
56
60
|
evictedTxCacheSize: 10_000,
|
|
61
|
+
dropTransactionsProbability: 0,
|
|
62
|
+
priceBumpPercentage: 10n,
|
|
57
63
|
};
|
|
58
64
|
|
|
59
65
|
/**
|
|
@@ -66,6 +72,8 @@ export type TxPoolV2Dependencies = {
|
|
|
66
72
|
worldStateSynchronizer: WorldStateSynchronizer;
|
|
67
73
|
/** Factory that creates a validator for re-validating pool transactions using metadata */
|
|
68
74
|
createTxValidator: () => Promise<TxValidator<TxMetaData>>;
|
|
75
|
+
/** Checks whether a tx's setup-phase calls are on the allow list. Precomputed at receipt time. */
|
|
76
|
+
checkAllowedSetupCalls: (tx: Tx) => Promise<boolean>;
|
|
69
77
|
};
|
|
70
78
|
|
|
71
79
|
/**
|
|
@@ -107,12 +115,12 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
|
|
|
107
115
|
addPendingTxs(txs: Tx[], opts?: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult>;
|
|
108
116
|
|
|
109
117
|
/**
|
|
110
|
-
* Checks if
|
|
111
|
-
*
|
|
118
|
+
* Checks if the pool would accept a transaction without modifying state.
|
|
119
|
+
* Used as a pre-check before expensive proof verification.
|
|
112
120
|
* @param tx - Transaction to check
|
|
113
|
-
* @returns
|
|
121
|
+
* @returns 'accepted' if the pool would accept, 'ignored' if already in pool or undesirable
|
|
114
122
|
*/
|
|
115
|
-
canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
123
|
+
canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'>;
|
|
116
124
|
|
|
117
125
|
/**
|
|
118
126
|
* Adds transactions as immediately protected for a given slot.
|
|
@@ -152,10 +160,10 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
|
|
|
152
160
|
handleMinedBlock(block: L2Block): Promise<void>;
|
|
153
161
|
|
|
154
162
|
/**
|
|
155
|
-
* Prepares the pool for a new slot
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
163
|
+
* Prepares the pool for a new slot by unprotecting transactions from earlier
|
|
164
|
+
* slots and re-validating them before returning to pending state.
|
|
165
|
+
* @param slotNumber - The pipeline slot we are building for (i.e. the slot
|
|
166
|
+
* the resulting blocks will target on L1).
|
|
159
167
|
*/
|
|
160
168
|
prepareForSlot(slotNumber: SlotNumber): Promise<void>;
|
|
161
169
|
|
|
@@ -2,7 +2,8 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
3
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
4
4
|
import { BlockHash, type L2BlockId } from '@aztec/stdlib/block';
|
|
5
|
-
import
|
|
5
|
+
import { Gas } from '@aztec/stdlib/gas';
|
|
6
|
+
import { type Tx, TxHash } from '@aztec/stdlib/tx';
|
|
6
7
|
|
|
7
8
|
import { getFeePayerBalanceDelta } from '../../msg_validators/tx_validator/fee_payer_balance.js';
|
|
8
9
|
import { getTxPriorityFee } from '../tx_pool/priority.js';
|
|
@@ -12,6 +13,8 @@ import { type PreAddResult, TxPoolRejectionCode } from './eviction/interfaces.js
|
|
|
12
13
|
export type TxMetaValidationData = {
|
|
13
14
|
getNonEmptyNullifiers(): Fr[];
|
|
14
15
|
expirationTimestamp: bigint;
|
|
16
|
+
/** Whether the tx has public calls. Used to select the correct L2 gas minimum. */
|
|
17
|
+
forPublic?: unknown;
|
|
15
18
|
constants: {
|
|
16
19
|
anchorBlockHeader: {
|
|
17
20
|
hash(): Promise<BlockHash>;
|
|
@@ -19,6 +22,9 @@ export type TxMetaValidationData = {
|
|
|
19
22
|
blockNumber: BlockNumber;
|
|
20
23
|
};
|
|
21
24
|
};
|
|
25
|
+
txContext: {
|
|
26
|
+
gasSettings: { gasLimits: Gas };
|
|
27
|
+
};
|
|
22
28
|
};
|
|
23
29
|
};
|
|
24
30
|
|
|
@@ -34,6 +40,9 @@ export type TxMetaData = {
|
|
|
34
40
|
/** The transaction hash as hex string */
|
|
35
41
|
readonly txHash: string;
|
|
36
42
|
|
|
43
|
+
/** The transaction hash as bigint (for efficient Fr conversion in comparisons) */
|
|
44
|
+
readonly txHashBigInt: bigint;
|
|
45
|
+
|
|
37
46
|
/** Block ID (number and hash) in which the transaction was mined (undefined if not mined) */
|
|
38
47
|
minedL2BlockId?: L2BlockId;
|
|
39
48
|
|
|
@@ -58,6 +67,9 @@ export type TxMetaData = {
|
|
|
58
67
|
/** Timestamp by which the transaction must be included (for expiration checks) */
|
|
59
68
|
readonly expirationTimestamp: bigint;
|
|
60
69
|
|
|
70
|
+
/** Whether the tx's setup-phase calls pass the allow list check. Computed at receipt time. */
|
|
71
|
+
readonly allowedSetupCalls: boolean;
|
|
72
|
+
|
|
61
73
|
/** Validator-compatible data, providing the same access patterns as Tx.data */
|
|
62
74
|
readonly data: TxMetaValidationData;
|
|
63
75
|
|
|
@@ -75,9 +87,15 @@ export type TxState = 'pending' | 'protected' | 'mined' | 'deleted';
|
|
|
75
87
|
* Builds TxMetaData from a full Tx object.
|
|
76
88
|
* Extracts all relevant fields for efficient in-memory storage and querying.
|
|
77
89
|
* Fr values are captured in closures for zero-cost re-validation.
|
|
90
|
+
*
|
|
91
|
+
* @param allowedSetupCalls - Whether the tx's setup-phase calls pass the allow list.
|
|
92
|
+
* For gossip/RPC txs this is always `true` (already validated by PhasesTxValidator).
|
|
93
|
+
* For req/resp txs this should be computed by the caller using the phases validator.
|
|
78
94
|
*/
|
|
79
|
-
export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
|
|
80
|
-
const
|
|
95
|
+
export async function buildTxMetaData(tx: Tx, allowedSetupCalls: boolean = true): Promise<TxMetaData> {
|
|
96
|
+
const txHashObj = tx.getTxHash();
|
|
97
|
+
const txHash = txHashObj.toString();
|
|
98
|
+
const txHashBigInt = txHashObj.toBigInt();
|
|
81
99
|
const nullifierFrs = tx.data.getNonEmptyNullifiers();
|
|
82
100
|
const nullifiers = nullifierFrs.map(n => n.toString());
|
|
83
101
|
const anchorBlockHeaderHashFr = await tx.data.constants.anchorBlockHeader.hash();
|
|
@@ -93,6 +111,7 @@ export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
|
|
|
93
111
|
|
|
94
112
|
return {
|
|
95
113
|
txHash,
|
|
114
|
+
txHashBigInt,
|
|
96
115
|
anchorBlockHeaderHash,
|
|
97
116
|
priorityFee,
|
|
98
117
|
feePayer,
|
|
@@ -100,16 +119,21 @@ export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
|
|
|
100
119
|
feeLimit,
|
|
101
120
|
nullifiers,
|
|
102
121
|
expirationTimestamp,
|
|
122
|
+
allowedSetupCalls,
|
|
103
123
|
receivedAt: 0,
|
|
104
124
|
estimatedSizeBytes,
|
|
105
125
|
data: {
|
|
106
126
|
getNonEmptyNullifiers: () => nullifierFrs,
|
|
107
127
|
expirationTimestamp,
|
|
128
|
+
forPublic: !!tx.data.forPublic,
|
|
108
129
|
constants: {
|
|
109
130
|
anchorBlockHeader: {
|
|
110
131
|
hash: () => Promise.resolve(anchorBlockHeaderHashFr),
|
|
111
132
|
globalVariables: { blockNumber: anchorBlockNumber },
|
|
112
133
|
},
|
|
134
|
+
txContext: {
|
|
135
|
+
gasSettings: { gasLimits: tx.data.constants.txContext.gasSettings.gasLimits },
|
|
136
|
+
},
|
|
113
137
|
},
|
|
114
138
|
},
|
|
115
139
|
};
|
|
@@ -124,11 +148,11 @@ const HEX_STRING_BYTES = 98;
|
|
|
124
148
|
const BIGINT_BYTES = 32;
|
|
125
149
|
const FR_BYTES = 80;
|
|
126
150
|
// Fixed cost: object shell + txHash + anchorBlockHeaderHash + feePayer (3 hex strings)
|
|
127
|
-
// + priorityFee + claimAmount + feeLimit + includeByTimestamp (
|
|
151
|
+
// + txHashBigInt + priorityFee + claimAmount + feeLimit + includeByTimestamp (5 bigints)
|
|
128
152
|
// + receivedAt (number, 8 bytes) + estimatedSizeBytes (number, 8 bytes)
|
|
129
153
|
// + data closure object (~OBJECT_OVERHEAD + anchorBlockHeaderHashFr Fr + anchorBlockNumber number)
|
|
130
154
|
const FIXED_METADATA_BYTES =
|
|
131
|
-
OBJECT_OVERHEAD + 3 * HEX_STRING_BYTES +
|
|
155
|
+
OBJECT_OVERHEAD + 3 * HEX_STRING_BYTES + 5 * BIGINT_BYTES + 8 + 8 + OBJECT_OVERHEAD + FR_BYTES + 8;
|
|
132
156
|
|
|
133
157
|
/** Estimates the in-memory size of a TxMetaData object based on the number of nullifiers. */
|
|
134
158
|
function estimateTxMetaDataSize(nullifierCount: number): number {
|
|
@@ -136,14 +160,19 @@ function estimateTxMetaDataSize(nullifierCount: number): number {
|
|
|
136
160
|
return FIXED_METADATA_BYTES + nullifierCount * (HEX_STRING_BYTES + FR_BYTES);
|
|
137
161
|
}
|
|
138
162
|
|
|
163
|
+
/** Converts a txHash bigint back to the canonical 0x-prefixed 64-char hex string. */
|
|
164
|
+
export function txHashFromBigInt(value: bigint): string {
|
|
165
|
+
return TxHash.fromBigInt(value).toString();
|
|
166
|
+
}
|
|
167
|
+
|
|
139
168
|
/** Minimal fields required for priority comparison. */
|
|
140
|
-
type PriorityComparable = Pick<TxMetaData, 'txHash' | 'priorityFee'>;
|
|
169
|
+
export type PriorityComparable = Pick<TxMetaData, 'txHash' | 'txHashBigInt' | 'priorityFee'>;
|
|
141
170
|
|
|
142
171
|
/**
|
|
143
172
|
* Compares two priority fees in ascending order.
|
|
144
173
|
* Returns negative if a < b, positive if a > b, 0 if equal.
|
|
145
174
|
*/
|
|
146
|
-
export function compareFee(a: bigint, b: bigint):
|
|
175
|
+
export function compareFee(a: bigint, b: bigint): -1 | 0 | 1 {
|
|
147
176
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
148
177
|
}
|
|
149
178
|
|
|
@@ -152,10 +181,8 @@ export function compareFee(a: bigint, b: bigint): number {
|
|
|
152
181
|
* Uses field element comparison for deterministic ordering.
|
|
153
182
|
* Returns negative if a < b, positive if a > b, 0 if equal.
|
|
154
183
|
*/
|
|
155
|
-
export function compareTxHash(a:
|
|
156
|
-
|
|
157
|
-
const fieldB = Fr.fromHexString(b);
|
|
158
|
-
return fieldA.cmp(fieldB);
|
|
184
|
+
export function compareTxHash(a: bigint, b: bigint): -1 | 0 | 1 {
|
|
185
|
+
return Fr.cmpAsBigInt(a, b);
|
|
159
186
|
}
|
|
160
187
|
|
|
161
188
|
/**
|
|
@@ -163,29 +190,46 @@ export function compareTxHash(a: string, b: string): number {
|
|
|
163
190
|
* Returns negative if a < b, positive if a > b, 0 if equal.
|
|
164
191
|
* Use with sort() for ascending order, or negate/reverse for descending.
|
|
165
192
|
*/
|
|
166
|
-
export function comparePriority(a: PriorityComparable, b: PriorityComparable):
|
|
193
|
+
export function comparePriority(a: PriorityComparable, b: PriorityComparable): -1 | 0 | 1 {
|
|
167
194
|
const feeComparison = compareFee(a.priorityFee, b.priorityFee);
|
|
168
195
|
if (feeComparison !== 0) {
|
|
169
196
|
return feeComparison;
|
|
170
197
|
}
|
|
171
|
-
return compareTxHash(a.
|
|
198
|
+
return compareTxHash(a.txHashBigInt, b.txHashBigInt);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Returns the minimum fee required to replace an existing tx with the given price bump percentage.
|
|
203
|
+
* Uses integer arithmetic: `existingFee + existingFee * priceBumpPercentage / 100`.
|
|
204
|
+
*/
|
|
205
|
+
export function getMinimumPriceBumpFee(existingFee: bigint, priceBumpPercentage: bigint): bigint {
|
|
206
|
+
const bump = (existingFee * priceBumpPercentage) / 100n;
|
|
207
|
+
// Ensure the minimum bump is at least 1, so that replacement always requires
|
|
208
|
+
// paying strictly more — even with 0% bump or zero existing fee.
|
|
209
|
+
const effectiveBump = bump > 0n ? bump : 1n;
|
|
210
|
+
return existingFee + effectiveBump;
|
|
172
211
|
}
|
|
173
212
|
|
|
174
213
|
/**
|
|
175
214
|
* Checks for nullifier conflicts between an incoming transaction and existing pool state.
|
|
176
215
|
*
|
|
177
216
|
* When the incoming tx shares nullifiers with existing pending txs:
|
|
178
|
-
* - If the incoming tx
|
|
179
|
-
* -
|
|
217
|
+
* - If the incoming tx meets or exceeds the required priority, mark conflicting txs for eviction
|
|
218
|
+
* - Otherwise, ignore the incoming tx
|
|
219
|
+
*
|
|
220
|
+
* When `priceBumpPercentage` is provided (RPC path), uses fee-only comparison with the
|
|
221
|
+
* percentage bump instead of `comparePriority`.
|
|
180
222
|
*
|
|
181
223
|
* @param incomingMeta - Metadata for the incoming transaction
|
|
182
224
|
* @param getTxHashByNullifier - Accessor to find which tx uses a nullifier
|
|
183
225
|
* @param getMetadata - Accessor to get metadata for a tx hash
|
|
226
|
+
* @param priceBumpPercentage - Optional percentage bump required for fee-based replacement
|
|
184
227
|
*/
|
|
185
228
|
export function checkNullifierConflict(
|
|
186
229
|
incomingMeta: TxMetaData,
|
|
187
230
|
getTxHashByNullifier: (nullifier: string) => string | undefined,
|
|
188
231
|
getMetadata: (txHash: string) => TxMetaData | undefined,
|
|
232
|
+
priceBumpPercentage?: bigint,
|
|
189
233
|
): PreAddResult {
|
|
190
234
|
const txHashesToEvict: string[] = [];
|
|
191
235
|
|
|
@@ -206,19 +250,32 @@ export function checkNullifierConflict(
|
|
|
206
250
|
continue;
|
|
207
251
|
}
|
|
208
252
|
|
|
209
|
-
//
|
|
210
|
-
// Otherwise,
|
|
211
|
-
|
|
212
|
-
|
|
253
|
+
// When price bump is set (RPC path), require the incoming fee to meet the bumped threshold.
|
|
254
|
+
// Otherwise (P2P path), use full comparePriority with tx hash tiebreaker.
|
|
255
|
+
const isHigherPriority =
|
|
256
|
+
priceBumpPercentage !== undefined
|
|
257
|
+
? incomingMeta.priorityFee >= getMinimumPriceBumpFee(conflictingMeta.priorityFee, priceBumpPercentage)
|
|
258
|
+
: comparePriority(incomingMeta, conflictingMeta) > 0;
|
|
259
|
+
|
|
260
|
+
if (isHigherPriority) {
|
|
213
261
|
txHashesToEvict.push(conflictingHashStr);
|
|
214
262
|
} else {
|
|
263
|
+
const minimumFee =
|
|
264
|
+
priceBumpPercentage !== undefined
|
|
265
|
+
? getMinimumPriceBumpFee(conflictingMeta.priorityFee, priceBumpPercentage)
|
|
266
|
+
: undefined;
|
|
215
267
|
return {
|
|
216
268
|
shouldIgnore: true,
|
|
217
269
|
txHashesToEvict: [],
|
|
218
270
|
reason: {
|
|
219
271
|
code: TxPoolRejectionCode.NULLIFIER_CONFLICT,
|
|
220
|
-
message:
|
|
272
|
+
message:
|
|
273
|
+
minimumFee !== undefined
|
|
274
|
+
? `Nullifier conflict with existing tx ${conflictingHashStr}. Minimum required fee: ${minimumFee}, got: ${incomingMeta.priorityFee}`
|
|
275
|
+
: `Nullifier conflict with existing tx ${conflictingHashStr}`,
|
|
221
276
|
conflictingTxHash: conflictingHashStr,
|
|
277
|
+
minimumPriceBumpFee: minimumFee,
|
|
278
|
+
txPriorityFee: minimumFee !== undefined ? incomingMeta.priorityFee : undefined,
|
|
222
279
|
},
|
|
223
280
|
};
|
|
224
281
|
}
|
|
@@ -237,6 +294,44 @@ export function stubTxMetaValidationData(overrides: { expirationTimestamp?: bigi
|
|
|
237
294
|
hash: () => Promise.resolve(new BlockHash(Fr.ZERO)),
|
|
238
295
|
globalVariables: { blockNumber: BlockNumber(0) },
|
|
239
296
|
},
|
|
297
|
+
txContext: {
|
|
298
|
+
gasSettings: { gasLimits: Gas.empty() },
|
|
299
|
+
},
|
|
240
300
|
},
|
|
241
301
|
};
|
|
242
302
|
}
|
|
303
|
+
|
|
304
|
+
/** Creates a stub TxMetaData for tests. All fields have sensible defaults and can be overridden. */
|
|
305
|
+
export function stubTxMetaData(
|
|
306
|
+
txHash: string,
|
|
307
|
+
overrides: {
|
|
308
|
+
priorityFee?: bigint;
|
|
309
|
+
feePayer?: string;
|
|
310
|
+
claimAmount?: bigint;
|
|
311
|
+
feeLimit?: bigint;
|
|
312
|
+
nullifiers?: string[];
|
|
313
|
+
expirationTimestamp?: bigint;
|
|
314
|
+
anchorBlockHeaderHash?: string;
|
|
315
|
+
allowedSetupCalls?: boolean;
|
|
316
|
+
} = {},
|
|
317
|
+
): TxMetaData {
|
|
318
|
+
const txHashBigInt = Fr.fromHexString(txHash).toBigInt();
|
|
319
|
+
// Normalize to canonical zero-padded hex so txHashFromBigInt(txHashBigInt) === normalizedTxHash
|
|
320
|
+
const normalizedTxHash = txHashFromBigInt(txHashBigInt);
|
|
321
|
+
const expirationTimestamp = overrides.expirationTimestamp ?? 0n;
|
|
322
|
+
return {
|
|
323
|
+
txHash: normalizedTxHash,
|
|
324
|
+
txHashBigInt,
|
|
325
|
+
anchorBlockHeaderHash: overrides.anchorBlockHeaderHash ?? '0x1234',
|
|
326
|
+
priorityFee: overrides.priorityFee ?? 100n,
|
|
327
|
+
feePayer: overrides.feePayer ?? '0xfeepayer',
|
|
328
|
+
claimAmount: overrides.claimAmount ?? 0n,
|
|
329
|
+
feeLimit: overrides.feeLimit ?? 100n,
|
|
330
|
+
nullifiers: overrides.nullifiers ?? [`0x${normalizedTxHash.slice(2)}null1`],
|
|
331
|
+
expirationTimestamp,
|
|
332
|
+
allowedSetupCalls: overrides.allowedSetupCalls ?? true,
|
|
333
|
+
receivedAt: 0,
|
|
334
|
+
estimatedSizeBytes: 0,
|
|
335
|
+
data: stubTxMetaValidationData({ expirationTimestamp }),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { insertIntoSortedArray, removeFromSortedArray } from '@aztec/foundation/array';
|
|
1
2
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import type { L2BlockId } from '@aztec/stdlib/block';
|
|
3
4
|
|
|
4
|
-
import { type TxMetaData, type TxState,
|
|
5
|
+
import { type PriorityComparable, type TxMetaData, type TxState, comparePriority } from './tx_metadata.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Manages in-memory indices for the transaction pool.
|
|
@@ -22,8 +23,8 @@ export class TxPoolIndices {
|
|
|
22
23
|
#nullifierToTxHash: Map<string, string> = new Map();
|
|
23
24
|
/** Fee payer to txHashes index (pending txs only) */
|
|
24
25
|
#feePayerToTxHashes: Map<string, Set<string>> = new Map();
|
|
25
|
-
/** Pending
|
|
26
|
-
#pendingByPriority:
|
|
26
|
+
/** Pending transactions sorted ascending by priority fee, ties broken by txHash */
|
|
27
|
+
#pendingByPriority: PriorityComparable[] = [];
|
|
27
28
|
/** Protected transactions: txHash -> slotNumber */
|
|
28
29
|
#protectedTransactions: Map<string, SlotNumber> = new Map();
|
|
29
30
|
|
|
@@ -73,20 +74,14 @@ export class TxPoolIndices {
|
|
|
73
74
|
* @param order - 'desc' for highest priority first, 'asc' for lowest priority first
|
|
74
75
|
*/
|
|
75
76
|
*iteratePendingByPriority(order: 'asc' | 'desc', filter?: (hash: string) => boolean): Generator<string> {
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Use compareTxHash from tx_metadata, swap args for descending order
|
|
85
|
-
const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
|
|
86
|
-
for (const hash of sortedHashes) {
|
|
87
|
-
if (filter === undefined || filter(hash)) {
|
|
88
|
-
yield hash;
|
|
89
|
-
}
|
|
77
|
+
const arr = this.#pendingByPriority;
|
|
78
|
+
const start = order === 'asc' ? 0 : arr.length - 1;
|
|
79
|
+
const step = order === 'asc' ? 1 : -1;
|
|
80
|
+
const inBounds = order === 'asc' ? (i: number) => i < arr.length : (i: number) => i >= 0;
|
|
81
|
+
|
|
82
|
+
for (let i = start; inBounds(i); i += step) {
|
|
83
|
+
if (filter === undefined || filter(arr[i].txHash)) {
|
|
84
|
+
yield arr[i].txHash;
|
|
90
85
|
}
|
|
91
86
|
}
|
|
92
87
|
}
|
|
@@ -227,11 +222,7 @@ export class TxPoolIndices {
|
|
|
227
222
|
|
|
228
223
|
/** Gets the count of pending transactions */
|
|
229
224
|
getPendingTxCount(): number {
|
|
230
|
-
|
|
231
|
-
for (const hashes of this.#pendingByPriority.values()) {
|
|
232
|
-
count += hashes.size;
|
|
233
|
-
}
|
|
234
|
-
return count;
|
|
225
|
+
return this.#pendingByPriority.length;
|
|
235
226
|
}
|
|
236
227
|
|
|
237
228
|
/** Gets the lowest priority pending transaction hashes (up to limit) */
|
|
@@ -264,12 +255,10 @@ export class TxPoolIndices {
|
|
|
264
255
|
/** Gets all pending transactions */
|
|
265
256
|
getPendingTxs(): TxMetaData[] {
|
|
266
257
|
const result: TxMetaData[] = [];
|
|
267
|
-
for (const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
result.push(meta);
|
|
272
|
-
}
|
|
258
|
+
for (const entry of this.#pendingByPriority) {
|
|
259
|
+
const meta = this.#metadata.get(entry.txHash);
|
|
260
|
+
if (meta) {
|
|
261
|
+
result.push(meta);
|
|
273
262
|
}
|
|
274
263
|
}
|
|
275
264
|
return result;
|
|
@@ -408,13 +397,12 @@ export class TxPoolIndices {
|
|
|
408
397
|
}
|
|
409
398
|
feePayerSet.add(meta.txHash);
|
|
410
399
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
prioritySet.add(meta.txHash);
|
|
400
|
+
insertIntoSortedArray(
|
|
401
|
+
this.#pendingByPriority,
|
|
402
|
+
{ txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
|
|
403
|
+
comparePriority,
|
|
404
|
+
false,
|
|
405
|
+
);
|
|
418
406
|
}
|
|
419
407
|
|
|
420
408
|
#removeFromPendingIndices(meta: TxMetaData): void {
|
|
@@ -432,13 +420,11 @@ export class TxPoolIndices {
|
|
|
432
420
|
}
|
|
433
421
|
}
|
|
434
422
|
|
|
435
|
-
// Remove from priority
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
}
|
|
423
|
+
// Remove from priority array
|
|
424
|
+
removeFromSortedArray(
|
|
425
|
+
this.#pendingByPriority,
|
|
426
|
+
{ txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
|
|
427
|
+
comparePriority,
|
|
428
|
+
);
|
|
443
429
|
}
|
|
444
430
|
}
|
|
@@ -11,7 +11,14 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien
|
|
|
11
11
|
import EventEmitter from 'node:events';
|
|
12
12
|
|
|
13
13
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
AddTxsResult,
|
|
16
|
+
PoolReadAccess,
|
|
17
|
+
TxPoolV2,
|
|
18
|
+
TxPoolV2Config,
|
|
19
|
+
TxPoolV2Dependencies,
|
|
20
|
+
TxPoolV2Events,
|
|
21
|
+
} from './interfaces.js';
|
|
15
22
|
import type { TxState } from './tx_metadata.js';
|
|
16
23
|
import { TxPoolV2Impl } from './tx_pool_v2_impl.js';
|
|
17
24
|
|
|
@@ -58,6 +65,9 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
|
|
|
58
65
|
const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
|
|
59
66
|
this.emit('txs-removed', { txHashes: hashes });
|
|
60
67
|
},
|
|
68
|
+
onTxsMined: (txHashes: string[]) => {
|
|
69
|
+
this.#metrics?.transactionsRemoved(txHashes);
|
|
70
|
+
},
|
|
61
71
|
};
|
|
62
72
|
|
|
63
73
|
// Create the implementation
|
|
@@ -74,7 +84,7 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
|
|
|
74
84
|
return this.#queue.put(() => this.#impl.addPendingTxs(txs, opts));
|
|
75
85
|
}
|
|
76
86
|
|
|
77
|
-
canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
87
|
+
canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
78
88
|
return this.#queue.put(() => this.#impl.canAddPendingTx(tx));
|
|
79
89
|
}
|
|
80
90
|
|
|
@@ -162,6 +172,11 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
|
|
|
162
172
|
return this.#queue.put(() => Promise.resolve(this.#impl.getLowestPriorityPending(limit)));
|
|
163
173
|
}
|
|
164
174
|
|
|
175
|
+
/** Returns read-only access to the pool. Used for testing. */
|
|
176
|
+
getPoolReadAccess(): PoolReadAccess {
|
|
177
|
+
return this.#impl.getPoolReadAccess();
|
|
178
|
+
}
|
|
179
|
+
|
|
165
180
|
// === Configuration ===
|
|
166
181
|
|
|
167
182
|
updateConfig(config: Partial<TxPoolV2Config>): Promise<void> {
|