Skip to content
This repository was archived by the owner on Jan 20, 2026. It is now read-only.

Add GetTxPriorityHint and mempool backpressure via priority drops#301

Merged
masih merged 24 commits intomainfrom
masih/abci-get-tx-priority
Sep 29, 2025
Merged

Add GetTxPriorityHint and mempool backpressure via priority drops#301
masih merged 24 commits intomainfrom
masih/abci-get-tx-priority

Conversation

@masih
Copy link
Collaborator

@masih masih commented Aug 19, 2025

Extends the ABCI interface with a side-effect free GetTxPriorityHint method and connects transaction priority hints to the mempool. The change gives the network a straightforward way to apply backpressure when the mempool is congested, without blocking liveness-critical transactions. By making the dropping logic priority-aware, nodes can favor important traffic under load.

Three new configuration options are introduced:

  • DropUtilisationThreshold – the utilisation level (0.0–1.0) at which dropping starts. For example, 0.8 means the mempool must be at least 80% full before the policy takes effect.
  • DropPriorityThreshold – the fraction of lowest-priority transactions to drop once the utilisation threshold is exceeded. The default 0.1 drops the bottom 10%.
  • DropPriorityReservoirSize – the number of samples used to estimate the distribution of transaction priorities. Defaults to 10,240 entries (~80KB). Larger values improve accuracy at the cost of memory.

The reservoir approach is designed to avoid tracking every transaction’s priority directly, which would be inefficient. Instead, the mempool keeps a statistically representative sample (the reservoir) of observed priorities. This sample makes it possible to estimate percentile cutoffs with good accuracy, without storing all values. Operators can tune the reservoir size depending on whether memory savings or precision is more important for their setup.

The combination of the utilisation threshold, priority cutoff, and reservoir sampling introduces a low-risk form of backpressure. Only the least important transactions are dropped when space is tight, ensuring new, high-priority transactions can still enter. This improves resilience under load while keeping the policy simple and predictable.

@masih masih changed the base branch from masih/fix-mockery-lint-and-more to main August 19, 2025 15:44
@masih masih force-pushed the masih/abci-get-tx-priority branch from 7067d5c to ae86e6f Compare August 19, 2025 15:47
masih added a commit to sei-protocol/sei-cosmos that referenced this pull request Aug 20, 2025
Add hooks to allow injection of transaction prioritization logic and
handle ABCI requests to get transaction priority via the hook.

Relates to:
 * sei-protocol/sei-tendermint#301
@masih masih marked this pull request as ready for review August 22, 2025 09:29
masih added 2 commits August 25, 2025 21:25
Expand the ABCI interface to expose a side-effect free get transaction
priority
Rename the priority interfaces to hint, to make it clear that it is a
hint.

Integrate it with mempool to reject transactions below threshold when
mempool is over utilised.
@masih masih force-pushed the masih/abci-get-tx-priority branch from 18f4d5a to 492b079 Compare August 25, 2025 20:27
@masih masih changed the title Add GetTxPriority to ABCI interface Add GetTxPriority to ABCI interface and integrate with mempool Aug 25, 2025
@codecov
Copy link

codecov bot commented Aug 26, 2025

Codecov Report

❌ Patch coverage is 63.95349% with 62 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.28%. Comparing base (25bb4a7) to head (5b97528).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/mempool/metrics.gen.go 52.38% 20 Missing ⚠️
internal/mempool/mempool.go 44.11% 18 Missing and 1 partial ⚠️
internal/libs/reservoir/reservoir.go 88.73% 7 Missing and 1 partial ⚠️
config/config.go 33.33% 4 Missing and 2 partials ⚠️
abci/types/messages.go 0.00% 4 Missing ⚠️
internal/proxy/client.go 0.00% 3 Missing ⚠️
abci/types/application.go 0.00% 2 Missing ⚠️

