Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -1228,3 +1228,47 @@ func (app *BaseApp) LoadLatest(ctx context.Context, req *abci.RequestLoadLatest)
app.initialHeight = app.cms.LastCommitID().Version
return &abci.ResponseLoadLatest{}, nil
}

func (app *BaseApp) GetTxPriorityHint(_ context.Context, req *abci.RequestGetTxPriorityHint) (_resp *abci.ResponseGetTxPriorityHint, _err error) {
defer func() {
if r := recover(); r != nil {
// Fall back to no-op priority if we panic for any reason. This is to avoid DoS
// vectors where a malicious actor crafts a transaction that panics the
// prioritizer. Since the prioritizer is used as a hint only, it's safe to fall
// back to zero priority in this case and log the panic for monitoring purposes.
app.logger.Error("tx prioritizer base app panicked. Falling back on no priority", "error", r)
if _err == nil {
_resp = &abci.ResponseGetTxPriorityHint{Priority: 0}
}
// Do not overwrite an existing error if one was already set to keep panics a
// non-event at this stage but safeguard against them.
}
}()

defer telemetry.MeasureSince(time.Now(), "abci", "get_tx_priority_hint")

tx, err := app.txDecoder(req.Tx)
if err != nil {
return nil, err
}
if tx == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "nil tx")
}

// TODO: should we bother validating the messages here?
msgs := tx.GetMsgs()
if err := validateBasicTxMsgs(msgs); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might be consuming some resources, but we can test it out to see if that make a difference or not

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right. I was on the fence for adding this too 👍

