Skip to content

Commit

Permalink
Better mempool tests (chain simulator).
Browse files Browse the repository at this point in the history
  • Loading branch information
andreibancioiu committed Dec 19, 2024
1 parent 276ffeb commit eaf721a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 74 deletions.
114 changes: 45 additions & 69 deletions integrationTests/chainSimulator/mempool/mempool_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package mempool

import (
"math/big"
"testing"
"time"

"github.com/multiversx/mx-chain-core-go/data/transaction"
"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/node/chainSimulator/configs"
"github.com/multiversx/mx-chain-go/node/chainSimulator/dtos"
"github.com/multiversx/mx-chain-go/storage"
logger "github.com/multiversx/mx-chain-logger-go"
"github.com/stretchr/testify/require"
)

func TestMempoolWithChainSimulator_Selection(t *testing.T) {
logger.SetLogLevel("*:INFO,txcache:DEBUG")

if testing.Short() {
t.Skip("this is not a short test")
}
Expand Down Expand Up @@ -56,6 +51,7 @@ func TestMempoolWithChainSimulator_Selection(t *testing.T) {
}

sendTransactions(t, simulator, transactions)
time.Sleep(durationWaitAfterSendMany)
require.Equal(t, 30_000, getNumTransactionsInPool(simulator, shard))

selectedTransactions, gas := selectTransactions(t, simulator, shard)
Expand All @@ -67,106 +63,86 @@ func TestMempoolWithChainSimulator_Selection(t *testing.T) {
require.Equal(t, 27_756, getNumTransactionsInCurrentBlock(simulator, shard))

selectedTransactions, gas = selectTransactions(t, simulator, shard)
require.Equal(t, 30_000, len(selectedTransactions))
require.Equal(t, 50_000*30_000, int(gas))
require.Equal(t, 30_000-27_756, len(selectedTransactions))
require.Equal(t, 50_000*(30_000-27_756), int(gas))
}

func TestMempoolWithChainSimulator_Eviction(t *testing.T) {
if testing.Short() {
t.Skip("this is not a short test")
}

simulator := startChainSimulator(t, func(cfg *config.Configs) {})
node := simulator.GetNodeHandler(0)
mempool := node.GetDataComponents().Datapool().Transactions()

defer simulator.Close()

numSenders := 10000
numTransactionsPerSender := 30
shard := 0

senders := make([]dtos.WalletAddress, numSenders)
sendersNonces := make([]uint64, numSenders)

for i := 0; i < numSenders; i++ {
sender, err := simulator.GenerateAndMintWalletAddress(0, oneEGLD)
require.NoError(t, err)

senders[i] = sender
}

receiver, err := simulator.GenerateAndMintWalletAddress(0, big.NewInt(0))
require.NoError(t, err)
simulator := startChainSimulator(t, func(cfg *config.Configs) {})
defer simulator.Close()

err = simulator.GenerateBlocks(1)
require.Nil(t, err)
participants := createParticipants(t, simulator, numSenders)
noncesTracker := newNoncesTracker()

transactions := make([]*transaction.Transaction, 0, numSenders*numTransactionsPerSender)

for i := 0; i < numSenders; i++ {
sender := participants.sendersByShard[shard][i]
receiver := participants.receiverByShard[shard]

for j := 0; j < numTransactionsPerSender; j++ {
tx := &transaction.Transaction{
Nonce: sendersNonces[i],
Value: oneEGLD,
SndAddr: senders[i].Bytes,
Nonce: noncesTracker.getThenIncrementNonce(sender),
Value: oneQuarterOfEGLD,
SndAddr: sender.Bytes,
RcvAddr: receiver.Bytes,
Data: []byte{},
GasLimit: 50000,
GasLimit: 50_000,
GasPrice: 1_000_000_000,
ChainID: []byte(configs.ChainID),
Version: 2,
Signature: []byte("signature"),
}

sendersNonces[i]++
transactions = append(transactions, tx)
}
}

numSent, err := node.GetFacadeHandler().SendBulkTransactions(transactions)
require.NoError(t, err)
require.Equal(t, 300000, int(numSent))

time.Sleep(1 * time.Second)
require.Equal(t, 300000, int(mempool.GetCounts().GetTotal()))
sendTransactions(t, simulator, transactions)
time.Sleep(durationWaitAfterSendMany)
require.Equal(t, 300_000, getNumTransactionsInPool(simulator, shard))

// Send one more transaction (fill up the mempool)
_, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{
{
Nonce: 42,
Value: oneEGLD,
SndAddr: senders[7].Bytes,
RcvAddr: receiver.Bytes,
Data: []byte{},
GasLimit: 50000,
GasPrice: 1_000_000_000,
ChainID: []byte(configs.ChainID),
Version: 2,
Signature: []byte("signature"),
},
sendTransaction(t, simulator, &transaction.Transaction{
Nonce: 42,
Value: oneEGLD,
SndAddr: participants.sendersByShard[shard][7].Bytes,
RcvAddr: participants.receiverByShard[shard].Bytes,
Data: []byte{},
GasLimit: 50000,
GasPrice: 1_000_000_000,
ChainID: []byte(configs.ChainID),
Version: 2,
Signature: []byte("signature"),
})
require.NoError(t, err)

time.Sleep(42 * time.Millisecond)
require.Equal(t, 300001, int(mempool.GetCounts().GetTotal()))
time.Sleep(durationWaitAfterSendSome)
require.Equal(t, 300_001, getNumTransactionsInPool(simulator, shard))

// Send one more transaction to trigger eviction
_, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{
{
Nonce: 42,
Value: oneEGLD,
SndAddr: senders[7].Bytes,
RcvAddr: receiver.Bytes,
Data: []byte{},
GasLimit: 50000,
GasPrice: 1_000_000_000,
ChainID: []byte(configs.ChainID),
Version: 2,
Signature: []byte("signature"),
},
sendTransaction(t, simulator, &transaction.Transaction{
Nonce: 42,
Value: oneEGLD,
SndAddr: participants.sendersByShard[shard][7].Bytes,
RcvAddr: participants.receiverByShard[shard].Bytes,
Data: []byte{},
GasLimit: 50000,
GasPrice: 1_000_000_000,
ChainID: []byte(configs.ChainID),
Version: 2,
Signature: []byte("signature"),
})
require.NoError(t, err)

time.Sleep(1 * time.Second)
require.Equal(t, 300000+1+1-int(storage.TxPoolSourceMeNumItemsToPreemptivelyEvict), int(mempool.GetCounts().GetTotal()))

expectedNumTransactionsInPool := 300_000 + 1 + 1 - int(storage.TxPoolSourceMeNumItemsToPreemptivelyEvict)
require.Equal(t, expectedNumTransactionsInPool, getNumTransactionsInPool(simulator, shard))
}
13 changes: 8 additions & 5 deletions integrationTests/chainSimulator/mempool/testutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import (
)

var (
oneEGLD = big.NewInt(1000000000000000000)
oneQuarterOfEGLD = big.NewInt(250000000000000000)
oneCentOfEGLD = big.NewInt(10000000000000000)
durationWaitAfterSend = 500 * time.Millisecond
oneEGLD = big.NewInt(1000000000000000000)
oneQuarterOfEGLD = big.NewInt(250000000000000000)
oneCentOfEGLD = big.NewInt(10000000000000000)

Check failure on line 26 in integrationTests/chainSimulator/mempool/testutils_test.go

View workflow job for this annotation

GitHub Actions / golangci linter

var `oneCentOfEGLD` is unused (unused)
durationWaitAfterSendMany = 750 * time.Millisecond
durationWaitAfterSendSome = 10 * time.Millisecond
)

func startChainSimulator(t *testing.T, alterConfigsFunction func(cfg *config.Configs)) testsChainSimulator.ChainSimulator {
Expand Down Expand Up @@ -130,8 +131,10 @@ func sendTransactions(t *testing.T, simulator testsChainSimulator.ChainSimulator
require.NoError(t, err)
require.Equal(t, len(transactionsFromShard), int(numSent))
}
}

time.Sleep(durationWaitAfterSend)
func sendTransaction(t *testing.T, simulator testsChainSimulator.ChainSimulator, tx *transaction.Transaction) {
sendTransactions(t, simulator, []*transaction.Transaction{tx})
}

func selectTransactions(t *testing.T, simulator testsChainSimulator.ChainSimulator, shard int) ([]*txcache.WrappedTransaction, uint64) {
Expand Down

0 comments on commit eaf721a

Please sign in to comment.