From f052a0823d00d55980c1f76ddb2c8a7eca7ff44b Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Wed, 5 Mar 2025 14:58:13 +0100 Subject: [PATCH] Add benchmark for getLedgerentries method The benchmark tests the two backends for the implementation: * Using the new Captive Core HTTP endpoint * Using the DB-based internal soroban-rpc implementation --- .../get_ledger_entries_test.go | 64 ++++++++++++++++++- .../integrationtest/infrastructure/client.go | 18 +++--- .../infrastructure/contract.go | 2 +- .../integrationtest/infrastructure/test.go | 12 ++-- 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/cmd/stellar-rpc/internal/integrationtest/get_ledger_entries_test.go b/cmd/stellar-rpc/internal/integrationtest/get_ledger_entries_test.go index d717414a..acc29293 100644 --- a/cmd/stellar-rpc/internal/integrationtest/get_ledger_entries_test.go +++ b/cmd/stellar-rpc/internal/integrationtest/get_ledger_entries_test.go @@ -96,7 +96,7 @@ func TestGetLedgerEntriesSucceeds(t *testing.T) { }) } -func testGetLedgerEntriesSucceeds(t *testing.T, useCore bool) { +func testGetLedgerEntriesSucceeds(t testing.TB, useCore bool) { test := infrastructure.NewTest(t, &infrastructure.TestConfig{ EnableCoreHTTPQueryServer: useCore, }) @@ -162,3 +162,65 @@ func testGetLedgerEntriesSucceeds(t *testing.T, useCore bool) { Type: xdr.ScValTypeScvLedgerKeyContractInstance, })) } + +func benchmarkGetLedgerEntries(b *testing.B, useCore bool) { + test := infrastructure.NewTest(b, &infrastructure.TestConfig{ + EnableCoreHTTPQueryServer: useCore, + }) + _, contractID, contractHash := test.CreateHelloWorldContract() + + contractCodeKeyB64, err := xdr.MarshalBase64(xdr.LedgerKey{ + Type: xdr.LedgerEntryTypeContractCode, + ContractCode: &xdr.LedgerKeyContractCode{ + Hash: contractHash, + }, + }) + require.NoError(b, err) + + // Doesn't exist. + notFoundKeyB64, err := xdr.MarshalBase64(getCounterLedgerKey(contractID)) + require.NoError(b, err) + + contractIDHash := xdr.Hash(contractID) + contractInstanceKeyB64, err := xdr.MarshalBase64(xdr.LedgerKey{ + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.LedgerKeyContractData{ + Contract: xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractIDHash, + }, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvLedgerKeyContractInstance, + }, + Durability: xdr.ContractDataDurabilityPersistent, + }, + }) + require.NoError(b, err) + + keys := []string{contractCodeKeyB64, notFoundKeyB64, contractInstanceKeyB64} + request := protocol.GetLedgerEntriesRequest{ + Keys: keys, + } + + client := test.GetRPCLient() + + b.ResetTimer() + + for range b.N { + result, err := client.GetLedgerEntries(context.Background(), request) + b.StopTimer() + require.NoError(b, err) + require.Len(b, result.Entries, 2) + require.Positive(b, result.LatestLedger) + b.StartTimer() + } +} + +func BenchmarkGetLedgerEntries(b *testing.B) { + b.Run("WithCore", func(b *testing.B) { + benchmarkGetLedgerEntries(b, true) + }) + b.Run("WithoutCore", func(b *testing.B) { + benchmarkGetLedgerEntries(b, false) + }) +} diff --git a/cmd/stellar-rpc/internal/integrationtest/infrastructure/client.go b/cmd/stellar-rpc/internal/integrationtest/infrastructure/client.go index 544efb36..9af87588 100644 --- a/cmd/stellar-rpc/internal/integrationtest/infrastructure/client.go +++ b/cmd/stellar-rpc/internal/integrationtest/infrastructure/client.go @@ -17,9 +17,9 @@ import ( "github.com/stellar/stellar-rpc/protocol" ) -func getTransaction(t *testing.T, client *client.Client, hash string) protocol.GetTransactionResponse { +func getTransaction(t testing.TB, client *client.Client, hash string) protocol.GetTransactionResponse { var result protocol.GetTransactionResponse - for i := 0; i < 60; i++ { + for range 60 { var err error request := protocol.GetTransactionRequest{Hash: hash} result, err = client.GetTransaction(context.Background(), request) @@ -36,7 +36,7 @@ func getTransaction(t *testing.T, client *client.Client, hash string) protocol.G return result } -func logTransactionResult(t *testing.T, response protocol.GetTransactionResponse) { +func logTransactionResult(t testing.TB, response protocol.GetTransactionResponse) { var txResult xdr.TransactionResult require.NoError(t, xdr.SafeUnmarshalBase64(response.ResultXDR, &txResult)) t.Logf("error: %#v\n", txResult) @@ -61,7 +61,7 @@ func logTransactionResult(t *testing.T, response protocol.GetTransactionResponse } } -func SendSuccessfulTransaction(t *testing.T, client *client.Client, kp *keypair.Full, +func SendSuccessfulTransaction(t testing.TB, client *client.Client, kp *keypair.Full, transaction *txnbuild.Transaction, ) protocol.GetTransactionResponse { tx, err := transaction.Sign(StandaloneNetworkPassphrase, kp) @@ -99,7 +99,7 @@ func SendSuccessfulTransaction(t *testing.T, client *client.Client, kp *keypair. return response } -func SimulateTransactionFromTxParams(t *testing.T, client *client.Client, +func SimulateTransactionFromTxParams(t testing.TB, client *client.Client, params txnbuild.TransactionParams, ) protocol.SimulateTransactionResponse { savedAutoIncrement := params.IncrementSequenceNum @@ -115,7 +115,7 @@ func SimulateTransactionFromTxParams(t *testing.T, client *client.Client, return response } -func PreflightTransactionParamsLocally(t *testing.T, params txnbuild.TransactionParams, +func PreflightTransactionParamsLocally(t testing.TB, params txnbuild.TransactionParams, response protocol.SimulateTransactionResponse, ) txnbuild.TransactionParams { if !assert.Empty(t, response.Error) { @@ -144,13 +144,13 @@ func PreflightTransactionParamsLocally(t *testing.T, params txnbuild.Transaction } v.Auth = auth case *txnbuild.ExtendFootprintTtl: - require.Len(t, response.Results, 0) + require.Empty(t, response.Results) v.Ext = xdr.TransactionExt{ V: 1, SorobanData: &transactionData, } case *txnbuild.RestoreFootprint: - require.Len(t, response.Results, 0) + require.Empty(t, response.Results) v.Ext = xdr.TransactionExt{ V: 1, SorobanData: &transactionData, @@ -165,7 +165,7 @@ func PreflightTransactionParamsLocally(t *testing.T, params txnbuild.Transaction return params } -func PreflightTransactionParams(t *testing.T, client *client.Client, params txnbuild.TransactionParams, +func PreflightTransactionParams(t testing.TB, client *client.Client, params txnbuild.TransactionParams, ) txnbuild.TransactionParams { response := SimulateTransactionFromTxParams(t, client, params) // The preamble should be zero except for the special restore case diff --git a/cmd/stellar-rpc/internal/integrationtest/infrastructure/contract.go b/cmd/stellar-rpc/internal/integrationtest/infrastructure/contract.go index e4c087fc..45d6eee4 100644 --- a/cmd/stellar-rpc/internal/integrationtest/infrastructure/contract.go +++ b/cmd/stellar-rpc/internal/integrationtest/infrastructure/contract.go @@ -55,7 +55,7 @@ func CreateInvokeHostOperation(sourceAccount string, contractID xdr.Hash, method } } -func getContractID(t *testing.T, sourceAccount string, salt [32]byte, networkPassphrase string) [32]byte { +func getContractID(t testing.TB, sourceAccount string, salt [32]byte, networkPassphrase string) [32]byte { sourceAccountID := xdr.MustAddress(sourceAccount) preImage := xdr.HashIdPreimage{ Type: xdr.EnvelopeTypeEnvelopeTypeContractId, diff --git a/cmd/stellar-rpc/internal/integrationtest/infrastructure/test.go b/cmd/stellar-rpc/internal/integrationtest/infrastructure/test.go index feac5ba5..0a6e1fa4 100644 --- a/cmd/stellar-rpc/internal/integrationtest/infrastructure/test.go +++ b/cmd/stellar-rpc/internal/integrationtest/infrastructure/test.go @@ -93,7 +93,7 @@ type TestPorts struct { } type Test struct { - t *testing.T + t testing.TB testPorts TestPorts @@ -119,7 +119,7 @@ type Test struct { enableCoreHTTPQueryServer bool } -func NewTest(t *testing.T, cfg *TestConfig) *Test { +func NewTest(t testing.TB, cfg *TestConfig) *Test { if os.Getenv("STELLAR_RPC_INTEGRATION_TESTS_ENABLED") == "" { t.Skip("skipping integration test: STELLAR_RPC_INTEGRATION_TESTS_ENABLED not set") } @@ -153,8 +153,8 @@ func NewTest(t *testing.T, cfg *TestConfig) *Test { i.sqlitePath = path.Join(i.t.TempDir(), "stellar_rpc.sqlite") } - if parallel { - t.Parallel() + if tt, ok := t.(*testing.T); ok && parallel { + tt.Parallel() } if i.protocolVersion == 0 { @@ -424,13 +424,13 @@ func (i *Test) generateRPCConfigFile(rpcConfig rpcConfig) { require.NoError(i.t, err) } -func newTestLogWriter(t *testing.T, prefix string) *testLogWriter { +func newTestLogWriter(t testing.TB, prefix string) *testLogWriter { tw := &testLogWriter{t: t, prefix: prefix} return tw } type testLogWriter struct { - t *testing.T + t testing.TB prefix string }