Skip to content

Commit

Permalink
return mempool error; if a tx exceeds lane limits
Browse files Browse the repository at this point in the history
  • Loading branch information
beer-1 committed Nov 6, 2024
1 parent cc2c0bb commit 601db42
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 7 deletions.
13 changes: 12 additions & 1 deletion app/lanes/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,21 @@ func NewDefaultLane(cfg blockbase.LaneConfig) block.Lane {
lane := &blockbase.BaseLane{}
proposalHandler := NewDefaultProposalHandler(lane)

mempool, err := NewMempool(
blockbase.NewDefaultTxPriority(),
cfg.SignerExtractor,
cfg.MaxTxs,
cfg.MaxBlockSpace,
cfg.TxEncoder,
)
if err != nil {
panic(err)

Check warning on line 31 in app/lanes/default.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/default.go#L23-L31

Added lines #L23 - L31 were not covered by tests
}

_lane, err := blockbase.NewBaseLane(
cfg,
DefaultName,
blockbase.WithMempool(NewMempool(blockbase.NewDefaultTxPriority(), cfg.SignerExtractor, cfg.MaxTxs)),
blockbase.WithMempool(mempool),

Check warning on line 37 in app/lanes/default.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/default.go#L37

Added line #L37 was not covered by tests
blockbase.WithPrepareLaneHandler(proposalHandler.PrepareLaneHandler()),
blockbase.WithProcessLaneHandler(proposalHandler.ProcessLaneHandler()),
)
Expand Down
13 changes: 12 additions & 1 deletion app/lanes/free.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,22 @@ func NewFreeLane(
lane := &blockbase.BaseLane{}
proposalHandler := NewDefaultProposalHandler(lane)

mempool, err := NewMempool(
blockbase.NewDefaultTxPriority(),
cfg.SignerExtractor,
cfg.MaxTxs,
cfg.MaxBlockSpace,
cfg.TxEncoder,
)
if err != nil {
panic(err)

Check warning on line 53 in app/lanes/free.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/free.go#L45-L53

Added lines #L45 - L53 were not covered by tests
}

_lane, err := blockbase.NewBaseLane(
cfg,
FreeLaneName,
blockbase.WithMatchHandler(matchFn),
blockbase.WithMempool(NewMempool(blockbase.NewDefaultTxPriority(), cfg.SignerExtractor, cfg.MaxTxs)),
blockbase.WithMempool(mempool),

Check warning on line 60 in app/lanes/free.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/free.go#L60

Added line #L60 was not covered by tests
blockbase.WithPrepareLaneHandler(proposalHandler.PrepareLaneHandler()),
blockbase.WithProcessLaneHandler(proposalHandler.ProcessLaneHandler()),
)
Expand Down
5 changes: 3 additions & 2 deletions app/lanes/free_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ var _ sdk.Tx = MockTx{}
var _ sdk.FeeTx = &MockTx{}

type MockTx struct {
msgs []sdk.Msg
msgs []sdk.Msg
gasLimit uint64
}

func (tx MockTx) GetMsgsV2() ([]protov2.Message, error) {
Expand All @@ -53,7 +54,7 @@ func (tx MockTx) GetMsgs() []sdk.Msg {
}

func (tx MockTx) GetGas() uint64 {
return 0
return tx.gasLimit
}

func (tx MockTx) GetFee() sdk.Coins {
Expand Down
57 changes: 55 additions & 2 deletions app/lanes/mempool.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import (
"errors"
"fmt"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"

signer_extraction "github.com/skip-mev/block-sdk/v2/adapters/signer_extraction_adapter"
blockbase "github.com/skip-mev/block-sdk/v2/block/base"
"github.com/skip-mev/block-sdk/v2/block/proposals"
)

type (
Expand All @@ -33,11 +36,25 @@ type (
// txCache is a map of all transactions in the mempool. It is used
// to quickly check if a transaction is already in the mempool.
txCache map[txKey]struct{}

// ratio defines the relative percentage of block space that can be
// used by this lane.
ratio math.LegacyDec

// txEncoder defines tx encoder.
txEncoder sdk.TxEncoder
}
)

// NewMempool returns a new Mempool.
func NewMempool[C comparable](txPriority blockbase.TxPriority[C], extractor signer_extraction.Adapter, maxTx int) *Mempool[C] {
func NewMempool[C comparable](
txPriority blockbase.TxPriority[C], extractor signer_extraction.Adapter,
maxTx int, ratio math.LegacyDec, txEncoder sdk.TxEncoder,
) (*Mempool[C], error) {
if !ratio.IsPositive() {
return nil, errors.New("mempool creation; ratio must be positive")
}

Check warning on line 56 in app/lanes/mempool.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/mempool.go#L55-L56

Added lines #L55 - L56 were not covered by tests

return &Mempool[C]{
index: blockbase.NewPriorityMempool(
blockbase.PriorityNonceMempoolConfig[C]{
Expand All @@ -48,7 +65,9 @@ func NewMempool[C comparable](txPriority blockbase.TxPriority[C], extractor sign
),
extractor: extractor,
txCache: make(map[txKey]struct{}),
}
ratio: ratio,
txEncoder: txEncoder,
}, nil
}

// Priority returns the priority of the transaction.
Expand Down Expand Up @@ -89,6 +108,10 @@ func (cm *Mempool[C]) Contains(tx sdk.Tx) bool {

// Insert inserts a transaction into the mempool.
func (cm *Mempool[C]) Insert(ctx context.Context, tx sdk.Tx) error {
if err := cm.AssertLaneLimits(sdk.UnwrapSDKContext(ctx), tx); err != nil {
return err
}

if err := cm.index.Insert(ctx, tx); err != nil {
return fmt.Errorf("failed to insert tx into auction index: %w", err)
}
Expand Down Expand Up @@ -130,3 +153,33 @@ func (cm *Mempool[C]) getTxKey(tx sdk.Tx) (txKey, error) {
nonce := sig.Sequence
return txKey{nonce, sender}, nil
}

// AssertLaneLimits asserts that the transaction does not exceed the lane's max size and gas limit.
func (cm *Mempool[C]) AssertLaneLimits(ctx sdk.Context, tx sdk.Tx) error {
maxBlockSize, maxGasLimit := proposals.GetBlockLimits(ctx)
maxLaneTxSize := cm.ratio.MulInt64(maxBlockSize).TruncateInt().Int64()
maxLaneGasLimit := cm.ratio.MulInt(math.NewIntFromUint64(maxGasLimit)).TruncateInt().Uint64()

txBytes, err := cm.txEncoder(tx)
if err != nil {
return fmt.Errorf("failed to encode transaction: %w", err)
}

Check warning on line 166 in app/lanes/mempool.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/mempool.go#L165-L166

Added lines #L165 - L166 were not covered by tests

gasTx, ok := tx.(sdk.FeeTx)
if !ok {
return fmt.Errorf("failed to cast transaction to gas tx")
}

Check warning on line 171 in app/lanes/mempool.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/mempool.go#L170-L171

Added lines #L170 - L171 were not covered by tests

txSize := int64(len(txBytes))
txGasLimit := gasTx.GetGas()

if txSize > maxLaneTxSize {
return fmt.Errorf("tx size %d exceeds max lane size %d", txSize, maxLaneTxSize)
}

if txGasLimit > maxLaneGasLimit {
return fmt.Errorf("tx gas limit %d exceeds max lane gas limit %d", txGasLimit, maxLaneGasLimit)
}

return nil
}
78 changes: 78 additions & 0 deletions app/lanes/mempool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package lanes_test

import (
"testing"

"github.com/stretchr/testify/require"

"cosmossdk.io/log"
"cosmossdk.io/math"

cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"

"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsign "github.com/cosmos/cosmos-sdk/x/auth/signing"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

signer_extraction "github.com/skip-mev/block-sdk/v2/adapters/signer_extraction_adapter"
blockbase "github.com/skip-mev/block-sdk/v2/block/base"

lanes "github.com/initia-labs/initia/app/lanes"
"github.com/initia-labs/initia/app/params"
)

func Test_MempoolInsert(t *testing.T) {
ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()).WithConsensusParams(cmtproto.ConsensusParams{
Block: &cmtproto.BlockParams{
MaxBytes: 1000000,
MaxGas: 1000000,
},
})

signerExtractor := signer_extraction.NewDefaultAdapter()
encodingConfig := params.MakeEncodingConfig()
txEncoder := encodingConfig.TxConfig.TxEncoder()
mempool, err := lanes.NewMempool(
blockbase.NewDefaultTxPriority(),
signerExtractor,
1, // max txs
math.LegacyMustNewDecFromStr("0.01"), // max block space
txEncoder,
)
require.NoError(t, err)

priv, _, addr := testdata.KeyTestPubAddr()
defaultSignMode, err := authsign.APISignModeToInternal(encodingConfig.TxConfig.SignModeHandler().DefaultMode())
require.NoError(t, err)

// valid gas limit
txBuilder := encodingConfig.TxConfig.NewTxBuilder()
txBuilder.SetGasLimit(10000)
txBuilder.SetMemo("")
txBuilder.SetMsgs(&banktypes.MsgSend{FromAddress: addr.String(), ToAddress: addr.String(), Amount: sdk.Coins{}})
sigV2 := signing.SignatureV2{
PubKey: priv.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: defaultSignMode,
Signature: nil,
},
Sequence: 1,
}
err = txBuilder.SetSignatures(sigV2)
require.NoError(t, err)
err = mempool.Insert(ctx, txBuilder.GetTx())
require.NoError(t, err)

// high gas limit than max gas
txBuilder.SetGasLimit(10001)
err = mempool.Insert(ctx, txBuilder.GetTx())
require.ErrorContains(t, err, "exceeds max lane gas limit")

// rollback gas limit and set memo to exceed max block space
txBuilder.SetGasLimit(10000)
txBuilder.SetMemo(string(make([]byte, 10000)))
err = mempool.Insert(ctx, txBuilder.GetTx())
require.ErrorContains(t, err, "exceeds max lane size")
}
12 changes: 11 additions & 1 deletion app/lanes/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,21 @@ func NewSystemLane(
lane := &blockbase.BaseLane{}
proposalHandler := NewDefaultProposalHandler(lane)

mempool, err := NewMempool(
blockbase.NewDefaultTxPriority(),
cfg.SignerExtractor,
cfg.MaxTxs,
cfg.MaxBlockSpace,
cfg.TxEncoder,
)
if err != nil {
panic(err)

Check warning on line 37 in app/lanes/system.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/system.go#L29-L37

Added lines #L29 - L37 were not covered by tests
}
_lane, err := blockbase.NewBaseLane(
cfg,
SystemLaneName,
blockbase.WithMatchHandler(matchFn),
blockbase.WithMempool(NewMempool(blockbase.NewDefaultTxPriority(), cfg.SignerExtractor, cfg.MaxTxs)),
blockbase.WithMempool(mempool),

Check warning on line 43 in app/lanes/system.go

View check run for this annotation

Codecov / codecov/patch

app/lanes/system.go#L43

Added line #L43 was not covered by tests
blockbase.WithPrepareLaneHandler(proposalHandler.PrepareLaneHandler()),
blockbase.WithProcessLaneHandler(proposalHandler.ProcessLaneHandler()),
)
Expand Down

0 comments on commit 601db42

Please sign in to comment.