From 5f6c60e2e2ad19e1a8f4940679ff34ccc762fdcf Mon Sep 17 00:00:00 2001 From: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> Date: Thu, 2 Nov 2023 10:47:25 -0400 Subject: [PATCH 1/5] optimize in-memory transaction store --- .../internal/methods/get_transaction.go | 25 +++--------- .../internal/methods/get_transaction_test.go | 40 +++++++++---------- .../internal/transactions/transactions.go | 28 ++++++++----- .../transactions/transactions_test.go | 27 ++++++++----- 4 files changed, 61 insertions(+), 59 deletions(-) diff --git a/cmd/soroban-rpc/internal/methods/get_transaction.go b/cmd/soroban-rpc/internal/methods/get_transaction.go index a93457d79..7a393e6e5 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction.go @@ -2,6 +2,7 @@ package methods import ( "context" + "encoding/base64" "encoding/hex" "fmt" @@ -99,25 +100,11 @@ func GetTransaction(getter transactionGetter, request GetTransactionRequest) (Ge response.FeeBump = tx.FeeBump response.Ledger = int64(tx.Ledger.Sequence) response.LedgerCloseTime = tx.Ledger.CloseTime - if response.ResultXdr, err = xdr.MarshalBase64(tx.Result); err != nil { - return GetTransactionResponse{}, &jrpc2.Error{ - Code: jrpc2.InternalError, - Message: err.Error(), - } - } - if response.EnvelopeXdr, err = xdr.MarshalBase64(tx.Envelope); err != nil { - return GetTransactionResponse{}, &jrpc2.Error{ - Code: jrpc2.InternalError, - Message: err.Error(), - } - } - if response.ResultMetaXdr, err = xdr.MarshalBase64(tx.Meta); err != nil { - return GetTransactionResponse{}, &jrpc2.Error{ - Code: jrpc2.InternalError, - Message: err.Error(), - } - } - if tx.Result.Successful() { + + response.ResultXdr = base64.StdEncoding.EncodeToString(tx.Result) + response.EnvelopeXdr = base64.StdEncoding.EncodeToString(tx.Envelope) + response.ResultMetaXdr = base64.StdEncoding.EncodeToString(tx.Meta) + if tx.Successfull { response.Status = TransactionStatusSuccess } else { response.Status = TransactionStatusFailed diff --git a/cmd/soroban-rpc/internal/methods/get_transaction_test.go b/cmd/soroban-rpc/internal/methods/get_transaction_test.go index 1b30cb762..85847f00c 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction_test.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stellar/go/xdr" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stellar/go/network" @@ -115,33 +115,33 @@ func txEnvelope(acctSeq uint32) xdr.TransactionEnvelope { func TestGetTransaction(t *testing.T) { store := transactions.NewMemoryStore(interfaces.MakeNoOpDeamon(), "passphrase", 100) _, err := GetTransaction(store, GetTransactionRequest{"ab"}) - assert.EqualError(t, err, "[-32602] unexpected hash length (2)") + require.EqualError(t, err, "[-32602] unexpected hash length (2)") _, err = GetTransaction(store, GetTransactionRequest{"foo "}) - assert.EqualError(t, err, "[-32602] incorrect hash: encoding/hex: invalid byte: U+006F 'o'") + require.EqualError(t, err, "[-32602] incorrect hash: encoding/hex: invalid byte: U+006F 'o'") hash := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" tx, err := GetTransaction(store, GetTransactionRequest{hash}) - assert.NoError(t, err) - assert.Equal(t, GetTransactionResponse{ + require.NoError(t, err) + require.Equal(t, GetTransactionResponse{ Status: TransactionStatusNotFound, }, tx) meta := txMeta(1, true) err = store.IngestTransactions(meta) - assert.NoError(t, err) + require.NoError(t, err) xdrHash := txHash(1) hash = hex.EncodeToString(xdrHash[:]) tx, err = GetTransaction(store, GetTransactionRequest{hash}) - assert.NoError(t, err) + require.NoError(t, err) expectedTxResult, err := xdr.MarshalBase64(meta.V1.TxProcessing[0].Result.Result) - assert.NoError(t, err) + require.NoError(t, err) expectedEnvelope, err := xdr.MarshalBase64(txEnvelope(1)) - assert.NoError(t, err) + require.NoError(t, err) expectedTxMeta, err := xdr.MarshalBase64(meta.V1.TxProcessing[0].TxApplyProcessing) - assert.NoError(t, err) - assert.Equal(t, GetTransactionResponse{ + require.NoError(t, err) + require.Equal(t, GetTransactionResponse{ Status: TransactionStatusSuccess, LatestLedger: 101, LatestLedgerCloseTime: 2625, @@ -159,12 +159,12 @@ func TestGetTransaction(t *testing.T) { // ingest another (failed) transaction meta = txMeta(2, false) err = store.IngestTransactions(meta) - assert.NoError(t, err) + require.NoError(t, err) // the first transaction should still be there tx, err = GetTransaction(store, GetTransactionRequest{hash}) - assert.NoError(t, err) - assert.Equal(t, GetTransactionResponse{ + require.NoError(t, err) + require.Equal(t, GetTransactionResponse{ Status: TransactionStatusSuccess, LatestLedger: 102, LatestLedgerCloseTime: 2650, @@ -184,16 +184,16 @@ func TestGetTransaction(t *testing.T) { hash = hex.EncodeToString(xdrHash[:]) expectedTxResult, err = xdr.MarshalBase64(meta.V1.TxProcessing[0].Result.Result) - assert.NoError(t, err) + require.NoError(t, err) expectedEnvelope, err = xdr.MarshalBase64(txEnvelope(2)) - assert.NoError(t, err) + require.NoError(t, err) expectedTxMeta, err = xdr.MarshalBase64(meta.V1.TxProcessing[0].TxApplyProcessing) - assert.NoError(t, err) + require.NoError(t, err) tx, err = GetTransaction(store, GetTransactionRequest{hash}) - assert.NoError(t, err) - assert.NoError(t, err) - assert.Equal(t, GetTransactionResponse{ + require.NoError(t, err) + require.NoError(t, err) + require.Equal(t, GetTransactionResponse{ Status: TransactionStatusFailed, LatestLedger: 102, LatestLedgerCloseTime: 2650, diff --git a/cmd/soroban-rpc/internal/transactions/transactions.go b/cmd/soroban-rpc/internal/transactions/transactions.go index 1c63ce399..998b48ddc 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions.go +++ b/cmd/soroban-rpc/internal/transactions/transactions.go @@ -14,10 +14,11 @@ import ( type transaction struct { bucket *ledgerbucketwindow.LedgerBucket[[]xdr.Hash] - result xdr.TransactionResult - meta xdr.TransactionMeta - envelope xdr.TransactionEnvelope + result []byte // encoded XDR of xdr.TransactionResult + meta []byte // encoded XDR of xdr.TransactionMeta + envelope []byte // encoded XDR of xdr.TransactionEnvelope feeBump bool + successful bool applicationOrder int32 } @@ -92,11 +93,18 @@ func (m *MemoryStore) IngestTransactions(ledgerCloseMeta xdr.LedgerCloseMeta) er } transactions[i] = transaction{ bucket: &bucket, - result: tx.Result.Result, - meta: tx.UnsafeMeta, - envelope: tx.Envelope, feeBump: tx.Envelope.IsFeeBump(), applicationOrder: int32(tx.Index), + successful: tx.Result.Result.Successful(), + } + if transactions[i].result, err = tx.Result.Result.MarshalBinary(); err != nil { + return err + } + if transactions[i].meta, err = tx.UnsafeMeta.MarshalBinary(); err != nil { + return err + } + if transactions[i].envelope, err = tx.Envelope.MarshalBinary(); err != nil { + return err } if transactions[i].feeBump { innerHash := tx.Result.InnerHash() @@ -135,11 +143,12 @@ type LedgerInfo struct { } type Transaction struct { - Result xdr.TransactionResult - Meta xdr.TransactionMeta - Envelope xdr.TransactionEnvelope + Result []byte // XDR encoded xdr.TransactionResult + Meta []byte // XDR encoded xdr.TransactionMeta + Envelope []byte // XDR encoded xdr.TransactionEnvelope FeeBump bool ApplicationOrder int32 + Successfull bool Ledger LedgerInfo } @@ -191,6 +200,7 @@ func (m *MemoryStore) GetTransaction(hash xdr.Hash) (Transaction, bool, StoreRan Meta: internalTx.meta, Envelope: internalTx.envelope, FeeBump: internalTx.feeBump, + Successfull: internalTx.successful, ApplicationOrder: internalTx.applicationOrder, Ledger: LedgerInfo{ Sequence: internalTx.bucket.LedgerSeq, diff --git a/cmd/soroban-rpc/internal/transactions/transactions_test.go b/cmd/soroban-rpc/internal/transactions/transactions_test.go index 64fabff1f..8df55af69 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions_test.go +++ b/cmd/soroban-rpc/internal/transactions/transactions_test.go @@ -10,19 +10,24 @@ import ( "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" ) -func expectedTransaction(ledger uint32, feeBump bool) Transaction { - return Transaction{ - Result: transactionResult(ledger, feeBump), - Meta: xdr.TransactionMeta{ - V: 3, - Operations: &[]xdr.OperationMeta{}, - V3: &xdr.TransactionMetaV3{}, - }, - Envelope: txEnvelope(ledger, feeBump), +func expectedTransaction(t *testing.T, ledger uint32, feeBump bool) Transaction { + tx := Transaction{ FeeBump: feeBump, ApplicationOrder: 1, Ledger: expectedLedgerInfo(ledger), } + var err error + tx.Result, err = transactionResult(ledger, feeBump).MarshalBinary() + require.NoError(t, err) + tx.Meta, err = xdr.TransactionMeta{ + V: 3, + Operations: &[]xdr.OperationMeta{}, + V3: &xdr.TransactionMetaV3{}, + }.MarshalBinary() + require.NoError(t, err) + tx.Envelope, err = txEnvelope(ledger, feeBump).MarshalBinary() + require.NoError(t, err) + return tx } func expectedLedgerInfo(ledgerSequence uint32) LedgerInfo { @@ -173,12 +178,12 @@ func txEnvelope(ledgerSequence uint32, feeBump bool) xdr.TransactionEnvelope { func requirePresent(t *testing.T, store *MemoryStore, feeBump bool, ledgerSequence, firstSequence, lastSequence uint32) { tx, ok, storeRange := store.GetTransaction(txHash(ledgerSequence, false)) require.True(t, ok) - require.Equal(t, expectedTransaction(ledgerSequence, feeBump), tx) + require.Equal(t, expectedTransaction(t, ledgerSequence, feeBump), tx) require.Equal(t, expectedStoreRange(firstSequence, lastSequence), storeRange) if feeBump { tx, ok, storeRange = store.GetTransaction(txHash(ledgerSequence, true)) require.True(t, ok) - require.Equal(t, expectedTransaction(ledgerSequence, feeBump), tx) + require.Equal(t, expectedTransaction(t, ledgerSequence, feeBump), tx) require.Equal(t, expectedStoreRange(firstSequence, lastSequence), storeRange) } } From acac65bc171ad38df08d363ebcd3bbd48ca9e6f1 Mon Sep 17 00:00:00 2001 From: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:23:56 -0400 Subject: [PATCH 2/5] fix test --- .../internal/ingest/service_test.go | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/cmd/soroban-rpc/internal/ingest/service_test.go b/cmd/soroban-rpc/internal/ingest/service_test.go index 4993d326f..c2e4def09 100644 --- a/cmd/soroban-rpc/internal/ingest/service_test.go +++ b/cmd/soroban-rpc/internal/ingest/service_test.go @@ -111,6 +111,7 @@ func TestIngestion(t *testing.T) { Type: xdr.ScAddressTypeScAddressTypeContract, ContractId: &contractID, } + xdrTrue := true operationChanges := xdr.LedgerEntryChanges{ { Type: xdr.LedgerEntryChangeTypeLedgerEntryState, @@ -125,6 +126,10 @@ func TestIngestion(t *testing.T) { Sym: &persistentKey, }, Durability: xdr.ContractDataDurabilityPersistent, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvBool, + B: &xdrTrue, + }, }, }, }, @@ -145,6 +150,10 @@ func TestIngestion(t *testing.T) { Sym: &persistentKey, }, Durability: xdr.ContractDataDurabilityPersistent, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvBool, + B: &xdrTrue, + }, }, }, }, @@ -161,6 +170,10 @@ func TestIngestion(t *testing.T) { Sym: &persistentKey, }, Durability: xdr.ContractDataDurabilityTemporary, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvBool, + B: &xdrTrue, + }, }, }, } @@ -202,7 +215,14 @@ func TestIngestion(t *testing.T) { }, TxProcessing: []xdr.TransactionResultMeta{ { - Result: xdr.TransactionResultPair{TransactionHash: firstTxHash}, + Result: xdr.TransactionResultPair{ + TransactionHash: firstTxHash, + Result: xdr.TransactionResult{ + Result: xdr.TransactionResultResult{ + Results: &[]xdr.OperationResult{}, + }, + }, + }, FeeProcessing: xdr.LedgerEntryChanges{}, TxApplyProcessing: xdr.TransactionMeta{ V: 3, From fb563df8be5cfce08928e4df683146b14ccea1dd Mon Sep 17 00:00:00 2001 From: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> Date: Thu, 2 Nov 2023 16:54:25 -0400 Subject: [PATCH 3/5] add memory consumption test --- .../transactions/transactions_test.go | 135 +++++++++++++++++- 1 file changed, 131 insertions(+), 4 deletions(-) diff --git a/cmd/soroban-rpc/internal/transactions/transactions_test.go b/cmd/soroban-rpc/internal/transactions/transactions_test.go index 8df55af69..a6ffd100b 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions_test.go +++ b/cmd/soroban-rpc/internal/transactions/transactions_test.go @@ -1,7 +1,12 @@ package transactions import ( + "encoding/hex" + "fmt" + "math" + "runtime" "testing" + "time" "github.com/stellar/go/network" "github.com/stellar/go/xdr" @@ -86,13 +91,72 @@ func transactionResult(ledgerSequence uint32, feeBump bool) xdr.TransactionResul func txMeta(ledgerSequence uint32, feeBump bool) xdr.LedgerCloseMeta { envelope := txEnvelope(ledgerSequence, feeBump) - + persistentKey := xdr.ScSymbol("TEMPVAL") + contractIDBytes, _ := hex.DecodeString("df06d62447fd25da07c0135eed7557e5a5497ee7d15b7fe345bd47e191d8f577") + var contractID xdr.Hash + copy(contractID[:], contractIDBytes) + contractAddress := xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractID, + } + xdrTrue := true + operationChanges := xdr.LedgerEntryChanges{ + { + Type: xdr.LedgerEntryChangeTypeLedgerEntryState, + State: &xdr.LedgerEntry{ + LastModifiedLedgerSeq: xdr.Uint32(ledgerSequence - 1), + Data: xdr.LedgerEntryData{ + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.ContractDataEntry{ + Contract: contractAddress, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + Durability: xdr.ContractDataDurabilityPersistent, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvBool, + B: &xdrTrue, + }, + }, + }, + }, + }, + { + Type: xdr.LedgerEntryChangeTypeLedgerEntryUpdated, + Updated: &xdr.LedgerEntry{ + LastModifiedLedgerSeq: xdr.Uint32(ledgerSequence - 1), + Data: xdr.LedgerEntryData{ + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.ContractDataEntry{ + Contract: xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractID, + }, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + Durability: xdr.ContractDataDurabilityPersistent, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvBool, + B: &xdrTrue, + }, + }, + }, + }, + }, + } txProcessing := []xdr.TransactionResultMeta{ { TxApplyProcessing: xdr.TransactionMeta{ - V: 3, - Operations: &[]xdr.OperationMeta{}, - V3: &xdr.TransactionMetaV3{}, + V: 3, + Operations: &[]xdr.OperationMeta{ + { + Changes: operationChanges, + }, + }, + V3: &xdr.TransactionMetaV3{}, }, Result: xdr.TransactionResultPair{ TransactionHash: txHash(ledgerSequence, feeBump), @@ -246,3 +310,66 @@ func TestIngestTransactions(t *testing.T) { require.Equal(t, uint32(3), store.transactionsByLedger.Len()) require.Len(t, store.transactions, 3) } + +func stableHeapInUse() int64 { + var ( + m = runtime.MemStats{} + prevInUse uint64 + prevNumGC uint32 + ) + + for { + runtime.GC() + + // Sleeping to allow GC to run a few times and collect all temporary data. + time.Sleep(100 * time.Millisecond) + + runtime.ReadMemStats(&m) + + // Considering heap stable if recent cycle collected less than 10KB. + if prevNumGC != 0 && m.NumGC > prevNumGC && math.Abs(float64(m.HeapInuse-prevInUse)) < 10*1024 { + break + } + + prevInUse = m.HeapInuse + prevNumGC = m.NumGC + } + + return int64(m.HeapInuse) +} + +func ByteCountBinary(b int64) string { + const unit = 1024 + if b < unit { + return fmt.Sprintf("%d B", b) + } + div, exp := int64(unit), 0 + for n := b / unit; n >= unit; n /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp]) +} + +func TestIngestTransactionsMemory(t *testing.T) { + roundsNumber := uint32(100000) + // Use a small retention window to test eviction + store := NewMemoryStore(interfaces.MakeNoOpDeamon(), "passphrase", roundsNumber) + + heapSizeBefore := stableHeapInUse() + + for i := uint32(0); i < roundsNumber; i++ { + // Insert ledger i + store.IngestTransactions(txMeta(i, false)) + } + heapSizeAfter := stableHeapInUse() + t.Logf("Memory consumption for %d transactions %v", roundsNumber, ByteCountBinary(heapSizeAfter-heapSizeBefore)) + + // we want to generate 500*20000 transactions total, to cover the expected daily amount of transactions. + projectedTransactionCount := int64(500 * 20000) + projectedMemoryUtiliztion := (heapSizeAfter - heapSizeBefore) * projectedTransactionCount / int64(roundsNumber) + t.Logf("Projected memory consumption for %d transactions %v", projectedTransactionCount, ByteCountBinary(projectedMemoryUtiliztion)) + + // add another call to store to prevent the GC from collecting. + store.GetTransaction(xdr.Hash{}) +} From 5c2a4cf2378def42f459fc4d188308b167392a13 Mon Sep 17 00:00:00 2001 From: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> Date: Fri, 3 Nov 2023 09:48:35 -0400 Subject: [PATCH 4/5] update per code review. --- cmd/soroban-rpc/internal/methods/get_transaction.go | 2 +- .../internal/transactions/transactions.go | 4 ++-- .../internal/transactions/transactions_test.go | 12 +++++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/soroban-rpc/internal/methods/get_transaction.go b/cmd/soroban-rpc/internal/methods/get_transaction.go index 7a393e6e5..257d435f3 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction.go @@ -104,7 +104,7 @@ func GetTransaction(getter transactionGetter, request GetTransactionRequest) (Ge response.ResultXdr = base64.StdEncoding.EncodeToString(tx.Result) response.EnvelopeXdr = base64.StdEncoding.EncodeToString(tx.Envelope) response.ResultMetaXdr = base64.StdEncoding.EncodeToString(tx.Meta) - if tx.Successfull { + if tx.Successful { response.Status = TransactionStatusSuccess } else { response.Status = TransactionStatusFailed diff --git a/cmd/soroban-rpc/internal/transactions/transactions.go b/cmd/soroban-rpc/internal/transactions/transactions.go index 998b48ddc..8d58a035a 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions.go +++ b/cmd/soroban-rpc/internal/transactions/transactions.go @@ -148,7 +148,7 @@ type Transaction struct { Envelope []byte // XDR encoded xdr.TransactionEnvelope FeeBump bool ApplicationOrder int32 - Successfull bool + Successful bool Ledger LedgerInfo } @@ -200,7 +200,7 @@ func (m *MemoryStore) GetTransaction(hash xdr.Hash) (Transaction, bool, StoreRan Meta: internalTx.meta, Envelope: internalTx.envelope, FeeBump: internalTx.feeBump, - Successfull: internalTx.successful, + Successful: internalTx.successful, ApplicationOrder: internalTx.applicationOrder, Ledger: LedgerInfo{ Sequence: internalTx.bucket.LedgerSeq, diff --git a/cmd/soroban-rpc/internal/transactions/transactions_test.go b/cmd/soroban-rpc/internal/transactions/transactions_test.go index a6ffd100b..6eb01ee02 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions_test.go +++ b/cmd/soroban-rpc/internal/transactions/transactions_test.go @@ -338,7 +338,7 @@ func stableHeapInUse() int64 { return int64(m.HeapInuse) } -func ByteCountBinary(b int64) string { +func byteCountBinary(b int64) string { const unit = 1024 if b < unit { return fmt.Sprintf("%d B", b) @@ -351,8 +351,8 @@ func ByteCountBinary(b int64) string { return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp]) } -func TestIngestTransactionsMemory(t *testing.T) { - roundsNumber := uint32(100000) +func BenchmarkIngestTransactionsMemory(b *testing.B) { + roundsNumber := uint32(b.N * 100000) // Use a small retention window to test eviction store := NewMemoryStore(interfaces.MakeNoOpDeamon(), "passphrase", roundsNumber) @@ -363,12 +363,14 @@ func TestIngestTransactionsMemory(t *testing.T) { store.IngestTransactions(txMeta(i, false)) } heapSizeAfter := stableHeapInUse() - t.Logf("Memory consumption for %d transactions %v", roundsNumber, ByteCountBinary(heapSizeAfter-heapSizeBefore)) + b.ReportMetric(float64(heapSizeAfter), "bytes/100k_transactions") + b.Logf("Memory consumption for %d transactions %v", roundsNumber, byteCountBinary(heapSizeAfter-heapSizeBefore)) // we want to generate 500*20000 transactions total, to cover the expected daily amount of transactions. projectedTransactionCount := int64(500 * 20000) projectedMemoryUtiliztion := (heapSizeAfter - heapSizeBefore) * projectedTransactionCount / int64(roundsNumber) - t.Logf("Projected memory consumption for %d transactions %v", projectedTransactionCount, ByteCountBinary(projectedMemoryUtiliztion)) + b.Logf("Projected memory consumption for %d transactions %v", projectedTransactionCount, byteCountBinary(projectedMemoryUtiliztion)) + b.ReportMetric(float64(projectedMemoryUtiliztion), "bytes/10M_transactions") // add another call to store to prevent the GC from collecting. store.GetTransaction(xdr.Hash{}) From 7d0b0a0e380f13495b85a95e36745132e36f6063 Mon Sep 17 00:00:00 2001 From: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> Date: Fri, 3 Nov 2023 10:21:56 -0400 Subject: [PATCH 5/5] update: --- cmd/soroban-rpc/internal/transactions/transactions_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/soroban-rpc/internal/transactions/transactions_test.go b/cmd/soroban-rpc/internal/transactions/transactions_test.go index 6eb01ee02..d32a62c6d 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions_test.go +++ b/cmd/soroban-rpc/internal/transactions/transactions_test.go @@ -360,7 +360,7 @@ func BenchmarkIngestTransactionsMemory(b *testing.B) { for i := uint32(0); i < roundsNumber; i++ { // Insert ledger i - store.IngestTransactions(txMeta(i, false)) + require.NoError(b, store.IngestTransactions(txMeta(i, false))) } heapSizeAfter := stableHeapInUse() b.ReportMetric(float64(heapSizeAfter), "bytes/100k_transactions")