diff --git a/services/horizon/docker/stellar-core-integration-tests.cfg b/services/horizon/docker/stellar-core-integration-tests.cfg index 035ff26122..4299863ebd 100644 --- a/services/horizon/docker/stellar-core-integration-tests.cfg +++ b/services/horizon/docker/stellar-core-integration-tests.cfg @@ -2,7 +2,7 @@ # see stellar-core_example.cfg for a description of the configuration parameters RUN_STANDALONE=false -MANUAL_CLOSE=true +ARTIFICIALLY_ACCELERATE_TIME_FOR_TESTING=true NETWORK_PASSPHRASE="Standalone Network ; February 2017" diff --git a/services/horizon/internal/integration/protocol14_sponsorship_ops_test.go b/services/horizon/internal/integration/protocol14_sponsorship_ops_test.go index a01c36934a..bdc3c6b9a6 100644 --- a/services/horizon/internal/integration/protocol14_sponsorship_ops_test.go +++ b/services/horizon/internal/integration/protocol14_sponsorship_ops_test.go @@ -363,7 +363,7 @@ func TestSponsorships(t *testing.T) { // Submit the preauthorized transaction var txResult xdr.TransactionResult tt.NoError(err) - txResp, err = itest.SubmitTransactionXDR(preAuthTxB64) + txResp, err = itest.Client().SubmitTransactionXDR(preAuthTxB64) tt.NoError(err) err = xdr.SafeUnmarshalBase64(txResp.ResultXdr, &txResult) tt.NoError(err) diff --git a/services/horizon/internal/integration/protocol14_state_verifier_test.go b/services/horizon/internal/integration/protocol14_state_verifier_test.go index 72c694175e..ecfa3d5799 100644 --- a/services/horizon/internal/integration/protocol14_state_verifier_test.go +++ b/services/horizon/internal/integration/protocol14_state_verifier_test.go @@ -14,12 +14,6 @@ import ( "github.com/stretchr/testify/assert" ) -const ( - firstCheckpoint = (64 * (iota + 1)) - 1 - secondCheckpoint - thirdCheckpoint -) - func TestProtocol14StateVerifier(t *testing.T) { itest := integration.NewTest(t, protocol15Config) @@ -104,14 +98,6 @@ func TestProtocol14StateVerifier(t *testing.T) { assert.NoError(t, err) assert.True(t, txResp.Successful) - // Reach the first checkpoint ledger - // Core will push to history archives *after* checkpoint ledger - err = itest.CloseCoreLedgersUntilSequence(firstCheckpoint + 1) - assert.NoError(t, err) - for !itest.LedgerIngested(firstCheckpoint) { - time.Sleep(time.Second) - } - verified := waitForStateVerifications(itest, 1) if !verified { t.Fatal("State verification not run...") @@ -121,19 +107,6 @@ func TestProtocol14StateVerifier(t *testing.T) { err = itest.Horizon().HistoryQ().UpdateExpIngestVersion(0) assert.NoError(t, err) - // Wait for the second checkpoint ledger and state rebuild - // Core will push to history archives *after* checkpoint ledger - err = itest.CloseCoreLedgersUntilSequence(secondCheckpoint + 1) - assert.NoError(t, err) - - // Wait for the third checkpoint ledger and state verification trigger - // Core will push to history archives *after* checkpoint ledger - err = itest.CloseCoreLedgersUntilSequence(thirdCheckpoint + 1) - assert.NoError(t, err) - for !itest.LedgerIngested(thirdCheckpoint) { - time.Sleep(time.Second) - } - verified = waitForStateVerifications(itest, 2) if !verified { t.Fatal("State verification not run...") diff --git a/services/horizon/internal/integration/protocol14_test.go b/services/horizon/internal/integration/protocol14_test.go index 6f2319b2e5..e7cd90095b 100644 --- a/services/horizon/internal/integration/protocol14_test.go +++ b/services/horizon/internal/integration/protocol14_test.go @@ -70,7 +70,7 @@ func TestProtocol15Basics(t *testing.T) { predictions := []string{id1, id2} var txResult xdr.TransactionResult - txResp, err := itest.SubmitTransaction(tx) + txResp, err := itest.Client().SubmitTransaction(tx) tt.NoError(err) xdr.SafeUnmarshalBase64(txResp.ResultXdr, &txResult) opResults, ok := txResult.OperationResults() diff --git a/services/horizon/internal/test/integration/integration.go b/services/horizon/internal/test/integration/integration.go index a497ac871d..b8c67a650f 100644 --- a/services/horizon/internal/test/integration/integration.go +++ b/services/horizon/internal/test/integration/integration.go @@ -11,7 +11,6 @@ import ( "path" "path/filepath" "strconv" - "sync" "syscall" "testing" "time" @@ -25,7 +24,6 @@ import ( proto "github.com/stellar/go/protocols/horizon" horizon "github.com/stellar/go/services/horizon/internal" "github.com/stellar/go/support/db/dbtest" - "github.com/stellar/go/support/log" "github.com/stellar/go/txnbuild" "github.com/stellar/go/xdr" ) @@ -193,18 +191,18 @@ func (i *Test) waitForCore() { } } - if err := i.CloseCoreLedger(); err != nil { - i.t.Fatalf("Failed to manually close the second ledger: %s", err) - } - - { + for t := 0; t < 5; t++ { ctx, cancel := context.WithTimeout(context.Background(), time.Second) info, err := i.cclient.Info(ctx) cancel() if err != nil || !info.IsSynced() { - i.t.Fatal("failed to wait for Core to be synced") + i.t.Logf("Core is still not synced: %v %v", err, info) + time.Sleep(time.Second) + continue } + return } + i.t.Fatal("Core could not sync after several attempts") } func (i *Test) waitForHorizon() { @@ -244,27 +242,6 @@ func (i *Test) Horizon() *horizon.App { return i.app } -// LedgerIngested returns true if the ledger with a given sequence has been -// ingested by Horizon. Panics in case of errors. -func (i *Test) LedgerIngested(sequence uint32) bool { - root, err := i.Client().Root() - panicIf(err) - - return root.IngestSequence >= sequence -} - -// LedgerClosed returns true if the ledger with a given sequence has been -// closed by Stellar-Core. Panics in case of errors. Note it's different -// than LedgerIngested because it checks if the ledger was closed, not -// necessarily ingested (ex. when rebuilding state Horizon does not ingest -// recent ledgers). -func (i *Test) LedgerClosed(sequence uint32) bool { - root, err := i.Client().Root() - panicIf(err) - - return root.CoreSequence >= int32(sequence) -} - // AdminPort returns Horizon admin port. func (i *Test) AdminPort() int { return adminPort @@ -447,7 +424,7 @@ func (i *Test) SubmitMultiSigOperations( if err != nil { return proto.Transaction{}, err } - return i.SubmitTransaction(tx) + return i.Client().SubmitTransaction(tx) } func (i *Test) CreateSignedTransaction( @@ -476,51 +453,6 @@ func (i *Test) CreateSignedTransaction( return tx, nil } -// CloseCoreLedgersUntilSequence will close ledgers until sequence. -func (i *Test) CloseCoreLedgersUntilSequence(seq int) error { - currentLedger, err := i.GetCurrentCoreLedgerSequence() - if err != nil { - return err - } - for ; currentLedger < seq; currentLedger++ { - if err = i.CloseCoreLedger(); err != nil { - return err - } - } - return nil -} - -// CloseCoreLedger will synchronously close at least one ledger. -// Note: because Core's manualclose endpoint doesn't block until ledger is actually -// closed, this method may end up closing multiple ledgers -func (i *Test) CloseCoreLedger() error { - i.t.Log("Closing one ledger manually...") - currentLedgerNum, err := i.GetCurrentCoreLedgerSequence() - if err != nil { - return err - } - targetLedgerNum := currentLedgerNum + 1 - // Core's manualclose endpoint doesn't currently block until the ledger is actually - // closed. So, we loop until we are certain it happened. - for { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - err = i.cclient.ManualClose(ctx) - cancel() - if err != nil { - return err - } - currentLedgerNum, err = i.GetCurrentCoreLedgerSequence() - if err != nil { - return err - } - if currentLedgerNum >= targetLedgerNum { - return nil - } - // pace ourselves - time.Sleep(50 * time.Millisecond) - } -} - func (i *Test) GetCurrentCoreLedgerSequence() (int, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -531,51 +463,6 @@ func (i *Test) GetCurrentCoreLedgerSequence() (int, error) { return info.Info.Ledger.Num, nil } -func (i *Test) SubmitTransaction(tx *txnbuild.Transaction) (proto.Transaction, error) { - txb64, err := tx.Base64() - if err != nil { - return proto.Transaction{}, err - } - return i.SubmitTransactionXDR(txb64) -} - -func (i *Test) SubmitTransactionXDR(txb64 string) (proto.Transaction, error) { - // Core runs in manual-close mode to run tests faster, so we need to explicitly - // close a ledger after the transaction is submitted. - // - // Horizon's submission endpoint blocks until the transaction is in a closed ledger. - // Thus, we close the ledger in parallel to the submission. - submissionDone := make(chan struct{}) - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - // We manually-close in a loop to guarantee that (at some point) - // a ledger-close happens after Core receives the transaction. - // Otherwise there is a risk of the manual-close happening before the transaction - // reaches Core, consequently causing the SubmitTransaction() call below to block indefinitely. - // - // This approach is ugly, but a better approach would probably require - // instrumenting Horizon to tell us when the submission is done. - for { - time.Sleep(time.Millisecond * 100) - if err := i.CloseCoreLedger(); err != nil { - log.Fatalf("failed to CloseCoreLedger(): %s", err) - } - select { - case <-submissionDone: - // The transaction reached a closed-ledger! - return - default: - } - } - }() - tx, err := i.Client().SubmitTransactionXDR(txb64) - close(submissionDone) - wg.Wait() - return tx, err -} - // A convenience function to provide verbose information about a failing // transaction to the test output log, if it's expected to succeed. func (i *Test) LogFailedTx(txResponse proto.Transaction, horizonResult error) {