❌ Your patch status has failed because the patch coverage (63.95%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #301      +/-   ##
==========================================
+ Coverage   57.10%   57.28%   +0.17%     
==========================================
  Files         258      255       -3     
  Lines       34487    33914     -573     
==========================================
- Hits        19695    19427     -268     
+ Misses      13214    12958     -256     
+ Partials     1578     1529      -49     
Files with missing lines Coverage Δ
config/toml.go 51.35% <ø> (ø)
internal/mempool/metrics.go 100.00% <100.00%> (ø)
abci/types/application.go 0.00% <0.00%> (ø)
internal/proxy/client.go 21.13% <0.00%> (-0.53%) ⬇️
abci/types/messages.go 4.63% <0.00%> (-0.13%) ⬇️
config/config.go 62.70% <33.33%> (-0.49%) ⬇️
internal/libs/reservoir/reservoir.go 88.73% <88.73%> (ø)
internal/mempool/mempool.go 69.27% <44.11%> (-1.21%) ⬇️
internal/mempool/metrics.gen.go 15.06% <52.38%> (-0.33%) ⬇️

... and 16 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@masih masih requested a review from yzang2019 September 5, 2025 20:33
# Conflicts:
#	abci/types/types.pb.go
#	proto/tendermint/abci/types.proto
@github-actions
Copy link

github-actions bot commented Sep 24, 2025

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedSep 29, 2025, 10:23 AM

Keep a sample of transaction priorities handled by mempool to determine
the drop cut off when mempool is over-utilised.
@masih masih changed the title Add GetTxPriority to ABCI interface and integrate with mempool Add GetTxPriorityHint to ABCI interface with priority-based transaction drop under load Sep 24, 2025
@masih masih changed the title Add GetTxPriorityHint to ABCI interface with priority-based transaction drop under load Add GetTxPriorityHint and mempool backpressure via priority drops Sep 24, 2025
@masih masih requested review from sei-will and yzang2019 September 24, 2025 12:54
}
if j := s.rng.Int64N(s.seen); int(j) < s.size {
s.samples[j] = item
}
Copy link
Contributor

@pompon0 pompon0 Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaiu, this means that the reservoir is never pruned, i.e. it approximates the whole history of transactions since the node was started. Is this intentional? What if the traffic pattern changes over time?

Copy link
Collaborator Author

@masih masih Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? What if the traffic pattern changes over time?

It is. The rationale is to attempt to discover a more and more representative distribution of the global space of priorities a node handles. That then offers a more predictable behaviour for the node operators where they can reason about what proportion of transactions they are willing to give up if mempool is struggling.

The transactions end up being retried anyway so I think this is a relatively low risk approach?

Taking an alternative route where reservoir is a "moving window" of priorities is also valid, and other than my limited intuition I have no data to decide which is better for Sei node operators.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has a fixed size though right? What would happen if the total num of unique priority exceed the size limit, do we evict the old samples?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has a fixed size though right?

Correct.

What would happen if the total num of unique priority exceed the size limit, do we evict the old samples?

"uniqueness" does not make any difference. Once the number of samples (unique or not) exceeds the fixed size, we may pick an item at random to replace with the new sample. See algorithm R:

The way we select which item to replace is to pick a random value between 0 and the total number of samples seen so far, if the random number is within the range of sample sizes then we replace. Otherwise, we ignore the given sample.

Cache the last asked for percentile for at least 5 seconds and avoid
redundant re-computation of it if the sample set has not changed. This
cache design is based on the rationale that the percentile value asked
for in Sei is fixed in configuration for the lifetime of the
application. Therefore, the only value that's updated in reservoir is
the samples.

// lastPercentileCacheTTL is the duration for which a cached percentile value is
// considered valid if no new percentile p is asked for.
const lastPercentileCacheTTL = 5 * time.Second
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy to parameterise this if the reviewers prefer it to be from get go.

To remove a couple of edge cases and performance footgun make the
reservoir less generic into a fixed percentile.
Only consider the percentile cache dirty if add results in expansion of
samples, or it replaces an item with a different value.
@masih masih merged commit b0665bf into main Sep 29, 2025
46 of 49 checks passed
@masih masih deleted the masih/abci-get-tx-priority branch September 29, 2025 14:39
@masih
Copy link
Collaborator Author

masih commented Sep 29, 2025

Big thanks to @yzang2019 for help in testing this under load 🍻 ❤️

masih added a commit to sei-protocol/sei-chain that referenced this pull request Oct 1, 2025
Extract the logic of transaction prioritisation from various Ante
handlers for both EVM and cosmos transactions into a side effect free
lightweight API exposed via ABCI interface.

Relates to:
 * sei-protocol/sei-tendermint#301
* ~sei-protocol/sei-cosmos#598 Repo archived,
and changes are ported to this PR.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants