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. |
kocubinski
left a comment
There was a problem hiding this comment.
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. |
facundomedica
left a comment
There was a problem hiding this comment.
utACK. btw what would be an usecase for MaxTx < 0 ? (// - if MaxTx < 0, Insert is a no-op.)
mark-rushakoff
left a comment
There was a problem hiding this comment.
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.
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.
When there are multiple types in a file, I use () to group them to make it easier for the reader.
Description
The
PriorityNonceMempoolprovides 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 anint64and is set inCheckTxwhen 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.CoinsI'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.mdReviewers 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