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

performance: Add /v2/blocks benchmark #1396

Closed
Closed
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
2 changes: 1 addition & 1 deletion idb/postgres/internal/testing/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func init() {

// SetupPostgres starts a gnomock postgres DB then returns the database object,
// the connection string and a shutdown function.
func SetupPostgres(t *testing.T) (*pgxpool.Pool, string, func()) {
func SetupPostgres(t testing.TB) (*pgxpool.Pool, string, func()) {
if testpg != "" {
// use non-docker Postgresql
connStr := testpg
Expand Down
4 changes: 2 additions & 2 deletions idb/postgres/postgres_integration_common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
pgtest "github.com/algorand/indexer/idb/postgres/internal/testing"
)

func setupIdbWithConnectionString(t *testing.T, connStr string, genesis sdk.Genesis) *IndexerDb {
func setupIdbWithConnectionString(t testing.TB, connStr string, genesis sdk.Genesis) *IndexerDb {
idb, _, err := OpenPostgres(connStr, idb.IndexerDbOptions{}, nil)
require.NoError(t, err)

Expand All @@ -28,7 +28,7 @@ func setupIdbWithConnectionString(t *testing.T, connStr string, genesis sdk.Gene
return idb
}

func setupIdb(t *testing.T, genesis sdk.Genesis) (*IndexerDb, func(), func(cert *rpcs.EncodedBlockCert) error, *ledger.Ledger) {
func setupIdb(t testing.TB, genesis sdk.Genesis) (*IndexerDb, func(), func(cert *rpcs.EncodedBlockCert) error, *ledger.Ledger) {

_, connStr, shutdownFunc := pgtest.SetupPostgres(t)

Expand Down
69 changes: 69 additions & 0 deletions idb/postgres/postgres_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,75 @@ func TestMultipleWriters(t *testing.T) {
assert.Equal(t, amt, balance)
}

// BenchmarkBlockTransactions benchmarks memory usage of the block endpoint.
func BenchmarkBlockTransactions(b *testing.B) {
db, shutdownFunc, proc, l := setupIdb(b, test.MakeGenesisV2())
b.Cleanup(func() {
shutdownFunc()
l.Close()
})

round := uint64(0)
var appAddr basics.Address
appAddr[1] = 99
type benchParams struct {
testTxns uint64
innerTxns int
}
benchmarks := []benchParams{
{
testTxns: 10,
innerTxns: 0,
},
{
testTxns: 100,
innerTxns: 0,
},
{
testTxns: 1000,
innerTxns: 0,
},
{
testTxns: 10,
innerTxns: 10,
},
{
testTxns: 100,
innerTxns: 100,
},
{
testTxns: 250,
innerTxns: 250,
},
}

b.SetParallelism(1)
prevBlockHeader := test.MakeGenesisBlock().BlockHeader
for _, benchmark := range benchmarks {
var txns []*transactions.SignedTxnWithAD
for n := uint64(0); n < benchmark.testTxns; n++ {
txn := test.MakeAppCallWithInnerTxns(test.AccountA, appAddr, test.AccountB, benchmark.innerTxns)
txns = append(txns, &txn)
}

block, err := test.MakeBlockForTxns(prevBlockHeader, txns...)
require.NoError(b, err)
prevBlockHeader = block.BlockHeader

err = proc(&rpcs.EncodedBlockCert{Block: block})
Copy link
Contributor

Choose a reason for hiding this comment

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

this test breaks after block_processor is refactored to query the state deltas.

require.NoError(b, err)
round++

b.Run(fmt.Sprintf("/v2/blocks txns: %v innerTxns: %v", benchmark.testTxns, benchmark.innerTxns), func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _, _ = db.GetBlock(context.Background(), round, idb.GetBlockOptions{Transactions: true, MaxTransactionsLimit: 1000})
}
})
}

}

// TestBlockWithTransactions tests that the block with transactions endpoint works.
func TestBlockWithTransactions(t *testing.T) {
db, shutdownFunc, proc, l := setupIdb(t, test.MakeGenesisV2())
Expand Down
30 changes: 30 additions & 0 deletions util/test/account_testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,36 @@ func MakeAppCallTxnWithLogs(appid uint64, sender basics.Address, logs []string)
return
}

// MakeAppCallWithInnerTxns creates an app call with numTxns inner txns
func MakeAppCallWithInnerTxns(appSender, paymentSender, paymentReceiver basics.Address, numTxns int) transactions.SignedTxnWithAD {
createApp := MakeCreateAppTxn(appSender)

// In order to simplify the test,
// since db.AddBlock uses ApplyData from the block and not from the evaluator,
// fake ApplyData to have inner txn
// otherwise it requires funding the app account and other special setup
for i := 0; i < numTxns; i++ {
createApp.ApplyData.EvalDelta.InnerTxns = append(
createApp.ApplyData.EvalDelta.InnerTxns,
transactions.SignedTxnWithAD{
SignedTxn: transactions.SignedTxn{
Txn: transactions.Transaction{
Type: protocol.PaymentTx,
Header: transactions.Header{
Sender: paymentSender,
Note: ArbitraryString(),
},
PaymentTxnFields: transactions.PaymentTxnFields{
Receiver: paymentReceiver,
Amount: basics.MicroAlgos{Raw: 12},
},
},
},
})
}
return createApp
}

// MakeAppCallWithInnerTxn creates an app call with 3 levels of transactions:
// application create
// |- payment
Expand Down