Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

testing: benchmark assemble / transaction pool's uses of recomputeBlockEvaluator #3138

Merged
merged 9 commits into from
Sep 14, 2022
112 changes: 112 additions & 0 deletions data/pools/transactionPool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"bytes"
"fmt"
"math/rand"
"os"
"runtime"
"runtime/pprof"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -1099,6 +1102,115 @@ func BenchmarkTransactionPoolPending(b *testing.B) {
}
}

func BenchmarkTransactionPoolRecompute(b *testing.B) {
algonautshant marked this conversation as resolved.
Show resolved Hide resolved
b.Log("Running with b.N", b.N)
poolSize := 100000
numOfAccounts := 100
numTransactions := 75000
blockTxnCount := 25000

myVersion := protocol.ConsensusVersion("test-large-blocks")
myProto := config.Consensus[protocol.ConsensusCurrentVersion]
if myProto.MaxTxnBytesPerBlock != 5*1024*1024 {
b.FailNow() // intended to use with 5MB blocks
}
config.Consensus[myVersion] = myProto

// Generate accounts
secrets := make([]*crypto.SignatureSecrets, numOfAccounts)
algonautshant marked this conversation as resolved.
Show resolved Hide resolved
addresses := make([]basics.Address, numOfAccounts)

for i := 0; i < numOfAccounts; i++ {
secret := keypair()
addr := basics.Address(secret.SignatureVerifier)
secrets[i] = secret
addresses[i] = addr
}

l := mockLedger(b, initAccFixed(addresses, 1<<50), myVersion)
cfg := config.GetDefaultLocal()
cfg.TxPoolSize = poolSize
cfg.EnableProcessBlockStats = false

setupPool := func() (*TransactionPool, map[transactions.Txid]ledgercore.IncludedTransactions, uint) {
transactionPool := MakeTransactionPool(l, cfg, logging.Base())

// make some transactions
var signedTransactions []transactions.SignedTxn
for i := 0; i < numTransactions; i++ {
tx := transactions.Transaction{
Type: protocol.PaymentTx,
Header: transactions.Header{
Sender: addresses[i%numOfAccounts],
Fee: basics.MicroAlgos{Raw: 20000 + proto.MinTxnFee},
FirstValid: 0,
LastValid: basics.Round(proto.MaxTxnLife),
GenesisHash: l.GenesisHash(),
},
PaymentTxnFields: transactions.PaymentTxnFields{
Receiver: addresses[rand.Intn(numOfAccounts)],
Amount: basics.MicroAlgos{Raw: proto.MinBalance + uint64(rand.Intn(1<<32))},
},
}

signedTx, err := transactions.AssembleSignedTxn(tx, crypto.Signature{}, crypto.MultisigSig{})
require.NoError(b, err)
signedTransactions = append(signedTransactions, signedTx)
}

// add all txns to pool
for _, txn := range signedTransactions {
err := transactionPool.RememberOne(txn)
require.NoError(b, err)
}

// make args for recomputeBlockEvaluator() like OnNewBlock() would
var knownCommitted uint
committedTxIds := make(map[transactions.Txid]ledgercore.IncludedTransactions)
for i := 0; i < blockTxnCount; i++ {
knownCommitted++
// OK to use empty IncludedTransactions: recomputeBlockEvaluator is only checking map membership
committedTxIds[signedTransactions[i].ID()] = ledgercore.IncludedTransactions{}
}
b.Logf("Made transactionPool with %d signedTransactions, %d committedTxIds, %d knownCommitted",
len(signedTransactions), len(committedTxIds), knownCommitted)
b.Logf("transactionPool pendingTxGroups %d rememberedTxGroups %d",
len(transactionPool.pendingTxGroups), len(transactionPool.rememberedTxGroups))
return transactionPool, committedTxIds, knownCommitted
}

transactionPool := make([]*TransactionPool, b.N)
committedTxIds := make([]map[transactions.Txid]ledgercore.IncludedTransactions, b.N)
knownCommitted := make([]uint, b.N)
for i := 0; i < b.N; i++ {
transactionPool[i], committedTxIds[i], knownCommitted[i] = setupPool()
}
time.Sleep(time.Second)
runtime.GC()
// CPU profiler if CPUPROFILE set
var profF *os.File
if os.Getenv("CPUPROFILE") != "" {
var err error
profF, err = os.Create(fmt.Sprintf("recomputePool-%d-%d.prof", b.N, crypto.RandUint64()))
require.NoError(b, err)
}

// call recomputeBlockEvaluator
if profF != nil {
pprof.StartCPUProfile(profF)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
transactionPool[i].recomputeBlockEvaluator(committedTxIds[i], knownCommitted[i])
}
b.StopTimer()
if profF != nil {
pprof.StopCPUProfile()
}
//t.Log("pool.assemblyResults.blk payset len", len(transactionPool.assemblyResults.blk.Block().Payset))
cce marked this conversation as resolved.
Show resolved Hide resolved
//t.Log("pool.pendingBlockEvaluation.block.Payset len", transactionPool.pendingBlockEvaluator.PaySetSize())
}

func BenchmarkTransactionPoolSteadyState(b *testing.B) {
poolSize := 100000

Expand Down