-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: Use Custom Priority in Priority Nonce Mempool #15328
Conversation
The why makes sense to me. Just another take on the how, we could also consider using a generic type to describe the comparable priority. I explored this here a bit 938280c. Far from perfect but hopefully you get the idea. I'm not convinced its any better, but something to think about it. |
@kocubinski that could work too, but how do you set the custom priority? I.e. what I did with |
It would need to be constructor injected like how you have it @alexanderbez. Another option is to just inject the priority fetcher which must return int64 and change nothing else. Would returning an int64 indicating priority from consumer code be acceptable for the use case you have in mind? If if we don't do that I think we'd need a |
@kocubinski yeah the goal here is to use priority that isn't always an |
That's fine, just be aware that whatever priority is being returned must implement |
Ok, marking this ready for review since Ci is green and the approach works. For review, I guess what I'm looking for is mainly:
|
This is an API breaking change though, so it cannot technically be backported. |
This test will fail with func TestSenderNonce_Priorities(t *testing.T) {
accounts := simtypes.RandomAccounts(rand.New(rand.NewSource(0)), 1)
ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger())
sa := accounts[0].Address
txs := []testTx{
{priority: 20, nonce: 1, address: sa},
}
txPriority := mempool.TxPriority{GetTxPriority: func(ctx context.Context, tx sdk.Tx) any {
priority := sdk.UnwrapSDKContext(ctx).Priority()
return []int64{priority}
}}
mp := mempool.NewPriorityMempool(txPriority)
for _, tx := range txs {
c := ctx.WithPriority(tx.priority)
require.NoError(t, mp.Insert(c, tx))
require.Equal(t, 1, mp.CountTx())
iter := mp.Select(ctx, nil)
require.Equal(t, tx, iter.Tx())
}
} |
@kocubinski re |
I explored using generics to assert the priority type is Another option is runtime reflection based checking. |
Pushed an approach that uses generics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. We should probably get another reviewer though since I've looked at this too much.
…mos-sdk into bez/mempool-improved-priority
Nice idea on the config @kocubinski. Pushed changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK. btw what would be an usecase for MaxTx < 0 ? (// - if MaxTx < 0, Insert is a no-op.
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a straightforward mechanical refactor, but I am not yet comfortable in this part of the codebase. I left a couple style comments.
res := skiplist.Int64.Compare(keyA.priority, keyB.priority) | ||
if res != 0 { | ||
return res | ||
type ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type (
block like this is not commonly used in Go. It adds indentation and impedes grep type TYPENAME
. Please keep the individual type declarations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When there are multiple types in a file, I use ()
to group them to make it easier for the reader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! We should add a changelog given that it had landed in v0.47, and this change is API breaking and an improvement.
Description
The
PriorityNonceMempool
provides a data structure that prioritizes transactions respecting sender nonces, which is an amazing data structure and will most likely be used in 99% of use-cases.The data structure works by using
ctx.Priority()
when determining priority (and weight). This value is anint64
and is set inCheckTx
when inserting a tx into the mempool.This is fine when priority is determined by fees or something similar, yet there are cases where you want priority to be something different that is either an entirely different type or something that doesn't fit into an
int64
.Example:
big.Int
, far exceed int64 max value (e.g. Evmos which uses 10^18)sdk.Coins
I've demonstrated in this PR how to achieve a generic way of allowing "generic" priority. There might be a cleaner or more straight forward way, but this seems to do the trick.
cc @kocubinski @JeancarloBarrios
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
to the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
!
in the type prefix if API or client breaking change