fix: Remove Incorrect Ordering from DefaultTxPriority (#371)
* init * replace existing tx_priorities with nop_tx_priority * fix go.mod --------- Co-authored-by: David Terpay <david.terpay@gmail.com>
This commit is contained in:
parent
d82fb33d1e
commit
234e2ff719
@ -131,7 +131,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[0],
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
@ -142,8 +142,8 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
|
||||
// Create a second random transaction that will be inserted into the default lane
|
||||
tx2, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[1],
|
||||
1,
|
||||
s.accounts[0],
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
@ -1346,27 +1346,46 @@ func (s *ProposalsTestSuite) TestPrepareProcessParity() {
|
||||
numAccounts := 25
|
||||
accounts := testutils.RandomAccounts(s.random, numAccounts)
|
||||
|
||||
feeDenoms := []string{
|
||||
s.gasTokenDenom,
|
||||
"eth",
|
||||
"btc",
|
||||
"usdt",
|
||||
"usdc",
|
||||
}
|
||||
|
||||
// Create a bunch of transactions to insert into the default lane
|
||||
txsToInsert := []sdk.Tx{}
|
||||
validationMap := make(map[sdk.Tx]bool)
|
||||
for _, account := range accounts {
|
||||
for nonce := uint64(0); nonce < numTxsPerAccount; nonce++ {
|
||||
// create a random fee amount
|
||||
feeAmount := math.NewInt(int64(rand.Intn(100000)))
|
||||
tx, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
account,
|
||||
nonce,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
sdk.NewCoin(s.gasTokenDenom, feeAmount),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txsToInsert = append(txsToInsert, tx)
|
||||
validationMap[tx] = true
|
||||
for nonce := uint64(0); nonce < numTxsPerAccount*uint64(numAccounts); nonce++ {
|
||||
fees := []sdk.Coin{}
|
||||
// choose a random set of fee denoms
|
||||
perm := rand.Perm(len(feeDenoms))
|
||||
for i := 0; i < 1+rand.Intn(len(feeDenoms)-1); i++ {
|
||||
fees = append(fees, sdk.NewCoin(feeDenoms[perm[i]], math.NewInt(int64(rand.Intn(100000)))))
|
||||
}
|
||||
|
||||
// choose a random set of accounts
|
||||
perm = rand.Perm(len(accounts))
|
||||
signers := []testutils.Account{}
|
||||
for i := 0; i < 1+rand.Intn(len(accounts)-1); i++ {
|
||||
signers = append(signers, accounts[perm[i]])
|
||||
}
|
||||
|
||||
// create a random fee amount
|
||||
tx, err := testutils.CreateRandomTxMultipleSigners(
|
||||
s.encodingConfig.TxConfig,
|
||||
signers,
|
||||
nonce,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
fees...,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txsToInsert = append(txsToInsert, tx)
|
||||
validationMap[tx] = true
|
||||
}
|
||||
|
||||
// Set up the default lane with the transactions
|
||||
|
||||
@ -67,7 +67,7 @@ func (s *ProposalsTestSuite) setUpCustomMatchHandlerLane(maxBlockSpace math.Lega
|
||||
|
||||
options := []base.LaneOption{
|
||||
base.WithMatchHandler(mh),
|
||||
base.WithMempoolConfigs[string](cfg, base.DefaultTxPriority()),
|
||||
base.WithMempoolConfigs(cfg, base.DefaultTxPriority()),
|
||||
}
|
||||
|
||||
lane, err := base.NewBaseLane(
|
||||
@ -131,7 +131,7 @@ func (s *ProposalsTestSuite) setUpPanicLane(name string, maxBlockSpace math.Lega
|
||||
|
||||
options := []base.LaneOption{
|
||||
base.WithMatchHandler(base.DefaultMatchHandler()),
|
||||
base.WithMempoolConfigs[string](cfg, base.DefaultTxPriority()),
|
||||
base.WithMempoolConfigs(cfg, base.DefaultTxPriority()),
|
||||
base.WithPrepareLaneHandler(base.PanicPrepareLaneHandler()),
|
||||
base.WithProcessLaneHandler(base.PanicProcessLaneHandler()),
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ func TestMempoolComparison(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
output, err := mp.Compare(ctx, tx1, tx2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, -1, output)
|
||||
require.Equal(t, 0, output)
|
||||
})
|
||||
t.Run("test diff account, tx1 lt amount, tx1 gt nonce, diff denoms", func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 1, 0, nil, sdk.NewCoin("nonstake", sdkmath.NewInt(1)))
|
||||
@ -118,33 +118,13 @@ func TestMempoolSelect(t *testing.T) {
|
||||
amount: sdk.NewCoin("stake", sdkmath.NewInt(1)),
|
||||
nonce: 0,
|
||||
},
|
||||
{
|
||||
acc: acct[1],
|
||||
amount: sdk.NewCoin("notstake", sdkmath.NewInt(1)),
|
||||
nonce: 0,
|
||||
},
|
||||
{
|
||||
acc: acct[0],
|
||||
amount: sdk.NewCoin("notstake", sdkmath.NewInt(2)),
|
||||
nonce: 1,
|
||||
},
|
||||
{
|
||||
acc: acct[1],
|
||||
amount: sdk.NewCoin("stake", sdkmath.NewInt(2)),
|
||||
nonce: 1,
|
||||
},
|
||||
},
|
||||
expected: []txGen{
|
||||
{
|
||||
acc: acct[1],
|
||||
amount: sdk.NewCoin("notstake", sdkmath.NewInt(1)),
|
||||
nonce: 0,
|
||||
},
|
||||
{
|
||||
acc: acct[1],
|
||||
amount: sdk.NewCoin("stake", sdkmath.NewInt(2)),
|
||||
nonce: 1,
|
||||
},
|
||||
{
|
||||
acc: acct[0],
|
||||
amount: sdk.NewCoin("stake", sdkmath.NewInt(1)),
|
||||
|
||||
@ -2,174 +2,19 @@ package base
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
type Coins map[string]math.Int
|
||||
|
||||
// DefaultTxPriority returns a default implementation of the TxPriority. It prioritizes
|
||||
// transactions by their fee.
|
||||
func DefaultTxPriority() TxPriority[string] {
|
||||
return TxPriority[string]{
|
||||
GetTxPriority: func(goCtx context.Context, tx sdk.Tx) string {
|
||||
feeTx, ok := tx.(sdk.FeeTx)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return coinsToString(feeTx.GetFee())
|
||||
// DefaultTxPriority
|
||||
func DefaultTxPriority() TxPriority[int] {
|
||||
return TxPriority[int]{
|
||||
GetTxPriority: func(goCtx context.Context, tx sdk.Tx) int {
|
||||
return 0
|
||||
},
|
||||
Compare: func(a, b string) int {
|
||||
aCoins, _ := coinsFromString(a)
|
||||
bCoins, _ := coinsFromString(b)
|
||||
|
||||
switch {
|
||||
case aCoins.Greater(bCoins):
|
||||
return 1
|
||||
|
||||
case bCoins.Greater(aCoins):
|
||||
return -1
|
||||
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
Compare: func(a, b int) int {
|
||||
return 0
|
||||
},
|
||||
MinValue: "",
|
||||
}
|
||||
}
|
||||
|
||||
func coinsToString(coins sdk.Coins) string {
|
||||
// sort the coins by denomination
|
||||
coins.Sort()
|
||||
|
||||
// to avoid dealing with regex, etc. we use a , to separate denominations from amounts
|
||||
// e.g. 10000,stake,10000,atom
|
||||
coinString := ""
|
||||
for i, coin := range coins {
|
||||
coinString += coin.Amount.String() + "," + coin.Denom
|
||||
if i != len(coins)-1 {
|
||||
coinString += ","
|
||||
}
|
||||
}
|
||||
|
||||
return coinString
|
||||
}
|
||||
|
||||
// coinsFromString converts a string of coins to a sdk.Coins object.
|
||||
func coinsFromString(coinsString string) (Coins, error) {
|
||||
// if its empty string (zero value), we return nil
|
||||
if coinsString == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// split the string by commas
|
||||
coinStrings := strings.Split(coinsString, ",")
|
||||
|
||||
// if the length is odd, then the given string is invalid
|
||||
if len(coinStrings)%2 != 0 {
|
||||
return nil, fmt.Errorf("invalid coins string: %s", coinsString)
|
||||
}
|
||||
|
||||
coins := make(Coins, len(coinsString)/2)
|
||||
for i := 0; i < len(coinStrings); i += 2 {
|
||||
// split the string by pipe
|
||||
amount, ok := intFromString(coinStrings[i])
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid amount: %s, denom: %s", coinStrings[i], coinStrings[i+1])
|
||||
}
|
||||
|
||||
coins[coinStrings[i+1]] = amount
|
||||
}
|
||||
|
||||
return coins, nil
|
||||
}
|
||||
|
||||
func intFromString(str string) (math.Int, bool) {
|
||||
// first attempt to get int64 from the string
|
||||
int64Val, err := strconv.ParseInt(str, 10, 64)
|
||||
if err == nil {
|
||||
return math.NewInt(int64Val), true
|
||||
}
|
||||
|
||||
// if we can't get an int64, then get raw math.Int
|
||||
return math.NewIntFromString(str)
|
||||
}
|
||||
|
||||
// Greater returns true if lhs is strictly greater than rhs, and false otherwise. Notice, lhs / rhs must be comparable,
|
||||
// specifically, they must have the exact same denoms, otherwise, they aren't comparable.
|
||||
func (lhs Coins) Greater(rhs Coins) bool {
|
||||
// if a or b is nil, then return whether a is non-nil
|
||||
if lhs == nil || rhs == nil {
|
||||
return lhs != nil
|
||||
}
|
||||
|
||||
// for each of a's denoms, check if b has the same denom
|
||||
if len(lhs) != len(rhs) {
|
||||
return false
|
||||
}
|
||||
|
||||
// for each of a's denoms, check if a is greater
|
||||
for denom, aAmount := range lhs {
|
||||
// b does not have the corresponding denom, a is not greater
|
||||
bAmount, ok := rhs[denom]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// a is not greater than b
|
||||
if !aAmount.GT(bAmount) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// DeprecatedTxPriority serves the same purpose as DefaultTxPriority, however, it is significantly slower- on the order of
|
||||
// 6-10x slower.
|
||||
func DeprecatedTxPriority() TxPriority[string] {
|
||||
return TxPriority[string]{
|
||||
GetTxPriority: func(goCtx context.Context, tx sdk.Tx) string {
|
||||
feeTx, ok := tx.(sdk.FeeTx)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return feeTx.GetFee().String()
|
||||
},
|
||||
Compare: func(a, b string) int {
|
||||
aCoins, _ := sdk.ParseCoinsNormalized(a)
|
||||
bCoins, _ := sdk.ParseCoinsNormalized(b)
|
||||
|
||||
switch {
|
||||
case aCoins == nil && bCoins == nil:
|
||||
return 0
|
||||
|
||||
case aCoins == nil:
|
||||
return -1
|
||||
|
||||
case bCoins == nil:
|
||||
return 1
|
||||
|
||||
default:
|
||||
switch {
|
||||
case aCoins.IsAllGT(bCoins):
|
||||
return 1
|
||||
|
||||
case aCoins.IsAllLT(bCoins):
|
||||
return -1
|
||||
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
},
|
||||
MinValue: "",
|
||||
MinValue: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,223 +1,41 @@
|
||||
package base_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/skip-mev/block-sdk/block/base"
|
||||
"github.com/skip-mev/block-sdk/testutils"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const maxUint64 = "18446744073709551616" // value is 2^64
|
||||
func TestNopTxPriority(t *testing.T) {
|
||||
txp := base.DefaultTxPriority()
|
||||
|
||||
func TestTxPriority(t *testing.T) {
|
||||
acct := testutils.RandomAccounts(rand.New(rand.NewSource(1)), 1)
|
||||
txc := testutils.CreateTestEncodingConfig().TxConfig
|
||||
accounts := testutils.RandomAccounts(rand.New(rand.NewSource(1)), 2)
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
priority base.TxPriority[string]
|
||||
}
|
||||
|
||||
testCases := []testCase{
|
||||
{
|
||||
"DeprecatedTxPriority",
|
||||
base.DeprecatedTxPriority(),
|
||||
},
|
||||
{
|
||||
"DefaultTxPriority",
|
||||
base.DefaultTxPriority(),
|
||||
},
|
||||
}
|
||||
t.Run("test getting a tx priority: DefaultTxPriority", func(t *testing.T) {
|
||||
priority := base.DefaultTxPriority()
|
||||
|
||||
tx, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)))
|
||||
t.Run("tx priority is zero, regardless of fees", func(t *testing.T) {
|
||||
tx, err := testutils.CreateTx(txc, accounts[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "1,stake", priority.GetTxPriority(nil, tx))
|
||||
priority := txp.GetTxPriority(context.Background(), tx)
|
||||
require.Equal(t, 0, priority)
|
||||
})
|
||||
|
||||
t.Run("test with amt that is not uint64", func(t *testing.T) {
|
||||
priority := base.DefaultTxPriority()
|
||||
|
||||
amt, ok := math.NewIntFromString(maxUint64)
|
||||
require.True(t, ok)
|
||||
tx, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", amt))
|
||||
t.Run("tx priorities are always equal", func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, accounts[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, maxUint64+",stake", priority.GetTxPriority(nil, tx))
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)))
|
||||
tx2, err := testutils.CreateTx(txc, accounts[1], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, priority.Compare(priority.GetTxPriority(nil, tx), priority.GetTxPriority(nil, tx2)))
|
||||
priority1 := txp.GetTxPriority(context.Background(), tx1)
|
||||
priority2 := txp.GetTxPriority(context.Background(), tx2)
|
||||
|
||||
require.Equal(t, priority1, priority2)
|
||||
})
|
||||
|
||||
t.Run("test invalid priorities", func(t *testing.T) {
|
||||
priority := base.DefaultTxPriority()
|
||||
|
||||
invalidAmount := "a,b"
|
||||
invalidCoins := "1,stake,2"
|
||||
|
||||
require.Equal(t, 0, priority.Compare(invalidAmount, ""))
|
||||
require.Equal(t, 0, priority.Compare("", invalidCoins))
|
||||
})
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("test with non-tx: %s", tc.name), func(t *testing.T) {
|
||||
require.Equal(t, "", tc.priority.GetTxPriority(nil, nil))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("test tx with no fee: %s", tc.name), func(t *testing.T) {
|
||||
tx, err := testutils.CreateTx(txc, acct[0], 0, 0, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "", tc.priority.GetTxPriority(nil, tx))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("test comparing two tx priorities: %s", tc.name), func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx1)
|
||||
priority2 := tc.priority.GetTxPriority(nil, tx2)
|
||||
|
||||
require.Equal(t, -1, tc.priority.Compare(priority1, priority2))
|
||||
require.Equal(t, 1, tc.priority.Compare(priority2, priority1))
|
||||
require.Equal(t, 0, tc.priority.Compare(priority2, priority2))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("test comparing two tx priorities with nil: %s", tc.name), func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx1)
|
||||
|
||||
require.Equal(t, 1, tc.priority.Compare(priority1, ""))
|
||||
require.Equal(t, -1, tc.priority.Compare("", priority1))
|
||||
require.Equal(t, 0, tc.priority.Compare("", ""))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("test with multiple fee coins: %s", tc.name), func(t *testing.T) {
|
||||
tx, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("atom", math.NewInt(2)))
|
||||
require.NoError(t, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)), sdk.NewCoin("atom", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx)
|
||||
priority2 := tc.priority.GetTxPriority(nil, tx2)
|
||||
|
||||
require.Equal(t, -1, tc.priority.Compare(priority1, priority2))
|
||||
require.Equal(t, 1, tc.priority.Compare(priority2, priority1))
|
||||
require.Equal(t, 0, tc.priority.Compare(priority2, priority2))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("test with multiple different fee coins: %s", tc.name), func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("atom", math.NewInt(2)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)), sdk.NewCoin("eth", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx1)
|
||||
priority2 := tc.priority.GetTxPriority(nil, tx2)
|
||||
|
||||
require.Equal(t, 0, tc.priority.Compare(priority1, priority2))
|
||||
|
||||
tx3, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)), sdk.NewCoin("osmo", math.NewInt(3)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority3 := tc.priority.GetTxPriority(nil, tx3)
|
||||
|
||||
require.Equal(t, 0, tc.priority.Compare(priority3, priority1))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("one is nil, and the other isn't: %s", tc.name), func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("atom", math.NewInt(2)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx1)
|
||||
priority2 := tc.priority.GetTxPriority(nil, tx2)
|
||||
|
||||
require.Equal(t, 1, tc.priority.Compare(priority1, priority2))
|
||||
require.Equal(t, -1, tc.priority.Compare(priority2, priority1))
|
||||
require.Equal(t, 0, tc.priority.Compare(priority2, priority2))
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("incorrectly ordered fee tokens: %s", tc.name), func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("atom", math.NewInt(2)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("atom", math.NewInt(2)), sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx1)
|
||||
priority2 := tc.priority.GetTxPriority(nil, tx2)
|
||||
|
||||
require.Equal(t, tc.priority.Compare(priority1, priority2), 0)
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("IBC tokens: %s", tc.name), func(t *testing.T) {
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2", math.NewInt(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2", math.NewInt(2)))
|
||||
require.NoError(t, err)
|
||||
|
||||
priority1 := tc.priority.GetTxPriority(nil, tx1)
|
||||
priority2 := tc.priority.GetTxPriority(nil, tx2)
|
||||
|
||||
require.Equal(t, -1, tc.priority.Compare(priority1, priority2))
|
||||
require.Equal(t, 1, tc.priority.Compare(priority2, priority1))
|
||||
require.Equal(t, 0, tc.priority.Compare(priority2, priority2))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDefaultTxPriority(b *testing.B) {
|
||||
acct := testutils.RandomAccounts(rand.New(rand.NewSource(1)), 1)
|
||||
txc := testutils.CreateTestEncodingConfig().TxConfig
|
||||
|
||||
priority := base.DefaultTxPriority()
|
||||
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("atom", math.NewInt(2)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(b, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)), sdk.NewCoin("eth", math.NewInt(3)), sdk.NewCoin("btc", math.NewInt(4)))
|
||||
require.NoError(b, err)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
priority.Compare(priority.GetTxPriority(nil, tx1), priority.GetTxPriority(nil, tx2))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDeprecatedTxPriority(b *testing.B) {
|
||||
// ignore setup
|
||||
acct := testutils.RandomAccounts(rand.New(rand.NewSource(1)), 1)
|
||||
txc := testutils.CreateTestEncodingConfig().TxConfig
|
||||
|
||||
priority := base.DeprecatedTxPriority()
|
||||
|
||||
tx1, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(1)), sdk.NewCoin("atom", math.NewInt(2)), sdk.NewCoin("btc", math.NewInt(3)))
|
||||
require.NoError(b, err)
|
||||
|
||||
tx2, err := testutils.CreateTx(txc, acct[0], 0, 0, nil, sdk.NewCoin("stake", math.NewInt(2)), sdk.NewCoin("eth", math.NewInt(3)), sdk.NewCoin("btc", math.NewInt(4)))
|
||||
require.NoError(b, err)
|
||||
// start timer
|
||||
for i := 0; i < b.N; i++ {
|
||||
priority.Compare(priority.GetTxPriority(nil, tx1), priority.GetTxPriority(nil, tx2))
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,8 +292,8 @@ func (s *BaseTestSuite) TestPrepareLane() {
|
||||
s.Run("should order transactions correctly in the proposal (with different insertion)", func() {
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[0],
|
||||
0,
|
||||
s.accounts[1],
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
@ -961,7 +961,7 @@ func (s *BaseTestSuite) TestProcessLane() {
|
||||
s.Require().Equal(encodedTxs, finalProposal.Txs)
|
||||
})
|
||||
|
||||
s.Run("should not accept a proposal with transactions that are not in the correct order fee wise", func() {
|
||||
s.Run("should accept a proposal with transactions that are in any order fee wise", func() {
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[0],
|
||||
@ -998,8 +998,8 @@ func (s *BaseTestSuite) TestProcessLane() {
|
||||
)
|
||||
|
||||
txsFromLane, remainingTxs, err := base.NewDefaultProposalHandler(lane).ProcessLaneHandler()(s.ctx, proposal)
|
||||
s.Require().Error(err)
|
||||
s.Require().Len(txsFromLane, 0)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(txsFromLane, 2)
|
||||
s.Require().Len(remainingTxs, 0)
|
||||
|
||||
emptyProposal := proposals.NewProposal(
|
||||
@ -1009,7 +1009,7 @@ func (s *BaseTestSuite) TestProcessLane() {
|
||||
)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, emptyProposal, proposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
s.Require().NoError(err)
|
||||
})
|
||||
|
||||
s.Run("should not accept proposal where transactions from lane are not contiguous from the start", func() {
|
||||
|
||||
@ -95,7 +95,7 @@ func (s *BaseTestSuite) TestCompareTxPriority() {
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("should return 1 when the first tx has a higher priority", func() {
|
||||
s.Run("should return 0 when the first tx has a higher fee", func() {
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[0],
|
||||
@ -120,12 +120,12 @@ func (s *BaseTestSuite) TestCompareTxPriority() {
|
||||
|
||||
cmp, err := lane.Compare(sdk.Context{}, tx1, tx2)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, cmp)
|
||||
s.Require().Equal(0, cmp)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BaseTestSuite) TestInsert() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
mempool := base.NewMempool(base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
s.Run("should be able to insert a transaction", func() {
|
||||
tx, err := testutils.CreateRandomTx(
|
||||
@ -180,7 +180,7 @@ func (s *BaseTestSuite) TestInsert() {
|
||||
}
|
||||
|
||||
func (s *BaseTestSuite) TestRemove() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
mempool := base.NewMempool(base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
s.Run("should be able to remove a transaction", func() {
|
||||
tx, err := testutils.CreateRandomTx(
|
||||
@ -220,11 +220,11 @@ func (s *BaseTestSuite) TestRemove() {
|
||||
|
||||
func (s *BaseTestSuite) TestSelect() {
|
||||
s.Run("should be able to select transactions in the correct order", func() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
mempool := base.NewMempool(base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[0],
|
||||
s.accounts[1],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@ -236,7 +236,7 @@ func (s *BaseTestSuite) TestSelect() {
|
||||
tx2, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
s.accounts[1],
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@ -252,16 +252,16 @@ func (s *BaseTestSuite) TestSelect() {
|
||||
// Check that the transactions are in the correct order
|
||||
iterator := mempool.Select(sdk.Context{}, nil)
|
||||
s.Require().NotNil(iterator)
|
||||
s.Require().Equal(tx2, iterator.Tx())
|
||||
s.Require().Equal(tx1, iterator.Tx())
|
||||
|
||||
// Check the second transaction
|
||||
iterator = iterator.Next()
|
||||
s.Require().NotNil(iterator)
|
||||
s.Require().Equal(tx1, iterator.Tx())
|
||||
s.Require().Equal(tx2, iterator.Tx())
|
||||
})
|
||||
|
||||
s.Run("should be able to select a single transaction", func() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
mempool := base.NewMempool(base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
|
||||
@ -40,7 +40,7 @@ func CreateMempool() *block.LanedMempool {
|
||||
MaxBlockSpace: math.LegacyMustNewDecFromStr("0.3"),
|
||||
MaxTxs: 0, // unlimited
|
||||
}
|
||||
freeLane := free.NewFreeLane[string](freeConfig, base.DefaultTxPriority(), free.DefaultMatchHandler())
|
||||
freeLane := free.NewFreeLane(freeConfig, base.DefaultTxPriority(), free.DefaultMatchHandler())
|
||||
|
||||
defaultConfig := base.LaneConfig{
|
||||
SignerExtractor: signerExtractor,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
@ -212,6 +213,49 @@ func CreateTxWithSigners(txCfg client.TxConfig, nonce, timeout uint64, signers [
|
||||
return txBuilder.GetTx(), nil
|
||||
}
|
||||
|
||||
func CreateRandomTxMultipleSigners(txCfg client.TxConfig, accounts []Account, nonce, numberMsgs, timeout uint64, gasLimit uint64, fees ...sdk.Coin) (authsigning.Tx, error) {
|
||||
if len(accounts) == 0 {
|
||||
return nil, fmt.Errorf("no accounts provided")
|
||||
}
|
||||
|
||||
msgs := make([]sdk.Msg, numberMsgs)
|
||||
for i := 0; i < int(numberMsgs); i++ {
|
||||
msgs[i] = &banktypes.MsgSend{
|
||||
FromAddress: accounts[0].Address.String(),
|
||||
ToAddress: accounts[0].Address.String(),
|
||||
}
|
||||
}
|
||||
|
||||
txBuilder := txCfg.NewTxBuilder()
|
||||
if err := txBuilder.SetMsgs(msgs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigs := make([]signing.SignatureV2, len(accounts))
|
||||
for i, acc := range accounts {
|
||||
sigs[i] = signing.SignatureV2{
|
||||
PubKey: acc.PrivKey.PubKey(),
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
|
||||
Signature: nil,
|
||||
},
|
||||
Sequence: nonce,
|
||||
}
|
||||
}
|
||||
|
||||
if err := txBuilder.SetSignatures(sigs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txBuilder.SetTimeoutHeight(timeout)
|
||||
|
||||
txBuilder.SetFeeAmount(fees)
|
||||
|
||||
txBuilder.SetGasLimit(gasLimit)
|
||||
|
||||
return txBuilder.GetTx(), nil
|
||||
}
|
||||
|
||||
func CreateAuctionTx(txCfg client.TxConfig, bidder Account, bid sdk.Coin, nonce, timeout uint64, signers []Account, gasLimit uint64) (sdk.Tx, []sdk.Tx, error) {
|
||||
bidMsg := &auctiontypes.MsgAuctionBid{
|
||||
Bidder: bidder.Address.String(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user