return nil, err
}
var priority int64
if app.txPrioritizer != nil {
sdkCtx := app.getContextForTx(runTxModeCheck, req.Tx)
priority, err = app.txPrioritizer(sdkCtx, tx)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, fmt.Sprintf("error getting tx priority: %s", err.Error()))
}
}
return &abci.ResponseGetTxPriorityHint{
Priority: priority,
}, nil
}
1 change: 1 addition & 0 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type BaseApp struct { //nolint: maligned
preCommitHandler sdk.PreCommitHandler
closeHandler sdk.CloseHandler
inplaceTestnetInitializer sdk.InplaceTestnetInitializer
txPrioritizer sdk.TxPrioritizer

appStore
baseappVersions
Expand Down
6 changes: 6 additions & 0 deletions baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,9 @@ func (app *BaseApp) SetQueryMultiStore(ms sdk.CommitMultiStore) {
func (app *BaseApp) SetMigrationHeight(height int64) {
app.migrationHeight = height
}

// SetTxPrioritizer sets the transaction prioritizer for the BaseApp. If unset,
// calls to GetTxPriorityHint for all valid transactions will return 0.
func (app *BaseApp) SetTxPrioritizer(prioritizer sdk.TxPrioritizer) {
app.txPrioritizer = prioritizer
}
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
go 1.21
go 1.24.5

module github.com/cosmos/cosmos-sdk

Expand Down Expand Up @@ -134,6 +134,7 @@ require (
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20210609091139-0a56a4bca00b // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect
Expand Down Expand Up @@ -196,7 +197,9 @@ replace (
github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.51
// Latest goleveldb is broken, we have to stick to this version
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.6.0
//// TODO: To be replaced with a concrete version number. See:
//// - https://github.com/sei-protocol/sei-tendermint/pull/301
github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.6.4-0.20250905203244-31c1f39f5fce
// latest grpc doesn't work with with our modified proto compiler, so we need to enforce
// the following version across all dependencies.
google.golang.org/grpc => google.golang.org/grpc v1.33.2
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,8 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
Expand Down Expand Up @@ -966,8 +968,8 @@ github.com/sei-protocol/sei-db v0.0.51 h1:jK6Ps+jDbGdWIPZttaWk7VIsq8aLWWlkTp9axI
github.com/sei-protocol/sei-db v0.0.51/go.mod h1:m5g7p0QeAS3dNJHIl28zQpzOgxQmvYqPb7t4hwgIOCA=
github.com/sei-protocol/sei-iavl v0.1.9 h1:y4mVYftxLNRs6533zl7N0/Ch+CzRQc04JDfHolIxgBE=
github.com/sei-protocol/sei-iavl v0.1.9/go.mod h1:7PfkEVT5dcoQE+s/9KWdoXJ8VVVP1QpYYPLdxlkSXFk=
github.com/sei-protocol/sei-tendermint v0.6.0 h1:H/qN54IUUnqMKbqL9rVt61ViIgPzpHixtKd43LV+C6I=
github.com/sei-protocol/sei-tendermint v0.6.0/go.mod h1:hLgRpS2d6VM8XzlhEtFeosCYkpuviU2ztqmOairIivc=
github.com/sei-protocol/sei-tendermint v0.6.4-0.20250905203244-31c1f39f5fce h1:sxqrZQgEzjs/8MofaB5g/IfpffK42xk2BymJq/irh50=
github.com/sei-protocol/sei-tendermint v0.6.4-0.20250905203244-31c1f39f5fce/go.mod h1:SSZv0P1NBP/4uB3gZr5XJIan3ks3Ui8FJJzIap4r6uc=
github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY=
github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
Expand Down
2 changes: 2 additions & 0 deletions types/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ type LoadVersionHandler func() error
type PreCommitHandler func(ctx Context) error
type CloseHandler func() error
type InplaceTestnetInitializer func(cryptotypes.PubKey) error

type TxPrioritizer func(Context, Tx) (int64, error)
10 changes: 9 additions & 1 deletion types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Context struct {
eventManager *EventManager
evmEventManager *EVMEventManager
priority int64 // The tx priority, only relevant in CheckTx
hasPriority bool // Whether the tx has a priority set
pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx
checkTxCallback func(Context, error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs`
deliverTxCallback func(Context) // callback to make at the end of DeliverTx.
Expand Down Expand Up @@ -241,12 +242,19 @@ func (c Context) StoreTracer() gaskv.IStoreTracer {
return c.storeTracer
}

// WithEventManager returns a Context with an updated tx priority
// WithPriority returns a Context with an updated tx priority.
func (c Context) WithPriority(p int64) Context {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where is this function being called?

Copy link
Collaborator Author

@masih masih Aug 27, 2025

Choose a reason for hiding this comment

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

By ante handlers. This is the main function that sets priority in the context. I just fixed the godc typo in this PR.

Note that I do not call this function in the PR because the priority calculated by SeiTxPrioritizer (in sei-chain) is meant to only be a hint. The actual proiority calculation by ante handlers is unchanged by my series of PRs.

c.priority = p
c.hasPriority = true
return c
}

// HasPriority returns true iff the priority is set for this Context even if it
// was set to zero.
func (c Context) HasPriority() bool {
return c.hasPriority
}

// HeaderHash returns a copy of the header hash obtained during abci.RequestBeginBlock
func (c Context) HeaderHash() tmbytes.HexBytes {
hash := make([]byte, len(c.headerHash))
Expand Down
30 changes: 30 additions & 0 deletions types/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
Expand Down Expand Up @@ -226,3 +227,32 @@ func (s *contextTestSuite) TestUnwrapSDKContext() {
ctx = context.Background()
s.Require().Panics(func() { types.UnwrapSDKContext(ctx) })
}

func TestContext_Priority(t *testing.T) {
var (
requireNoPriority = func(t *testing.T, ctx types.Context) {
require.Zero(t, ctx.Priority())
require.False(t, ctx.HasPriority())
}
requirePriority = func(t *testing.T, ctx types.Context, priority int64) {
require.Equal(t, priority, ctx.Priority())
require.True(t, ctx.HasPriority())
}
)

// Assert that a new context has no priority set and does not have priority.
var subject types.Context
requireNoPriority(t, subject)

// Assert that setting a priority sets the priority and marks the context as
// having priority set. But does not change the original context.
prioritisedSubject := subject.WithPriority(100)
requirePriority(t, prioritisedSubject, 100)
requireNoPriority(t, subject)

// Assert that setting priority to 0 updates the priority but still marks the
// context as having priority set. But does not change the original context.
deprioritisedSubject := subject.WithPriority(0)
requirePriority(t, deprioritisedSubject, 0)
requireNoPriority(t, subject)
}
Loading