diff --git a/ingest/change.go b/ingest/change.go index 758a8a11f4..6680faa057 100644 --- a/ingest/change.go +++ b/ingest/change.go @@ -119,7 +119,7 @@ func (c Change) String() string { ) } -func (c Change) ledgerKey() (xdr.LedgerKey, error) { +func (c Change) LedgerKey() (xdr.LedgerKey, error) { if c.Pre != nil { return c.Pre.LedgerKey() } @@ -182,7 +182,7 @@ type sortableChanges struct { func newSortableChanges(changes []Change) sortableChanges { ledgerKeys := make([][]byte, len(changes)) for i, c := range changes { - lk, err := c.ledgerKey() + lk, err := c.LedgerKey() if err != nil { panic(err) } diff --git a/services/horizon/docker/captive-core-integration-tests.cfg b/services/horizon/docker/captive-core-integration-tests.cfg index 275599bacd..296fc3f819 100644 --- a/services/horizon/docker/captive-core-integration-tests.cfg +++ b/services/horizon/docker/captive-core-integration-tests.cfg @@ -7,8 +7,8 @@ FAILURE_SAFETY=0 ENABLE_SOROBAN_DIAGNOSTIC_EVENTS=true # Lower the TTL of persistent ledger entries # so that ledger entry extension/restoring becomes testeable -TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10 -TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true +# TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10 +# TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true [[VALIDATORS]] NAME="local_core" diff --git a/services/horizon/docker/captive-core-integration-tests.soroban-rpc.cfg b/services/horizon/docker/captive-core-integration-tests.soroban-rpc.cfg index 0ce81a7f5c..744cb07985 100644 --- a/services/horizon/docker/captive-core-integration-tests.soroban-rpc.cfg +++ b/services/horizon/docker/captive-core-integration-tests.soroban-rpc.cfg @@ -8,8 +8,8 @@ FAILURE_SAFETY=0 ENABLE_SOROBAN_DIAGNOSTIC_EVENTS=true # Lower the TTL of persistent ledger entries # so that ledger entry extension/restoring becomes testeable -TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10 -TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true +#TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10 +#TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true [[VALIDATORS]] NAME="local_core" diff --git a/services/horizon/docker/stellar-core-integration-tests.cfg b/services/horizon/docker/stellar-core-integration-tests.cfg index 414ad9c1eb..aa1b868471 100644 --- a/services/horizon/docker/stellar-core-integration-tests.cfg +++ b/services/horizon/docker/stellar-core-integration-tests.cfg @@ -17,8 +17,8 @@ DATABASE="postgresql://user=postgres password=mysecretpassword host=core-postgre # Lower the TTL of persistent ledger entries # so that ledger entry extension/restoring becomes testeable -TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10 -TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true +# TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10 +# TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true [QUORUM_SET] THRESHOLD_PERCENT=100 diff --git a/services/horizon/internal/integration/load_test.go b/services/horizon/internal/integration/load_test.go new file mode 100644 index 0000000000..deb497160c --- /dev/null +++ b/services/horizon/internal/integration/load_test.go @@ -0,0 +1,421 @@ +package integration + +import ( + "context" + "encoding" + "flag" + "io" + "math/rand" + "os" + "path/filepath" + "sort" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/stellar/go/clients/horizonclient" + "github.com/stellar/go/clients/stellarcore" + "github.com/stellar/go/ingest" + "github.com/stellar/go/keypair" + proto "github.com/stellar/go/protocols/stellarcore" + "github.com/stellar/go/services/horizon/internal/test/integration" + "github.com/stellar/go/txnbuild" + "github.com/stellar/go/xdr" +) + +type sorobanTransaction struct { + op *txnbuild.InvokeHostFunction + fee int64 + signer *keypair.Full + sequenceNumber int64 +} + +func TestLoad(t *testing.T) { + var transactionsPerLedger, ledgers int + flag.IntVar(&transactionsPerLedger, "transactions-per-ledger", 4000, "number of transactions per ledger") + flag.IntVar(&ledgers, "ledgers", 10, "number of ledgers to generate") + flag.Parse() + + itest := integration.NewTest(t, integration.Config{ + EnableSorobanRPC: true, + }) + + maxAccountsPerTransaction := 100 + // transactionsPerLedger should be a multiple of maxAccountsPerTransaction + require.Zero(t, transactionsPerLedger%maxAccountsPerTransaction) + + txErr := itest.CoreClient().UpgradeTxSetSize(context.Background(), uint32(transactionsPerLedger*100), time.Unix(0, 0)) + require.NoError(t, txErr) + + txErr = itest.CoreClient().UpgradeSorobanTxSetSize(context.Background(), uint32(transactionsPerLedger*100), time.Unix(0, 0)) + require.NoError(t, txErr) + + contents, err := os.ReadFile(filepath.Join("testdata", "unlimited-config.xdr")) + require.NoError(t, err) + var configSet xdr.ConfigUpgradeSet + err = xdr.SafeUnmarshalBase64(string(contents), &configSet) + require.NoError(t, err) + + upgradeTransactions, upgradeKey, err := stellarcore.GenSorobanConfigUpgradeTxAndKey(stellarcore.GenSorobanConfig{ + BaseSeqNum: 0, + NetworkPassphrase: integration.StandaloneNetworkPassphrase, + SigningKey: itest.Master(), + StellarCorePath: itest.CoreBinaryPath(), + }, configSet) + require.NoError(t, err) + + for _, transaction := range upgradeTransactions { + b64, err := xdr.MarshalBase64(transaction) + require.NoError(t, err) + response, err := itest.Client().SubmitTransactionXDR(b64) + require.NoError(t, err) + require.True(t, response.Successful) + } + + require.NoError(t, + itest.CoreClient().UpgradeSorobanConfig(context.Background(), upgradeKey, time.Unix(0, 0)), + ) + + xlm := xdr.MustNewNativeAsset() + createSAC(itest, xlm) + + var signers []*keypair.Full + var accounts []txnbuild.Account + var accountLedgers []uint32 + for i := 0; i < 2*transactionsPerLedger; i += maxAccountsPerTransaction { + keys, curAccounts := itest.CreateAccounts(maxAccountsPerTransaction, "10000000") + account, err := itest.Client().AccountDetail(horizonclient.AccountRequest{AccountID: curAccounts[0].GetAccountID()}) + require.NoError(t, err) + accountLedgers = append(accountLedgers, account.LastModifiedLedger) + + signers = append(signers, keys...) + accounts = append(accounts, curAccounts...) + } + recipients := signers[transactionsPerLedger:] + signers = signers[:transactionsPerLedger] + accounts = accounts[:transactionsPerLedger] + var transactions []sorobanTransaction + for i := range signers { + var op *txnbuild.InvokeHostFunction + sender := accounts[i].GetAccountID() + var recipient xdr.ScVal + if i%2 == 0 { + recipient = accountAddressParam(recipients[i].Address()) + } else if i%2 == 1 { + var contractID xdr.Hash + _, err = rand.Read(contractID[:]) + require.NoError(t, err) + recipient = contractAddressParam(contractID) + } + op = transfer(itest, sender, xlm, "1", recipient) + preFlightOp, minFee := itest.PreflightHostFunctions(accounts[i], *op) + preFlightOp.Ext.SorobanData.Resources.ReadBytes *= 10 + preFlightOp.Ext.SorobanData.Resources.WriteBytes *= 10 + preFlightOp.Ext.SorobanData.Resources.Instructions *= 10 + preFlightOp.Ext.SorobanData.ResourceFee *= 10 + minFee *= 10 + sequenceNumber, err := accounts[i].GetSequenceNumber() + require.NoError(t, err) + transactions = append(transactions, sorobanTransaction{ + op: &preFlightOp, + fee: minFee + txnbuild.MinBaseFee, + signer: signers[i], + sequenceNumber: sequenceNumber, + }) + } + + lock := &sync.Mutex{} + ledgerMap := map[int32]int{} + wg := &sync.WaitGroup{} + transactionsPerWorker := 100 + // transactions should be a multiple of transactionsPerWorker + require.Zero(t, len(transactions)%transactionsPerWorker) + for repetitions := 0; repetitions < ledgers; repetitions++ { + for i := 0; i < len(transactions); i += transactionsPerWorker { + subset := transactions[i : i+transactionsPerWorker] + wg.Add(1) + go func() { + defer wg.Done() + txSubWorker( + itest, + subset, + itest.Client(), + itest.CoreClient(), + lock, + ledgerMap, + int64(repetitions), + ) + }() + } + wg.Wait() + } + + start, end := int32(-1), int32(-1) + for ledgerSeq := range ledgerMap { + if start < 0 || start > ledgerSeq { + start = ledgerSeq + } + if end < 0 || ledgerSeq > end { + end = ledgerSeq + } + } + waitForLedgerInArchive(t, 15*time.Second, uint32(end)) + allLedgers := getLedgers(itest, uint32(start), uint32(end)) + + var sortedLegers []xdr.LedgerCloseMeta + for ledgerSeq := range ledgerMap { + lcm, ok := allLedgers[uint32(ledgerSeq)] + require.True(t, ok) + sortedLegers = append(sortedLegers, lcm) + } + sort.Slice(sortedLegers, func(i, j int) bool { + return sortedLegers[i].LedgerSequence() < sortedLegers[j].LedgerSequence() + }) + + output, err := os.Create(filepath.Join("testdata", "load-test-ledgers.xdr")) + require.NoError(t, err) + _, err = xdr.Marshal(output, sortedLegers) + require.NoError(t, err) + require.NoError(t, output.Close()) + + ledgersForAccounts := getLedgers(itest, accountLedgers[0], accountLedgers[len(accountLedgers)-1]) + var accountLedgerEntries []xdr.LedgerEntry + accountSet := map[string]bool{} + for _, seq := range accountLedgers { + for _, change := range extractChanges(t, []xdr.LedgerCloseMeta{ledgersForAccounts[seq]}) { + if change.Type == xdr.LedgerEntryTypeAccount && change.Post != nil && change.Pre == nil { + account := *change.Post + accountSet[account.Data.MustAccount().AccountId.Address()] = true + accountLedgerEntries = append(accountLedgerEntries, *change.Post) + } + } + } + require.Len(t, accountLedgerEntries, 2*transactionsPerLedger) + + output, err = os.Create(filepath.Join("testdata", "load-test-accounts.xdr")) + require.NoError(t, err) + _, err = xdr.Marshal(output, accountLedgerEntries) + require.NoError(t, err) + require.NoError(t, output.Close()) + + merged := mergeLedgers(t, sortedLegers, transactionsPerLedger) + changes := extractChanges(t, sortedLegers) + for _, change := range changes { + if change.Type != xdr.LedgerEntryTypeAccount { + continue + } + ledgerKey, err := change.LedgerKey() + require.NoError(t, err) + require.True(t, accountSet[ledgerKey.MustAccount().AccountId.Address()]) + } + requireChangesAreEqual(t, changes, extractChanges(t, merged)) + + orignalTransactions := extractTransactions(t, sortedLegers) + mergedTransactions := extractTransactions(t, merged) + require.Equal(t, len(orignalTransactions), len(mergedTransactions)) + for i, original := range orignalTransactions { + requireTransactionsMatch(t, original, mergedTransactions[i]) + } +} + +func extractChanges(t *testing.T, ledgers []xdr.LedgerCloseMeta) []ingest.Change { + var changes []ingest.Change + for _, ledger := range ledgers { + reader, err := ingest.NewLedgerChangeReaderFromLedgerCloseMeta(integration.StandaloneNetworkPassphrase, ledger) + require.NoError(t, err) + for { + change, err := reader.Read() + if err == io.EOF { + break + } + require.NoError(t, err) + changes = append(changes, change) + } + } + return changes +} + +func extractTransactions(t *testing.T, ledgers []xdr.LedgerCloseMeta) []ingest.LedgerTransaction { + var transactions []ingest.LedgerTransaction + for _, ledger := range ledgers { + txReader, err := ingest.NewLedgerTransactionReaderFromLedgerCloseMeta(integration.StandaloneNetworkPassphrase, ledger) + require.NoError(t, err) + for { + tx, err := txReader.Read() + if err == io.EOF { + break + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + transactions = append(transactions, tx) + } + } + return transactions +} + +func groupChangesByLedgerKey(t *testing.T, changes []ingest.Change) map[string][]ingest.Change { + byLedgerKey := map[string][]ingest.Change{} + for _, change := range changes { + key, err := change.LedgerKey() + require.NoError(t, err) + keyB64, err := key.MarshalBinaryBase64() + require.NoError(t, err) + byLedgerKey[keyB64] = append(byLedgerKey[keyB64], change) + } + return byLedgerKey +} + +func requireChangesAreEqual(t *testing.T, a, b []ingest.Change) { + aByLedgerKey := groupChangesByLedgerKey(t, a) + bByLedgerKey := groupChangesByLedgerKey(t, b) + + for key, aChanges := range aByLedgerKey { + bChanges := bByLedgerKey[key] + require.Equal(t, len(aChanges), len(bChanges)) + for i, aChange := range aChanges { + bChange := bChanges[i] + require.Equal(t, aChange.Reason, bChange.Reason) + require.Equal(t, aChange.Type, bChange.Type) + if aChange.Pre == nil { + require.Nil(t, bChange.Pre) + } else { + requireXDREquals(t, aChange.Pre, bChange.Pre) + } + if aChange.Post == nil { + require.Nil(t, bChange.Post) + } else { + requireXDREquals(t, aChange.Post, bChange.Post) + } + } + } +} + +func requireTransactionsMatch(t *testing.T, a, b ingest.LedgerTransaction) { + requireXDREquals(t, a.Hash, b.Hash) + requireXDREquals(t, a.UnsafeMeta, b.UnsafeMeta) + requireXDREquals(t, a.Result, b.Result) + requireXDREquals(t, a.Envelope, b.Envelope) + requireXDREquals(t, a.FeeChanges, b.FeeChanges) + require.Equal(t, a.LedgerVersion, b.LedgerVersion) +} + +func requireXDREquals(t *testing.T, a, b encoding.BinaryMarshaler) { + serialized, err := a.MarshalBinary() + require.NoError(t, err) + otherSerialized, err := b.MarshalBinary() + require.NoError(t, err) + require.Equal(t, serialized, otherSerialized) +} + +func txSubWorker( + itest *integration.Test, + subset []sorobanTransaction, + horizonClient *horizonclient.Client, + coreClient *stellarcore.Client, + ledgerLock *sync.Mutex, + ledgerMap map[int32]int, + sequenceOffset int64, +) { + var total time.Duration + pending := map[string]bool{} + for _, tx := range subset { + account := txnbuild.NewSimpleAccount(tx.signer.Address(), tx.sequenceNumber+sequenceOffset) + tx, err := itest.CreateSignedTransactionFromOpsWithFee(&account, []*keypair.Full{tx.signer}, tx.fee, tx.op) + require.NoError(itest.CurrentTest(), err) + + hash, err := tx.HashHex(integration.StandaloneNetworkPassphrase) + require.NoError(itest.CurrentTest(), err) + b64Tx, err := tx.Base64() + require.NoError(itest.CurrentTest(), err) + start := time.Now() + resp, err := coreClient.SubmitTransaction(context.Background(), b64Tx) + elapsed := time.Since(start) + require.NoError(itest.CurrentTest(), err) + require.Empty(itest.CurrentTest(), resp.Exception) + require.False(itest.CurrentTest(), resp.IsException()) + require.Equal(itest.CurrentTest(), proto.TXStatusPending, resp.Status) + pending[hash] = true + total += elapsed + } + avg := total / time.Duration(len(subset)) + itest.CurrentTest().Logf("avg %v total %v", avg, total) + + start := time.Now() + waitForTransactions(itest.CurrentTest(), horizonClient, pending, ledgerLock, ledgerMap) + itest.CurrentTest().Logf("wait duration %v", time.Since(start)) + +} + +func waitForTransactions( + t *testing.T, + client *horizonclient.Client, + pending map[string]bool, + ledgerLock *sync.Mutex, + ledgerMap map[int32]int, +) { + require.Eventually(t, func() bool { + for hash := range pending { + resp, err := client.TransactionDetail(hash) + if err == nil { + delete(pending, hash) + require.True(t, resp.Successful) + ledgerLock.Lock() + ledgerMap[resp.Ledger]++ + ledgerLock.Unlock() + continue + } + if horizonclient.IsNotFoundError(err) { + continue + } else { + require.NoError(t, err) + } + } + return len(pending) == 0 + }, time.Second*90, time.Millisecond*100) +} + +func mergeLedgers(t *testing.T, ledgers []xdr.LedgerCloseMeta, transactionsPerLedger int) []xdr.LedgerCloseMeta { + var merged []xdr.LedgerCloseMeta + if len(ledgers) == 0 { + return merged + } + var cur xdr.LedgerCloseMeta + var curCount int + for _, ledger := range ledgers { + transactionCount := ledger.CountTransactions() + require.Empty(t, ledger.V1.EvictedTemporaryLedgerKeys) + require.Empty(t, ledger.V1.EvictedPersistentLedgerEntries) + require.Empty(t, ledger.V1.UpgradesProcessing) + if transactionCount == 0 { + continue + } + + if curCount == 0 { + cur = copyLedger(t, ledger) + cur.V1.TxProcessing = nil + } else { + cur.V1.TxSet.V1TxSet.Phases = append(cur.V1.TxSet.V1TxSet.Phases, ledger.V1.TxSet.V1TxSet.Phases...) + } + + require.LessOrEqual(t, curCount+transactionCount, transactionsPerLedger) + cur.V1.TxProcessing = append(cur.V1.TxProcessing, ledger.V1.TxProcessing...) + curCount += transactionCount + if curCount == transactionsPerLedger { + merged = append(merged, cur) + curCount = 0 + } + } + require.Zero(t, curCount) + return merged +} + +func copyLedger(t *testing.T, src xdr.LedgerCloseMeta) xdr.LedgerCloseMeta { + var dst xdr.LedgerCloseMeta + serialized, err := src.MarshalBinary() + require.NoError(t, err) + require.NoError(t, dst.UnmarshalBinary(serialized)) + return dst +} diff --git a/services/horizon/internal/integration/testdata/unlimited-config.xdr b/services/horizon/internal/integration/testdata/unlimited-config.xdr new file mode 100644 index 0000000000..14bd0c4924 --- /dev/null +++ b/services/horizon/internal/integration/testdata/unlimited-config.xdr @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/services/horizon/internal/test/integration/integration.go b/services/horizon/internal/test/integration/integration.go index f90eece01f..c6899f6f10 100644 --- a/services/horizon/internal/test/integration/integration.go +++ b/services/horizon/internal/test/integration/integration.go @@ -4,8 +4,6 @@ package integration import ( "context" "fmt" - "github.com/stellar/go/historyarchive" - "github.com/stellar/go/ingest/ledgerbackend" "io/ioutil" "os" "os/exec" @@ -18,6 +16,9 @@ import ( "testing" "time" + "github.com/stellar/go/historyarchive" + "github.com/stellar/go/ingest/ledgerbackend" + "github.com/stellar/go/services/horizon/internal/test" "github.com/2opremio/pretty" @@ -620,7 +621,7 @@ func (i *Test) CreateCaptiveCoreConfig() (*ledgerbackend.CaptiveCoreConfig, erro i.t.Logf("Creating Captive Core config files, ConfName: %v, storagePath: %v", confName, storagePath) captiveCoreConfig := ledgerbackend.CaptiveCoreConfig{ - BinaryPath: i.coreConfig.binaryPath, + BinaryPath: i.CoreBinaryPath(), HistoryArchiveURLs: []string{HistoryArchiveUrl}, NetworkPassphrase: StandaloneNetworkPassphrase, CheckpointFrequency: CheckpointFrequency, // This is required for accelerated archive creation for integration test @@ -689,7 +690,7 @@ func (i *Test) waitForCore() { i.t.Fatalf("Core could not sync after %v + %v", maxWaitForCoreStartup, maxWaitForCoreUpgrade) } -const sorobanRPCInitTime = 20 * time.Second +const sorobanRPCInitTime = 60 * 6 * time.Second const sorobanRPCHealthCheckInterval = time.Second // Wait for SorobanRPC to be up @@ -998,6 +999,15 @@ func (i *Test) CoreClient() *stellarcore.Client { return i.coreClient } +func (i *Test) CoreBinaryPath() string { + if i.coreConfig.binaryPath != "" { + return i.coreConfig.binaryPath + } + corePath, err := exec.LookPath("stellar-core") + require.NoError(i.t, err) + return corePath +} + // Client returns horizon.Client connected to started Horizon instance. func (i *Test) Client() *sdk.Client { return i.horizonClient